2013-01-06 26 views
1

我的问题是关于如何使repaint()在从方法或更具体地来自actionlistener执行时正常工作。为了说明我的观点,moveIt()方法从最初的go()执行时,按预期调用repaint(),并看到圆形幻灯片。当从ActionListener按钮调用moveIt()时,圆从起始位置跳转到结束位置。在调用repaint()和repaint()内部之前,我已经包含了一个println语句,您可以看到repaint()在启动时被调用了10次,并且在按下按钮时仅调用了一次。 - 提前感谢你的帮助。repaint()没有从actionlistener正确调用

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 
} 
+6

你正在EDT上睡觉。这是错误。 –

+0

[为单个线程使用sleep()可能的重复](http://stackoverflow.com/questions/14074329/using-sleep-for-a-single- thread) –

回答

2

您正在EDT(Event Dispatch Thread)上执行长时间运行的任务(休眠)。因此,当EDT休眠时,它无法更新UI并且重新绘制不能按预期工作。

要纠正这种情况,总是睡在一个单独的线程上。

使用SwingWorkerTimer针对这种情况

this职位有关如何访问一个线程安全的方式Swing组件的详细信息。

更新:This页面解释更好。

2

ActionListener中调用Thread.sleep会阻止EDT并导致GUI“冻结”。您可以在此处使用Swing timer