Jave Swing - 通过拖动鼠标绘制线条:为什么我的代码有效?

时间:2016-04-03 17:31:15

标签: java swing mouseevent paintcomponent repaint

我正在学习Swing的基础知识,并设法让这个程序通过拖动鼠标绘制一条线。

    public class SwingPaintDemo2 {

    public static void main(String[] args) {
        JFrame f = new JFrame("Swing Paint Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300,300);
        f.add(new MyPanel());
        f.setVisible(true);
    }
}

class MyPanel extends JPanel {

    private int x, y, x2, y2;

    public MyPanel() {

        setBorder(BorderFactory.createLineBorder(Color.black));
        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                x2 = e.getX();
                y2 = e.getY();
                repaint();
            }
        });

        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                x = e.getX();
                y = e.getY();
            }
        });
    }

    public void paintComponent(Graphics g){
//        super.paintComponent(g);
        g.setColor(Color.BLACK);
        g.drawLine(x, y, x2, y2);
        x = x2;
        y = y2;
    }
}

我有两个问题:

1)如果我打电话给super.paintComponent(g)没有画出来,为什么会这样?

2)在上面的代码中,我将x, y重置为x2, y2中的paintComponenet(),但我最初尝试在mouseDragged内重置它们,如下所示:< / p>

  public void mouseDragged(MouseEvent e) {
            x2 = e.getX();
            y2 = e.getY();
            repaint();
            x = x2;
            y = y2;
        }

然而,这并没有创造线条,只有一系列点。据我了解,这两种方法应该是等价的。他们有什么不同?

1 个答案:

答案 0 :(得分:2)

当您调用repaint()方法时,会向RepaintManager发出请求。然后,RepaintManager将(可能)将多个repaint()请求合并到一次调用组件的paint()方法中,然后调用paintComponent()方法。

因此,在调用paintComponent()方法时,repaint()语句之后的语句已经执行,因此x / y值已经更新。

您应该始终在方法开头调用super.paintComponent()以确保清除背景。如果你想进行增量绘画,请查看Custom Painting Approaches,它解释了执行此操作的两种常用方法。