Java Swing - 通过拖动鼠标画线:为什么我的代码有效?

Jave Swing - Drawing lines by dragging mouse: Why does my code work?

我正在学习 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) 在上面的代码中,我在 paintComponenet() 中将 x, y 重置为等于 x2, y2,但我最初尝试像这样在 mouseDragged 中重置它们:

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

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

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

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

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