Java中的分层绘画?

4

我基本上想做像经典的"画图"(微软的程序)一样的东西。但是我希望在绘画时使用图层。我认为我可以使用JPanel组件作为图层。

我正在测试下面的代码。目标是用鼠标绘制一个矩形。有一个临时层(temp)用于在拖动鼠标时进行绘制,还有一个实际层(area),用于在释放鼠标时进行绘制。但是每次我开始绘制新的矩形时,旧的矩形都会消失。而且如果我执行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);

这段代码有什么问题?

1
问:这段代码有什么问题吗? 答:getGraphics() - kleopatra
4个回答

6
每次重新绘制时,不能确保您会得到与离开时相同的图形状态。请采用以下两步替代方案:
1. 在您的类中创建一个矩形列表。 2. 在鼠标监听器中,不要直接在绘图上进行绘制,而是将矩形添加到列表中。然后覆盖 paintComponent 方法,并在其中将矩形列表绘制到传递给它的绘图上。
使用此列表很好,因为列表开始处的项目将被绘制在末尾处的项目之下。

但我不仅仅处理矩形。会有很多随机的形状,也许我会删除一个包含这些形状部分的图层。如果我能每次发布时保留整个图层图形,那么编码将更容易,内存负担也会更轻。但我不知道该怎么做。 - previous_developer

2

1
这里有一个大致的想法:(我假设你指的是像Photoshop中的图层)
设置一个单独的JPanel用于绘制。
创建一个包含所有可绘制对象的数据结构以供绘制使用。
在此数据结构中,还要创建一个字段,其中包含表示特定可绘制对象所属图层的整数。
在您的paintComponent()方法中,检查当前活动的图层,并仅绘制该图层或其下方的数据。

0

这就是我一直在寻找的东西; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

我的错误; 在paintComponent()之外使用getGraphics()方法并期望保持更改。

为什么@Keilly的答案对我不起作用; 因为如果我将形状放入列表或数组中,当形状发生变化时(例如; 删除圆的1/4),我无法更新列表中的元素。因为它不再是相同的形状。所以我必须将形状保留为绘图,并且我不必(也不想)将它们分开保存。


如果形状在列表中,您可以从任何地方修改它。列表只是指向您提供的对象,因此保留对它们的引用,并对每个单独的形状进行所需的操作。 - Keilly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接