在我为我的类构建的程序中,我有相同的类扩展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()调用不起作用。为什么会这样?
如果我为对象制作了不同的类,我猜它会起作用,但我对为什么它不会以这种方式工作感到好奇。
答案 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();