我有两个类似的类,在MyPanel类中,我重写了paintComponent方法,将自己的“图形”添加到JPanel。我之所以调用super.paintComponent(g),是因为据我了解,当我使用自己的继承方法实现时,我也重写了此方法的标准“隐藏”功能。我了解,如果我想在myPanel上使用诸如setBackground / setBorder之类的方法,则必须从扩展类中调用paintComponent方法,以使其以自己的标准方式工作
(油漆背景,寄宿生等)。

因此,我认为每当我按下鼠标按钮时,我都会调用moveSquare方法,它将调用repaint方法。调用repaint方法时,程序将转到重写的paintComponent方法。我知道当我使用

repaint(squareX, squareY, squareW, squareH);


在moveSquare方法中,它将仅重新绘制红色方块(不会重新绘制背景),这就是为什么我将在面板上看到每个红色方块的原因。我知道如果我会在第一次调用中使用repaint()然后使用这样的参数进行重画:

                    repaint();
        squareX=x;
        squareY=y;
        repaint(squareX, squareY, squareW, squareH);


它会重新绘制背景,然后绘制一个正方形,所以我将只能在面板上看到最后一个红色绘制的正方形。我不明白的是为什么为什么要对带有参数的repaint方法进行两次调用:

                    repaint(squareX, squareY, squareW, squareH);
        squareX=x;
        squareY=y;
        repaint(squareX, squareY, squareW, squareH);


将首先绘制一个带有背景颜色的正方形,然后绘制一个红色(它的行为就像我会在不带参数的情况下调用repaint,然后使用参数进行重画)。

很抱歉提供这么长的解释,但是我认为,如果
我将解释我认为它应该如何工作。

SwingMoveSquareDemo类

public class SwingMoveSquareDemo {

public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable(){

                    public void run(){
                        System.out.println("GUI started");
                        createGUI();

                    }

                    });


}

public static void createGUI(){

    JFrame f = new JFrame("Move square demo");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new MyPanel());

    f.pack();
    f.setVisible(true);


}





}


MyPanel类

public class MyPanel extends JPanel {

private int squareX=1;
private int squareY=1;
private int squareW=20;
private int squareH=20;

public MyPanel(){

    setBackground(Color.GRAY);
    setBorder(BorderFactory.createLineBorder(Color.WHITE));
    setPreferredSize(new Dimension(400,250));


    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent e) {
            System.out.println("mouspressed");
            moveSquare(e.getX(),e.getY());
        }
    });




}

private void moveSquare (int x, int y){


            repaint(squareX, squareY, squareW, squareH);
        squareX=x;
        squareY=y;
        repaint(squareX, squareY, squareW, squareH);





}



public void paintComponent(Graphics g){

    super.paintComponent(g);

    System.out.println("paint component");

    g.setColor(Color.RED);

    g.fillRect(squareX, squareY, squareW, squareH);


}


}

最佳答案

paintComponent委托给ComponentUI#update,后者将Graphics上下文的颜色设置为组件的背景色并填充0, 0, c.getWidth(), c.getHeight()(其中c是对绘制组件的引用)。

基本上,这意味着,即使您使用repaintrepaint(x, y, width, height),背景也会开始完全更新。

不同之处在于Graphics剪辑会更改。调用repaint时,剪辑将是组件的大小,使用repaint(x, y, width, height)时,剪辑的形状将与您传递的值相同。

您可能需要查看Painting in AWT and Swing以获得更多详细信息。

记住,Swing中的绘画受RepaintManager的控制,它将决定应绘画什么以及何时绘画。当它决定需要进行更新时,它将在事件队列中放置一个“绘制”事件,该事件将在将来的某个时间由事件调度线程进行处理。这意味着,在大多数情况下,绘画不是即时的。

关于java - Java Swing-super.paintcomponent(g)-repaint(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20083404/

10-10 12:49