2013-01-06 2 views
1

제 질문은 메서드에서 실행될 때 제대로 작동하려면 repaint()를 얻는 방법입니다. 특히 actionListener에서 실행하는 것이 좋습니다. 요점을 설명하기 위해 move() 메서드는 초기 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 (이벤트 발송 쓰레드)에 장기 실행 작업 (수면)을 수행한다. 결과적으로 EDT가 잠자기 상태 일 때 UI를 업데이트 할 수 없으며 다시 칠하기가 예상대로 작동하지 않습니다.

상황을 수정하려면 항상 별도의 스레드에서 절전하십시오. 이러한 상황

봐 스레드 안전한 방법으로 스윙 구성 요소에 액세스하는 방법에 대한 자세한 정보를 원하시면 this 게시물에 대한

사용 SwingWorker 또는 Timer.

업데이트 :This 페이지가 더 잘 설명되어 있습니다.

2

ActionListenerThread.sleep을 호출하면 EDT이 차단되어 GUI가 "고정"됩니다. 대신 Swing timer을 사용할 수 있습니다.