为什么 repaint() 在由同一类对象的方法调用时不起作用?



在我为我的班级构建的程序中,我有相同的班级扩展挥杆jpanel并实现Mouselistener,我为此我使用了两个实例 - 一种用于JPanel,一个功能其他作为鼠标听众的jpanel。

但是,当我在窗口中单击时,repaint()鼠标侦听器中的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()调用。为什么会发生?

我猜想如果我为对象组成不同的类,但是我很好奇为什么它不起作用。

我使用两个实例化 - 一种用作JPANEL,另一个用作该JPanel的鼠标侦听器。

无需这样做。您需要的只是TestPanel类的一个实例。

在您的TestPanel类的构造函数中,您只需添加:

addMouseListener( this);

摆脱testpanel类的静态变量。

然后,您的主要方法中的代码应该看起来像:

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

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

阅读有关MouseListener的工作示例的自定义绘画教程中的部分。

AWT线程负责调用MouseListener和重新粉刷。内部()内部;方法,告诉awt线程打电话给油漆();只需使用其他线程调用它。总的来说,对AWT线程进行密集的事情是一个坏主意。它已经做了很多事情,花太多时间会弄乱您的GUI。

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

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

最新更新