gpt4 book ai didi

java - 让用户在Java中用鼠标绘制一个矩形

转载 作者:行者123 更新时间:2023-12-02 07:32:15 25 4
gpt4 key购买 nike

我正在编写一个程序,让用户在屏幕上的图像顶部绘制一个空心矩形。他们还可以单击图像,然后将单击连接起来形成多边形。

连接点工作正常,但是当用户拖动以绘制矩形时,先前绘制的矩形和多边形会消失。可运行的代码如下;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ImageLabeller extends JFrame {

static boolean drawRectangle = false;
/**
* some java stuff to get rid of warnings
*/
private static final long serialVersionUID = 1L;

/**
* main window panel
*/
JPanel appPanel = null;

/**
* toolbox - put all buttons here
*/
JPanel toolboxPanel = null;

/**
* image panel - displays image and editing area
*/

static ImagePanel imagePanel;

/**
* handles New Object button action
*/

public ImageLabeller(String imageFilename) {

try {

this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
System.out.println("Bye bye!");
System.exit(0);
}
});

// Create and set up the image panel.
// setup main window panel
setExtendedState(Frame.MAXIMIZED_BOTH);
appPanel = new JPanel();
appPanel.setLayout(new BoxLayout(appPanel, BoxLayout.Y_AXIS));
this.setContentPane(appPanel);

imagePanel = new ImagePanel(imageFilename);
imagePanel.setOpaque(true); // content panes must be opaque
imagePanel.setBorder(BorderFactory.createLineBorder(Color.green));

// create toolbox panel
toolboxPanel = new JPanel();
toolboxPanel.setBorder(BorderFactory.createLineBorder(Color.black));


JButton newPolyButton = new JButton("New object");
newPolyButton.setMnemonic(KeyEvent.VK_N);
// newPolyButton.setSize(50, 20);
newPolyButton.setToolTipText("Click to add new object");
newPolyButton.addActionListener(new DrawListener());

JButton newSquareButton = new JButton("New Square");
newSquareButton.setMnemonic(KeyEvent.VK_S);
// newPolyButton.setSize(50, 20);
newSquareButton.setEnabled(true);
newSquareButton.setToolTipText("Click to add new square");
newSquareButton.addActionListener(new SquareListener());



// add all buttons to toolboxPanel
toolboxPanel.add(newPolyButton);
toolboxPanel.add(newSquareButton);

// add all panels to appPanel
appPanel.add(toolboxPanel);
appPanel.add(imagePanel);
// appPanel.add(Box.createRigidArea(new Dimension(0,10)));

// display all the stuff
this.pack();
this.setVisible(true);
} catch (Exception e) {
System.err.println("Image: ");
e.printStackTrace();
}
}

public static void addNewPolygon() {
imagePanel.addNewPolygon();
}

public static void addNewRectangle() {
//imagePanel.addNewRectangle();
}

static class DrawListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
addNewPolygon();
}
}

static class SquareListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
drawRectangle = true;
imagePanel.drawingRectangle = true;
System.out.println(imagePanel.drawingRectangle);
}
}

public static void main (String args []) {
new ImageLabeller("/change to/a photo/ of your choice.jpg");
}

}

_

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel implements MouseListener,
MouseMotionListener {

Rectangle currentRectangle = null;
boolean drawingRectangle = false;

/**
* some java stuff to get rid of warnings
*/
private static final long serialVersionUID = 1L;

/**
* image to be tagged
*/
BufferedImage image = null;

/**
* list of current polygon's vertices
*/
ArrayList<Point> currentPolygon = null;

/**
* list of polygons
*/
ArrayList<ArrayList<Point>> polygonsList = null;

ArrayList<Rectangle> rectangleList = null;

/**
* extended constructor - loads image to be labelled
*
* @param imageName
* - path to image
* @throws Exception
* if error loading the image
*/
public ImagePanel(String imageName) throws Exception {

currentPolygon = new ArrayList<Point>();
polygonsList = new ArrayList<ArrayList<Point>>();
rectangleList = new ArrayList<Rectangle>();

image = ImageIO.read(new File(imageName));
Dimension panelSize = new Dimension(image.getWidth(), image.getHeight());
this.setSize(panelSize);
this.setMinimumSize(panelSize);
this.setPreferredSize(panelSize);
this.setMaximumSize(panelSize);

setBounds(0, 0, image.getWidth(), image.getHeight());
addMouseListener(this);
addMouseMotionListener(this);
this.setVisible(true);

}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Paint Component");
Graphics2D g2d = (Graphics2D) g;

// Paint image on screen
g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);

// display all the completed polygons
for (ArrayList<Point> polygon : polygonsList) {
drawPolygon(polygon);
finishPolygon(polygon);
System.out.println("Polly");
}

// Display all completed squares
for (Rectangle r : rectangleList) {
drawRectangle(r);
System.out.println("Square");
}

// display current polygon
if (currentPolygon != null) {
drawPolygon(currentPolygon);
}

// display current square
if (currentRectangle != null) {
drawRectangle(currentRectangle);
}
}

/**
* displays a polygon without last stroke
*
* @param polygon
* to be displayed
*/
public void drawPolygon(ArrayList<Point> polygon) {
Graphics2D g = (Graphics2D) this.getGraphics();
// set to red so I can see when it's being redrawn
g.setColor(Color.RED);
g.setStroke(new BasicStroke(3));
for (int i = 0; i < polygon.size(); i++) {
Point currentVertex = polygon.get(i);
if (i != 0) {
Point prevVertex = polygon.get(i - 1);
g.drawLine(prevVertex.getX(), prevVertex.getY(),
currentVertex.getX(), currentVertex.getY());
}
g.fillOval(currentVertex.getX() - 5, currentVertex.getY() - 5, 10,
10);
}
}

public void drawRectangle(Rectangle r) {
Graphics2D g = (Graphics2D) this.getGraphics();
g.setStroke(new BasicStroke(3));
g.setColor(Color.BLUE);
g.drawLine(r.getX1(), r.getY1(), r.getX2(), r.getY1());
g.drawLine(r.getX1(), r.getY1(), r.getX1(), r.getY2());
g.drawLine(r.getX2(), r.getY2(), r.getX2(), r.getY1());
g.drawLine(r.getX2(), r.getY2(), r.getX1(), r.getY2());

System.out.println(r.getX1() + " " + r.getY1() + " " + r.getX2());
System.out.println("Drawn rectangle");
}

/**
* displays last stroke of the polygon (arch between the last and first
* vertices)
*
* @param polygon
* to be finished
*/
public void finishPolygon(ArrayList<Point> polygon) {
// if there are less than 3 vertices than nothing to be completed
if (polygon.size() >= 3) {
Point firstVertex = polygon.get(0);
Point lastVertex = polygon.get(polygon.size() - 1);

Graphics2D g = (Graphics2D) this.getGraphics();
g.setColor(Color.GREEN);
g.setStroke(new BasicStroke(3));
g.drawLine(firstVertex.getX(), firstVertex.getY(),
lastVertex.getX(), lastVertex.getY());
}
}

/**
* moves current polygon to the list of polygons and makes pace for a new
* one
*/
public void addNewPolygon() {
// finish the current polygon if any
if (currentPolygon != null) {
finishPolygon(currentPolygon);
polygonsList.add(currentPolygon);
}

currentPolygon = new ArrayList<Point>();
}

public void mouseClicked(MouseEvent e) {

if (!drawingRectangle) {
int x = e.getX();
int y = e.getY();

// check if the cursor is within image area
if (x > image.getWidth() || y > image.getHeight()) {
// if not do nothing
return;
}

Graphics2D g = (Graphics2D) this.getGraphics();

// if the left button than we will add a vertex to poly
if (e.getButton() == MouseEvent.BUTTON1) {
g.setColor(Color.GREEN);
if (currentPolygon.size() != 0) {
Point lastVertex = currentPolygon
.get(currentPolygon.size() - 1);

g.setStroke(new BasicStroke(3));
g.drawLine(lastVertex.getX(), lastVertex.getY(), x, y);
}
g.fillOval(x - 5, y - 5, 10, 10);

currentPolygon.add(new Point(x, y));
System.out.println(x + " " + y + " polygon point");
}
}
}

