在我为我的班级构建的程序中,我有相同的班级扩展挥杆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();