【问题标题】:Layered painting on java?java上的分层绘画?
【发布时间】:2012-02-11 22:28:44
【问题描述】:

我基本上是在尝试做一些经典的“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);

那段代码有什么问题?

【问题讨论】:

  • 问:那段代码有什么问题? 答:getGraphics()

标签: java swing draw paint


【解决方案1】:

每次重绘时,都无法保证您会在离开时获得相同的图形。

两步两步代替:

  • 在您的班级中创建一个矩形列表。
  • 在您的鼠标侦听器中,而不是绘制到图形,向列表中添加一个矩形。
  • 覆盖paintComponent并在其中将矩形列表绘制到它所传递的图形。

使用列表很好,因为列表开头的项目将绘制在末尾的下方。

【讨论】:

  • 但我不是只处理矩形。会有很多随机形状,也许我会删除可以包含这些形状的一部分的图层的一部分。如果我可以在每次发布时保留整个图层图形,我认为它会更容易编码和更轻的内存。但我不知道该怎么做。
【解决方案2】:

Classic bitmap-based graphics painting 软件在目标位图上运行。您可以在paintComponent() 中渲染多个Layers,正如@Keily 为Rectangles 所建议的那样。

或者,您可能想查看classic object-based drawing 软件,概述here

【讨论】:

    【解决方案3】:

    这是一个总体思路:(我假设您的意思是诸如 photoshop 中的图层)

    设置一个单独的 JPanel 进行绘图。

    创建一个数据结构,其中包含绘图所需的所有可绘制对象。

    在此数据结构中,还创建一个包含整数的字段,表示特定可绘制对象绑定到哪个层。

    在您的paintComponent() 方法中,检查当前处于活动状态的图层并仅在该图层中或其下方绘制数据。

    【讨论】:

      【解决方案4】:

      这就是我想要的; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

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

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

      【讨论】:

      • 如果形状在列表中,您可以从任何地方修改它。该列表只是指向您提供给它的对象,因此请保留对它们的引用并对每个单独的形状做您喜欢的事情。
      猜你喜欢
      • 2023-03-11
      • 2015-03-16
      • 2013-05-22
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 2014-08-20
      • 2017-01-27
      • 2013-07-15
      相关资源
      最近更新 更多