Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Layered painting on java?

I am basically trying to do something like classic "Paint" (Microsoft's program). But i want to work with layers when painting. I thought i can use JPanel component as layer.

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. But every time i start drawing a new rectangle, old ones are disappear. Also if i execute setVisible(false) and true again, everything disappears.

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?

like image 548
previous_developer Avatar asked Jan 18 '23 12:01

previous_developer


2 Answers

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.

Using the list is nice as items at the start of the list will be painted below ones at the end.

like image 68
Keilly Avatar answered Jan 25 '23 11:01

Keilly


Classic bitmap-based graphics painting software operates on a target bitmap. You can render multiple Layers in paintComponent(), as @Keily suggests for Rectangles.

Alternatively, you may want to to look at classic object-based drawing software, outlined here.

like image 25
trashgod Avatar answered Jan 25 '23 09:01

trashgod