public void mouseEntered(MouseEvent arg0) {
}

public void mouseExited(MouseEvent arg0) {
}

public void mousePressed(MouseEvent arg0) {
if (drawingRectangle) {
currentRectangle = new Rectangle(arg0.getX(), arg0.getY(),
arg0.getX(), arg0.getY(), Color.BLACK);

}
}

public void mouseReleased(MouseEvent arg0) {
if (drawingRectangle) {
rectangleList.add(new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor()));

System.out.println(currentRectangle.getX1() + " "
+ currentRectangle.getY1() + " " + arg0.getX() + " "
+ arg0.getY() + " rectangle point");

// unnecessary when mouseDragged calls paintComponent directly?
drawRectangle(new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor()));

currentRectangle = null;
drawingRectangle = false;

}
}

public void mouseDragged(MouseEvent arg0) {

if (drawingRectangle) {
currentRectangle = new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor());

System.out.println(currentRectangle.getX1() + " "
+ currentRectangle.getY1() + " " + arg0.getX() + " "
+ arg0.getX() + " " + "Dragging");
repaint();

// It works better using this instead on repaint()

// Graphics g = this.getGraphics();
// paintComponent(g);
}

}

public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub

}

}

-

public class Point {
private int x = 0;
private int y = 0;

public Point() {
}

public Point(int x, int y) {
this.x = x;
this.y = y;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

}

-

import java.awt.Color;
import java.awt.Graphics2D;

public class Rectangle {

// Initialize variables
private int x1; // x coordinate of first endpoint
private int y1; // y coordinate of first endpoint
private int x2; // x coordinate of second endpoint
private int y2; // y coordinate of second endpoint
private Color colour; // colour of the shape

// A no-parameter constructor that sets all the coordinates of the shape to
// 0 and the
// colour to Color.BLACK
public Rectangle() {
x1 = 0;
y1 = 0;
x2 = 0;
y2 = 0;
colour = Color.BLACK;
}

// A constructor that initializes the coordinates and colour to the values
// of the
// parameters supplied.
public Rectangle(int x1, int y1, int x2, int y2, Color col) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.colour = col;
}

public void setX1(int x1) {
this.x1 = x1;
}

public void setY1(int y1) {
this.y1 = y1;
}

public void setX2(int x2) {
this.x2 = x2;
}

public void setY2(int y2) {
this.y2 = y2;
}

public void setColor(Color colour) {
this.colour = colour;
}

public int getX1() {
return this.x1;
}

public int getY1() {
return this.y1;
}

public int getX2() {
return this.x2;
}

public int getY2() {
return this.y2;
}

public Color getColor() {
return this.colour;
}

public int getWidth() {
return (Math.abs(x2 - x1));
}

public int getHeight() {
return (Math.abs(y2 - y1));
}

public int getUpperLeftX() {
return (Math.min(x1, x2));
}

public int getUpperLeftY() {
return (Math.min(y1, y2));
}
}

对于大量代码,我深感抱歉,我已尽力删减。

单击图像可绘制点,这些点连接起来可创建线条。当用户单击“新对象”按钮时,第一个点和最后一个点将连接起来以创建多边形。这一切都工作正常,但如果您单击“新正方形”并在图像上拖动,则所有先前的形状都会随着鼠标移动而闪烁,并在释放鼠标按钮时消失。如果再次单击“新方 block ”(到目前为止,这对我来说是一个糟糕的编码的必要条件)并绘制了另一个方 block ,则可以看到“消失”的形状再次闪烁,但一旦释放鼠标就会消失。我在 mouseDragged(...) 事件中调用 repaint() ,我认为这就是必要的。当我改变时,它实际上(几乎)按我想要的方式工作

