Alex Alex - 25 days ago 8
Java Question

paintComponent() vs paint() and JPanel vs Canvas in a paintbrush-type GUI

I got some interesting ideas and criticism from this, this and this post (see last post for the code of the GUI in question). Nevertheless, I'm still quite confused about some things. Mainly, what is the least expensive way of displaying user-introduces graphics?

More specifically, I used a

paintComponent()
method from
JPanel
class by making an object of this class in the
MouseDragged()
method together with
paintComponent(getGraphics())
method (
AuxClass2
and
AuxClass1
accordingly).

Apparently, using
getGraphics()
and
paintComponent()
instead of
repaint()
are bad ideas, I suspect something to do with memory use. Also calling the
AuxClass2
every time the user drags the mouse is also a bad idea.

Also JPanel vs Canvas (i.e. swing vs awt) is a bit confusing. What is used and when?

I've been trying to find a workarounds, but have not found one, especially for the
getGraphics()
method: how else can the graphics be added to the panel?

Answer

I've been trying to find a workarounds, but have not found one, especially for the getGraphics() method: how else can the graphics be added to the panel?

You remember what needs to be painted as a variable and use that in paintComponent(). For example, what you seemed to be trying to do in your other question would look like:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PaintRectangle extends JPanel {

    private Point mouseLocation;

    public PaintRectangle() {
        setPreferredSize(new Dimension(500, 500));

        MouseAdapter listener = new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                updateMouseRectangle(e);
            }

            private void updateMouseRectangle(MouseEvent e) {
                mouseLocation = e.getPoint();
                repaint();
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                updateMouseRectangle(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                mouseLocation = null;
                repaint();
            }
        };
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }

    private Rectangle getRectangle() {
        if(mouseLocation != null) {
            return new Rectangle(mouseLocation.x - 5, mouseLocation.y - 5, 10, 10);
        }
        else {
            return null;
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Rectangle rectangle = getRectangle();
        if(rectangle != null) {
            Graphics2D gg = (Graphics2D) g;
            gg.setColor(Color.BLUE);
            gg.fill(rectangle);
            gg.setColor(Color.BLACK);
            gg.draw(rectangle);
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new PaintRectangle());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

See also http://docs.oracle.com/javase/tutorial/uiswing/painting/