当由同一个类的对象的方法调用时,为什么不重绘()工作?

时间:2016-12-02 21:15:41

标签: java swing paint

在我为我的类构建的程序中,我有相同的类扩展Swing JPanel并实现MouseListener,我使用两个实例 - 一个用作JPanel,另一个用作鼠标监听器那个JPanel。

但是当我在窗口中单击时,重绘()鼠标侦听器中的MouseClicked方法无法调用第一个对象的paintComponent()方法。例如:

import javax.swing.*; 
import java.awt.*;
import java.awt.event.*;

public class TestPanel extends JPanel implements MouseListener{
    static boolean black;
    static TestPanel test = new TestPanel();

    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseClicked(MouseEvent e){ //Expected behavior: the square turns black immediately
        System.out.println("CLICK!");
        black = true;
        test.repaint(); //this fails
        try{
            Thread.sleep(3000);
        }catch(Exception ex){}
    }

    public void paintComponent(Graphics g){
         super.paintComponent(g);
         Graphics2D g2d = (Graphics2D) g;
         System.out.println("Painting...");
         g2d.setColor(Color.white);
         if(black){
             g2d.setColor(Color.black);
         }
         g2d.fillRect(0, 0, 200, 200);
    }

    public static void main(String[] args) throws InterruptedException{
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        test.addMouseListener(new TestPanel());
        test.setPreferredSize(new Dimension(200, 200));
        frame.add(test);
        frame.pack();
        frame.setVisible(true);
        while (true){
            black = false;
            test.repaint();
            Thread.sleep(100);
        }
    }
}

如果你看一下点击发生的事情,点击注册后屏幕会保持白色3秒,直到循环再次启动,即鼠标监听器中的repaint()调用不起作用。为什么会这样?

如果我为对象制作了不同的类,我猜它会起作用,但我对为什么它不会以这种方式工作感到好奇。

2 个答案:

答案 0 :(得分:0)

  

我使用两个实例 - 一个用作JPanel,另一个用作JPanel的鼠标监听器。

没有必要这样做。您所需要的只是TestPanel类的单个实例。

TestPanel课程的构造函数中,您只需添加:

addMouseListener( this);

摆脱TestPanel类的静态变量。

然后,main方法中的代码应该类似于:

    //test.addMouseListener(new TestPanel());
    //test.setPreferredSize(new Dimension(200, 200));
    //frame.add(test);
    frame.add( new TestPanel() );  

此外,TestPanel类应覆盖getPreferredSize()方法以返回面板的尺寸。

阅读Custom Painting上的Swing教程中的部分,了解MouseListener的工作示例。

答案 1 :(得分:0)

AWT线程负责调用MouseListener和重绘。 里面的重绘();方法,告诉AWT线程调用paint(); 只需使用其他线程调用它即可。一般来说,使用AWT线程做任何密集的事情都是一个坏主意。它已经做了很多,花费太多时间会弄乱你的GUI。

根据您的需要,这可能有效:

new Thread(()->{repaint();}).start();