2016-09-09 5 views
1

나는 게임 이벤트가 발생할 때 화면에 애니메이션을 보여주는 타이머가 있습니다. 내가하고 싶은 일은이 애니메이션이 끝날 때까지 주 실행을 일시 중지하는 것입니다.하지만 시도 할 때마다 타이머가 실행되는 것을 차단하는 것 같습니다. 나는 Thread.sleep()을 사용하고 lock 객체에서 wait() 및 notify()를 호출하려고했지만 동일한 결과를 보았습니다. Timer 리스너의 actionPerformed()는 호출되지 않습니다.Timer (Java Swing)를 차단하지 않고 프로그램 실행을 일시 중지하는 방법은 무엇입니까?

이 코드는 타이머 설정하십시오 EffectsPane 객체 내부

protected void showMovingEffect(int steps, Direction dir, AnimatedImageSet imgs) { 
    effectsPane.runAnimation(imgs, dir, steps); 
    waiting = true; 
    while (waiting) { 
     synchronized(animationWaitLock) { 
      try { 
       animationWaitLock.wait(); 
      } catch (InterruptedException e) {} 
     } 
    } 
} 

그리고 타이머와 청취자를 :

private void runAnimation(AnimatedImageSet ais, Direction dir, int iters) { 
     System.out.println("run"); 
     imgs = ais; 
     top = 0; 
     left = 0; 
     topStep = dir.getRowIncrement() * 10; 
     leftStep = dir.getColIncrement() * 10; 
     iterations = iters; 
     index = 0; 
     active = true; 
     timer.start(); 
    } 

public void actionPerformed(ActionEvent e) { 
     System.out.println(index); 
     top += topStep; 
     left += leftStep; 
     index++; 
     currentImage = imgs.getImage(index); 
     repaint(); 
     if (index == iterations) { 
      active = false; 
      timer.stop(); 
      synchronized(animationWaitLock) { 
       animationWaitLock.notify(); 
      } 
      waiting = false; 
     } 
    } 

의 actionPerformed의 시작에서에서 System.out.println 호출() 호출되지 않기 때문에 wait() 호출도 Timer를 일시 중지하거나 무언가를 차단하고 있습니다. showMovingEffect()에서 sleep/wait 줄을 주석 처리하면 애니메이션이 실행되지만 프로그램이 일시 중지되지 않습니다.

+0

SLEEP을 사용하지 마십시오 !!!!! – paulsm4

+0

나는 그렇지 않습니다. wait()를 사용하고 있습니다. – Leonide

답변

3

한 가지 방법은 애니메이션 진행하는 동안 modal dialog를 표시하는 것입니다. here에서 논의 된 것처럼 사용자 상호 작용은 배제되지만 javax.swing.Timer에 대한 응답으로 백그라운드 GUI 업데이트가 계속됩니다. here과 같이 사용자가 언제든지 대화 상자를 닫을 수 있도록 허용 할 수 있지만 그 시점에서 애니메이션을 포기할 수 있습니다.

사용자로부터의 입력이 필요 없습니다.

애니메이션이 시작된 후 SecondaryLoop을 입력하여 대화 상자를 표시하지 않고 사용자 상호 작용을 차단할 수 있습니다.

SecondaryLoop loop = Toolkit.getDefaultToolkit() 
    .getSystemEventQueue().createSecondaryLoop(); 
timer.start(); 
loop.enter(); 

애니메이션 결론 , exit()SecondaryLoop :

public void actionPerformed(ActionEvent e) { 
    … 
    if (index == iterations) { 
     timer.stop(); 
     loop.exit(); 
     … 
    } 
} 
+0

이것은 내가 찾던 것이 아니며 두려웠습니다. 내가 타이머를 시작한 후 일시 중지하고 끝날 때 다시 시작하는 방법을 찾고 있어요. 사용자가 입력 할 필요가 없으므로 대화 상자를 사용하면 아무런 도움이되지 않습니다. – Leonide

+0

@Leonide : 시각적 인 피드백이나 탈출 메커니즘없이 사용자 상호 작용을 차단하는 것에 조심 스럽습니다. 단편 애니메이션의 경우 위에서 설명한대로 'SecondaryLoop'을 사용할 수 있습니다. – trashgod

+0

아마도 접선 질문입니다. 이걸 시도한 첫 번째 일은 runAnimation 메서드에 주기적으로 effectsPane을 새로 고치는 루프가있는 것이었지만, 원하는대로 일시 중지되었지만 effectsPane은 새로 고치지 않았습니다. 왜 그런가? – Leonide

0

이 작업을 시도 할 수 있습니다 :

timer.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // your code 
    } 
}); 
+0

어떻게 도움이됩니까? – ChiefTwoPencils

+0

이 코드에서이 actionPerformed는 사용자의 메서드이며 acction listener 메서드가 아니기 때문입니다. 그래서 당신이 그것을 실행하고 싶다면'effectsPane.runAnimation (imgs, dir, steps);과 같은'effectsPane.actionPerformed (java.awt.Event);를 호출하거나 actionPerformed 메소드에 @Override를 추가해야합니다 – Numb

+0

시도해 보았습니다. 그러나 동일한 결과와 함께. actionPerformed 메소드가 여전히 호출되지 않습니다. Timer가 showMovingEffect를 호출하는 클래스의 멤버인지 애니메이션을 표시하는 JPanel인지는 중요합니까? – Leonide

관련 문제