Question

I'm doing a selection tool and I've come with these solutions, in the first using the JPanel getGraphics method I draw a oval wherever the mouse been dragged, in the second I override the paintComponent method to draw the oval.

When I execute the first one there's flickering while dragging the mouse and the drawing is poor, while with the second approach runs perfect. Why does this happen?, if I quit repaint in the first solution it draws the ovals and doesn't 'delete' them.

What are best practices to do something like this?, am I missing something when I draw with getGraphics?.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class TestGetGraphics extends JFrame {

    JPanel canvas;
    Painter painter;

    class Painter{
        void paint( Graphics2D g, Point p ){
            g.drawOval(p.x, p.y, 30, 30);
        }
    }

    public TestGetGraphics(){
        super();

        canvas = new JPanel();
        painter = new Painter();

        canvas.setPreferredSize( new Dimension(400, 400) );
        canvas.setBackground(Color.WHITE);

        canvas.addMouseMotionListener(new MouseAdapter() {
                public void mouseDragged(MouseEvent me){
                    painter.paint((Graphics2D) canvas.getGraphics(), me.getPoint());
                    canvas.repaint();
                }
        });

        add( canvas );

        setVisible(true);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }


    public static void main(String [] args){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestGetGraphics();
            }
        });
    }

}

This is the paintComponent approach:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class TestPaintComponent extends JFrame  {
    JPanel canvas;
    Painter painter;

    class Painter{
        Point p;
        void paint( Graphics2D g ){
            if( p != null )
                g.drawOval(p.x, p.y, 30, 30);
        }

        void setPoint( Point p ){
            this.p = p;
        }
    }

    public TestPaintComponent(){
        super();

        canvas = new JPanel(){
            @Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                painter.paint((Graphics2D) g);

            }

        };
        painter = new Painter();

        canvas.setPreferredSize( new Dimension(400, 400) );
        canvas.setBackground(Color.WHITE);

        canvas.addMouseMotionListener(new MouseAdapter() {
                public void mouseDragged(MouseEvent me){
                    painter.setPoint(me.getPoint());
                    canvas.repaint();
                }
        });

        add( canvas );

        setVisible(true);
        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }



    public static void main(String [] args){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestPaintComponent();
            }
        });
    }
}
Was it helpful?

Solution

Don't call getGraphics() on a component. Instead, extend the component and override paintComponent(). More info here: http://docs.oracle.com/javase/tutorial/uiswing/painting/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top