我的问题是如何让repaint()在从方法执行时正常工作,或者更具体地说是从actionlistener执行。为了说明我的观点,moveIt()方法从初始go()执行时,按预期调用repaint(),你会看到圆形幻灯片。当从ActionListener按钮调用moveIt()时,圆圈从开始位置跳到结束位置。我在调用repaint()之前和repaint()中包含了一个println语句,你可以看到repaint()在启动时调用了10次,而在按下按钮时只调用了一次。 - 提前感谢您的协助。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleAnimation {
int x=70;
int y=70;
MyDrawPanel drawPanel;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawPanel = new MyDrawPanel();
JButton button = new JButton("Move It");
frame.getContentPane().add(BorderLayout.NORTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
button.addActionListener(new ButtonListener());
//frame.getContentPane().add(drawPanel);
frame.setSize(300,300);
frame.setVisible(true);
// frame.pack(); Tried it with frame.pack with same result.
moveIt();
}//close go()
public void moveIt(){
for (int i=0; i<10; i++){
x++;
y++;
drawPanel.revalidate();
System.out.println("before repaint"); //for debugging
drawPanel.repaint();
try{
Thread.sleep(50);
}catch (Exception e){}
}
}//close moveIt()
class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
moveIt();
}
}//close inner class
class MyDrawPanel extends JPanel{
public void paintComponent(Graphics g){
System.out.println("in repaint"); //for debugging
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.blue);
g.fillOval(x, y, 100, 100);
}
}//close inner class
}
答案 0 :(得分:2)
您正在EDT(事件调度线程)上执行长时间运行的任务(休眠)。因此,当EDT处于休眠状态时,它无法更新UI,并且重新绘制无法按预期工作。
要纠正这种情况,请始终睡在单独的线程上。
对于此类情况,请使用SwingWorker或Timer
请查看this帖子,了解有关如何以线程安全方式访问swing组件的更多信息。
更新: This页面更好地解释了它。
答案 1 :(得分:2)
在Thread.sleep
中调用ActionListener
阻止EDT
并导致GUI“冻结”。您可以在此处使用Swing timer。