简体   繁体   English

在java上分层绘画?

[英]Layered painting on java?

I am basically trying to do something like classic "Paint" (Microsoft's program). 我基本上试图做一些经典的“Paint”(微软的程序)。 But i want to work with layers when painting. 但我想在绘画时使用图层。 I thought i can use JPanel component as layer. 我以为我可以使用JPanel组件作为图层。

I was testing the code below. 我正在测试下面的代码。 The goal is drawing a rectangle with mouse. 目标是用鼠标绘制一个矩形。 There is a temp layer (temp) to draw on it while dragging the mouse, and there is actual layer (area) to draw when mouse released. 在拖动鼠标时有一个临时图层(temp)可以在它上面绘制,当鼠标释放时,有一个实际的图层(区域)可以绘制。 But every time i start drawing a new rectangle, old ones are disappear. 但每当我开始绘制一个新的矩形时,旧的矩形就会消失。 Also if i execute setVisible(false) and true again, everything disappears. 此外,如果我再次执行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);

What is wrong with that code? 这段代码出了什么问题?

Every time there's a repaint there's no guarantee you'll get the same graphics in the state you left it. 每次重新粉刷都无法保证您在离开状态时获得相同的图形。

Two a two-step instead: 两个两步代替:

  • Create a List of Rectangles in your class. 在类中创建一个矩形列表。
  • In your mouse listener instead of drawing to the graphics, add a rectangle to the list. 在鼠标侦听器中,而不是绘制到图形,请在列表中添加一个矩形。
  • Override paintComponent and in there draw the list of rectangles to the graphics it is passed. 覆盖paintComponent并在其中绘制矩形列表到它传递的图形。

Using the list is nice as items at the start of the list will be painted below ones at the end. 使用列表很好,因为列表开头的项目将在最后的下面绘制。

Classic bitmap-based graphics painting software operates on a target bitmap. 基于经典位图的图形绘制软件在目标位图上运行。 You can render multiple Layer s in paintComponent() , as @Keily suggests for Rectangle s. 您可以在paintComponent()渲染多个Layer ,正如@Keily为Rectangle建议的那样。

Alternatively, you may want to to look at classic object-based drawing software, outlined here . 或者,您可能希望查看此处概述的经典基于对象的绘图软件。

Here's a general idea: (I'm assuming you mean layers such as in photoshop) 这是一个大致的想法:(我假设你的意思是像在photoshop中的层)

Set up a single JPanel for drawing. 设置一个JPanel进行绘图。

Make a data structure containing all drawable objects you need for drawing. 创建一个包含绘制所需的所有可绘制对象的数据结构。

In this data structure, also make a field containing an integer expressing which layer that specific drawable object is tied to. 在此数据结构中,还创建一个包含整数的字段,该整数表示特定可绘制对象所绑定的层。

In your paintComponent() method, check which layer is currently active and only draw the the data in that layer or below it. 在paintComponent()方法中,检查当前处于活动状态的图层,并仅绘制该图层或其下方的数据。

This is what i was looking for; 这就是我所寻找的; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

My mistake; 我的错; using getGraphics() method out of paintComponent() and expecting keep changes. 使用getGraphics()方法从paintComponent()中获取并期望保持更改。

Why @Keilly's answer not working for me; 为什么@Keilly的回答不适合我; Because if i put shapes in a list or array, when a shape changed (for example; deleting a circle's 1/4) i can't update the element in the list. 因为如果我将形状放在列表或数组中,当形状发生变化时(例如,删除圆圈的1/4),我无法更新列表中的元素。 Because it doesn't be same shape anymore. 因为它不再是相同的形状。 So i have to keep shapes as drawings, and i don't have to (and dont want to) keep them separately. 所以我必须保持形状作为图纸,我不必(并且不想)将它们分开保存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM