【问题标题】:Jave Swing - Drawing lines by dragging mouse: Why does my code work?Java Swing - 通过拖动鼠标绘制线条:为什么我的代码有效?
【发布时间】:2016-04-03 17:31:14
【问题描述】:

我正在学习 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 重置为等于paintComponenet() 中的x2, y2,但我最初尝试在mouseDragged 中重置它们,如下所示:

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

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

【问题讨论】:

  • 我很确定第二个是因为每次移动鼠标时都会重新绘制整个组件。重新绘制包括背景颜色的绘制,这意味着每次重新绘制时都会擦除先前的绘制。所以你只看到了画的最后一点。
  • 我想我还是不太明白。 repaint() 在这两种情况下都会被调用。两者之间的唯一区别是方法错误,我尝试在mouseDraggedpaintComponent 中重置x, y
  • 对于repaint(),请阅读文档。 docs.oracle.com/javase/8/docs/api/java/awt/… repaint() 是 Swing 的标志,表明组件需要绘制,但不会立即发生。

标签: java swing mouseevent paintcomponent repaint


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2012-12-14
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 2020-08-27
    相关资源
    最近更新 更多