repaint();

对于

Graphics g = this.getGraphics();
paintComponent(g);

但是我读过的每本书和文章都说我永远不应该自己调用paintComponent。然而,调用paintComponent 的一个问题是背景图像往往会频繁闪烁。如果repaint()调用paintComponent,为什么它们会导致不同的结果?

我也不明白为什么,当在mouseDragged事件中使用repaint()时,我必须,我还必须在mouseReleased中调用drawRectangle(...)才能看到正方形,但是当使用paintComponent时,我不知道?

非常感谢任何建议或指示,谢谢。

最佳答案

在您的drawRectangle和drawPolygon中,您正在重新获取图形对象,但您是从paintComponent调用它们。这就是导致奇怪行为的原因,您应该将图形从 painComponent 传递到这些方法中。

不过,我看到了其他奇怪的行为,比如多边形保持绿色,直到我完成绘制一个正方形,然后它们变成红色,但其中一条线保持绿色并最终消失。我没有太关注这个。

此外,awt 支持多边形绘制以及点和矩形,您选择为这些创建自己的类有什么原因吗?

package test;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class ImagePanel extends JPanel implements MouseListener,
MouseMotionListener {

Rectangle currentRectangle = null;
boolean drawingRectangle = false;

/**
* some java stuff to get rid of warnings
*/
private static final long serialVersionUID = 1L;

/**
* image to be tagged
*/
BufferedImage image = null;

/**
* list of current polygon's vertices
*/
ArrayList<Point> currentPolygon = null;

/**
* list of polygons
*/
ArrayList<ArrayList<Point>> polygonsList = null;

ArrayList<Rectangle> rectangleList = null;

/**
* extended constructor - loads image to be labelled
*
* @param imageName
* - path to image
* @throws Exception
* if error loading the image
*/
public ImagePanel(String imageName) throws Exception {

currentPolygon = new ArrayList<Point>();
polygonsList = new ArrayList<ArrayList<Point>>();
rectangleList = new ArrayList<Rectangle>();

image = ImageIO.read(new File(imageName));
Dimension panelSize = new Dimension(image.getWidth(), image.getHeight());
this.setSize(panelSize);
this.setMinimumSize(panelSize);
this.setPreferredSize(panelSize);
this.setMaximumSize(panelSize);

setBounds(0, 0, image.getWidth(), image.getHeight());
addMouseListener(this);
addMouseMotionListener(this);
this.setVisible(true);

}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Paint Component");
Graphics2D g2d = (Graphics2D) g;

// Paint image on screen
g2d.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);

// display all the completed polygons
for (ArrayList<Point> polygon : polygonsList) {
drawPolygon(polygon,g);
finishPolygon(polygon);
System.out.println("Polly");
}

// Display all completed squares
for (Rectangle r : rectangleList) {
drawRectangle(r,g);
System.out.println("Square");
}

// display current polygon
if (currentPolygon != null) {
drawPolygon(currentPolygon, g);
}

// display current square
if (currentRectangle != null) {
drawRectangle(currentRectangle, g);
}
}

/**
* displays a polygon without last stroke
*
* @param polygon
* to be displayed
*/
public void drawPolygon(ArrayList<Point> polygon, Graphics gr) {
Graphics2D g = null;
if (gr instanceof Graphics2D) {
g = (Graphics2D) gr;
}
else{ return; }
// set to red so I can see when it's being redrawn
g.setColor(Color.RED);
g.setStroke(new BasicStroke(3));
for (int i = 0; i < polygon.size(); i++) {
Point currentVertex = polygon.get(i);
if (i != 0) {
Point prevVertex = polygon.get(i - 1);
g.drawLine(prevVertex.getX(), prevVertex.getY(),
currentVertex.getX(), currentVertex.getY());
}
g.fillOval(currentVertex.getX() - 5, currentVertex.getY() - 5, 10,
10);
}
}

