我基本上试图做一些经典的“Paint”(微软的程序)。但我想在绘画时使用图层。我以为我可以使用JPanel组件作为图层。
我正在测试下面的代码。目标是用鼠标绘制一个矩形。在拖动鼠标时有一个临时图层(temp)可以在它上面绘制,当鼠标释放时,有一个实际的图层(区域)可以绘制。但每当我开始绘制一个新的矩形时,旧的矩形就会消失。此外,如果我再次执行setVisible(false)和true,一切都会消失。
MouseInputAdapter mia = new MouseInputAdapter() {
private int startx = 0, starty = 0, stopx = 0, stopy = 0;
public void mousePressed(MouseEvent evt) {
startx = evt.getX();
starty = evt.getY();
}
public void mouseDragged(MouseEvent evt) {
Graphics2D tempg = (Graphics2D) temp.getGraphics();
int width = Math.abs(startx - evt.getX());
int height = Math.abs(starty - evt.getY());
int x = evt.getX(), y = evt.getY();
if(x > startx)
x = startx;
if(y > starty)
y = starty;
Rectangle r = new Rectangle(x, y, width, height);
tempg.clearRect(0, 0, getWidth(), getHeight());
tempg.draw(r);
}
public void mouseReleased(MouseEvent evt) {
Graphics2D g = (Graphics2D) area.getGraphics();
stopx = evt.getX();
stopy = evt.getY();
int width = Math.abs(startx - stopx);
int height = Math.abs(starty - stopy);
int x = startx, y = starty;
if(x > stopx)
x = stopx;
if(y > stopy)
y = stopy;
Rectangle r = new Rectangle(x, y, width, height);
g.draw(r);
}
};
area.addMouseListener(mia);
area.addMouseMotionListener(mia);
temp.addMouseListener(mia);
temp.addMouseMotionListener(mia);
该代码有什么问题?
答案 0 :(得分:6)
每次重画时,都不能保证你会在你离开的状态下获得相同的图形。
两个步骤改为:
使用列表很不错,因为列表开头的项目将在末尾的下面绘制。
答案 1 :(得分:2)
Classic bitmap-based graphics painting软件在目标位图上运行。您可以在Layer
中呈现多个paintComponent()
,正如@Keily为Rectangle
所建议的那样。
或者,您可能希望查看classic object-based drawing软件,概述here。
答案 2 :(得分:1)
这是一个大致的想法:(我假设你的意思是像在Photoshop中的层)
设置单个JPanel进行绘图。
创建一个包含绘制所需的所有可绘制对象的数据结构。
在这个数据结构中,还要创建一个包含整数的字段,表示特定可绘制对象绑定到哪个层。
在paintComponent()方法中,检查当前处于活动状态的图层,并仅绘制该图层或其下方的数据。
答案 3 :(得分:0)
这就是我所寻找的; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html
我的错误;使用getGraphics()方法从paintComponent()中获取并期望保持更改。
为什么@Keilly的回答不适合我;因为如果我将形状放在列表或数组中,当形状发生变化时(例如,删除圆圈的1/4),我无法更新列表中的元素。因为它不再是相同的形状。因此,我必须将形状保持为图纸,而且我不必(并且不希望)将它们分开保存。