当我绘制另一个矩形时,如何保留我在 Jpanel 上绘制的矩形?
Posted
技术标签:
【中文标题】当我绘制另一个矩形时,如何保留我在 Jpanel 上绘制的矩形?【英文标题】:How to keep the rectangle that I drew on the Jpanel when I draw another rectangle? 【发布时间】:2021-05-21 23:48:33 【问题描述】:我在 JAVA 中有这段代码,当我在面板上拖动鼠标时,它会像绘图应用程序一样绘制一个矩形。每次我单击并拖动以创建一个新矩形时,前一个矩形就会消失。我想知道是否有办法让它留在面板上。并且有多个矩形,就像 windows 上的绘图应用程序一样。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DrawRect extends JPanel
int x, y, x2, y2;
public static void main(String[] args)
JFrame f = new JFrame("Draw Box Mouse 2");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new DrawRect());
f.setSize(300, 300);
f.setVisible(true);
DrawRect()
x = y = x2 = y2 = 0; //
MyMouseListener listener = new MyMouseListener();
addMouseListener(listener);
addMouseMotionListener(listener);
public void setStartPoint(int x, int y)
this.x = x;
this.y = y;
public void setEndPoint(int x, int y)
x2 = (x);
y2 = (y);
public void drawPerfectRect(Graphics g, int x, int y, int x2, int y2)
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
g.drawRect(px, py, pw, ph);
class MyMouseListener extends MouseAdapter
public void mousePressed(MouseEvent e)
setStartPoint(e.getX(), e.getY());
public void mouseDragged(MouseEvent e)
setEndPoint(e.getX(), e.getY());
repaint();
public void mouseReleased(MouseEvent e)
setEndPoint(e.getX(), e.getY());
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
g.setColor(Color.RED);
drawPerfectRect(g, x, y, x2, y2);
【问题讨论】:
当然。将每个矩形保存在 java.awt.Rectangle 对象的 java.util.List 中。从列表中绘制矩形。paintComponent
在每次面板需要更新时调用,替换面板的所有内容。您需要管理要绘制的对象列表。
【参考方案1】:
在编写 Swing 图形程序时要记住一些有用的事情:
paintComponent
每次调用时都会重新绘制整个组件,因此您需要绘制您想要出现的所有内容。您对Graphics
对象执行的操作只会持续到下一次调用paintComponent
。
Graphics2D
比 Graphics
更有能力。它使用浮点坐标、各种线条样式等绘制了很好的抗锯齿形状。 paintComponent
的 Graphics
参数实际上始终是 Graphics2D
实例,您可以将其强制转换为一个实例。
组件的继承层次也是绘画层次,所以你需要在paintComponent
方法的开头调用super.paintComponent(g)
。有关详细信息,请参阅this question。
所以我对你的程序做了一些修改:
添加了一个字段List<Rectangle2D> rectangles
来记住用户创建的矩形。每次抬起鼠标按钮时,都会向此列表添加一个矩形。
添加了对super.paintComponent
的调用
使用Graphics2D
绘制矩形,线条风格更有趣(Stroke
)
更改了您的 paintComponent
以绘制列表中的每个矩形,以及用户当前正在绘制的“橡皮筋”矩形。
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
public class DrawRect extends JPanel
int x, y, x2, y2;
// this is the list of all the rectangles the user has drawn so far
List<Rectangle2D> rectangles = new ArrayList<>();
public static void main(String[] args)
JFrame f = new JFrame("Draw Box Mouse 2");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(new DrawRect());
f.setSize(300, 300);
f.setVisible(true);
DrawRect()
x = y = x2 = y2 = 0; //
MyMouseListener listener = new MyMouseListener();
addMouseListener(listener);
addMouseMotionListener(listener);
public void setStartPoint(int x, int y)
this.x = x;
this.y = y;
public void setEndPoint(int x, int y)
x2 = (x);
y2 = (y);
// this creates a new rectangle object instead of drawing one
public Rectangle2D makePerfectRect(int x, int y, int x2, int y2)
int px = Math.min(x,x2);
int py = Math.min(y,y2);
int pw=Math.abs(x-x2);
int ph=Math.abs(y-y2);
return new Rectangle2D.Float(px, py, pw, ph);
class MyMouseListener extends MouseAdapter
public void mousePressed(MouseEvent e)
setStartPoint(e.getX(), e.getY());
public void mouseDragged(MouseEvent e)
setEndPoint(e.getX(), e.getY());
repaint();
public void mouseReleased(MouseEvent e)
setEndPoint(e.getX(), e.getY());
// when the mouse is released, we add the current rectangle to our list
rectangles.add(makePerfectRect(x,y,x2,y2));
repaint();
public void paintComponent(Graphics g)
// use Graphics2D, you can draw much nicer lines
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g);
g.setColor(Color.RED);
// draw the rectangle the user is currently drawing
g2d.draw(makePerfectRect(x,y,x2,y2));
g.setColor(Color.BLUE);
Stroke oldStroke = g2d.getStroke();
g2d.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0.0f));
for (Rectangle2D r : rectangles)
g2d.draw(r);
g2d.setStroke(oldStroke); // restore the original Stroke
【讨论】:
以上是关于当我绘制另一个矩形时,如何保留我在 Jpanel 上绘制的矩形?的主要内容,如果未能解决你的问题,请参考以下文章