public void drawRectangle(Rectangle r, Graphics gr) {
Graphics2D g = null;
if (gr instanceof Graphics2D) {
g = (Graphics2D) gr;
}
else{ return; }
g.setStroke(new BasicStroke(3));
g.setColor(Color.BLUE);
g.drawLine(r.getX1(), r.getY1(), r.getX2(), r.getY1());
g.drawLine(r.getX1(), r.getY1(), r.getX1(), r.getY2());
g.drawLine(r.getX2(), r.getY2(), r.getX2(), r.getY1());
g.drawLine(r.getX2(), r.getY2(), r.getX1(), r.getY2());

System.out.println(r.getX1() + " " + r.getY1() + " " + r.getX2());
System.out.println("Drawn rectangle");
}

/**
* displays last stroke of the polygon (arch between the last and first
* vertices)
*
* @param polygon
* to be finished
*/
public void finishPolygon(ArrayList<Point> polygon) {
// if there are less than 3 vertices than nothing to be completed
if (polygon.size() >= 3) {
Point firstVertex = polygon.get(0);
Point lastVertex = polygon.get(polygon.size() - 1);

Graphics2D g = (Graphics2D) this.getGraphics();
g.setColor(Color.GREEN);
g.setStroke(new BasicStroke(3));
g.drawLine(firstVertex.getX(), firstVertex.getY(),
lastVertex.getX(), lastVertex.getY());
}
}

/**
* moves current polygon to the list of polygons and makes pace for a new
* one
*/
public void addNewPolygon() {
// finish the current polygon if any
if (currentPolygon != null) {
finishPolygon(currentPolygon);
polygonsList.add(currentPolygon);
}

currentPolygon = new ArrayList<Point>();
}

public void mouseClicked(MouseEvent e) {

if (!drawingRectangle) {
int x = e.getX();
int y = e.getY();

// check if the cursor is within image area
if (x > image.getWidth() || y > image.getHeight()) {
// if not do nothing
return;
}

Graphics2D g = (Graphics2D) this.getGraphics();

// if the left button than we will add a vertex to poly
if (e.getButton() == MouseEvent.BUTTON1) {
g.setColor(Color.GREEN);
if (currentPolygon.size() != 0) {
Point lastVertex = currentPolygon
.get(currentPolygon.size() - 1);

g.setStroke(new BasicStroke(3));
g.drawLine(lastVertex.getX(), lastVertex.getY(), x, y);
}
g.fillOval(x - 5, y - 5, 10, 10);

currentPolygon.add(new Point(x, y));
System.out.println(x + " " + y + " polygon point");
}
}
}

public void mouseEntered(MouseEvent arg0) {
}

public void mouseExited(MouseEvent arg0) {
}

public void mousePressed(MouseEvent arg0) {
if (drawingRectangle) {
currentRectangle = new Rectangle(arg0.getX(), arg0.getY(),
arg0.getX(), arg0.getY(), Color.BLACK);

}
}

public void mouseReleased(MouseEvent arg0) {
if (drawingRectangle) {
rectangleList.add(new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor()));

System.out.println(currentRectangle.getX1() + " "
+ currentRectangle.getY1() + " " + arg0.getX() + " "
+ arg0.getY() + " rectangle point");

// unnecessary when mouseDragged calls paintComponent directly?
/*drawRectangle(new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor()));*/

currentRectangle = null;
drawingRectangle = false;

}
}

public void mouseDragged(MouseEvent arg0) {

if (drawingRectangle) {
currentRectangle = new Rectangle(currentRectangle.getX1(),
currentRectangle.getY1(), arg0.getX(), arg0.getY(),
currentRectangle.getColor());

System.out.println(currentRectangle.getX1() + " "
+ currentRectangle.getY1() + " " + arg0.getX() + " "
+ arg0.getX() + " " + "Dragging");
repaint();

// It works better using this instead on repaint()

// Graphics g = this.getGraphics();
// paintComponent(g);
}

}

public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub

}

}

关于java - 让用户在Java中用鼠标绘制一个矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12746783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com