previous_developer
previous_developer

Reputation: 10988

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?

Upvotes: 4

Views: 2826

Answers (4)

previous_developer
previous_developer

Reputation: 10988

This is what i was looking for; http://www.leepoint.net/notes-java/examples/mouse/paintdemo.html

My mistake; using getGraphics() method out of paintComponent() and expecting keep changes.

Why @Keilly's answer not working for me; 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. 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.

Upvotes: 0

Josh Claxton
Josh Claxton

Reputation: 410

Here's a general idea: (I'm assuming you mean layers such as in photoshop)

Set up a single JPanel for drawing.

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.

Upvotes: 1

trashgod
trashgod

Reputation: 205785

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.

Upvotes: 2

Keilly
Keilly

Reputation: 556

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.

Upvotes: 6

Related Questions