2011-03-19 3 views
1

스윙을 기반으로하는 GUI가있는 Java 프로그램이 있습니다. 메인 클래스에는 별도의 스레드로 그룹화 된 계산이 있습니다. 내 문제는 : 나는 그 계산이 시작되면 스톱워치를 시작하고, 타이머가 진행되는 동안 보여 주며, 끝내면 멈춰야한다. 남은 시간을 계산할 필요가 있다면 별도의 스레드에서 스톱워치를 시작하고 주 스레드의 모든 계산을 마친 후 스톱워치 스레드를 중단하고 타이머를 표시합니다. 제가 알듯이 자바 스윙은 singlethreaded입니다. 그래서 메인 스윙에서 스톱워치의 digith를 다시 칠할 수 있습니다.자바 스윙 : 이벤트 디스 패칭 스레드 VS 스톱워치

답변

1

:

다음은 초에 의해 계산하려면이 옵션을 사용할 수있는 방법에 대한 간단한 예입니다.

나는 @Ernest 프리드먼 힐의 javax.swing.Timer 제안을지지 하겠지만,이 SwingWorkerexample 탐험 가치가있다. 기존 스레드 코드를 활용하는 데 도움이 될 수 있습니다.

3

가장 쉬운 방법은 javax.swing.Timer를 사용하는 것입니다. Timer가 GUI를 업데이트하기 위해 정기적 인 업데이트 이벤트를 보내는 것이 쉽습니다. 필요에 따라 타이머를 중지하거나 재설정하는 것이 쉽습니다.

+0

답변을 주셔서 감사합니다. 그러나 모든 계산이 끝났을 때 타이머를 중지해야하며 이는 정기적 인 조치가 아닙니다. 알림을 제공 할 수있는 방법이 있습니까? – Dmitry

+0

스톱워치 **의 타이머 틱 자체는 ** 정기적 인 동작이며 예를 들어 타이머 인스턴스에서 stop()을 호출하면 타이머를 쉽게 중지 할 수 있습니다. –

+0

하지만 내 타이머는 완벽하게 작동합니다.) 나는 계산이 완료되면 타이머까지 알림을 받아야합니다. 타이머가이 알림을 받으면 중지해야합니다. 타이머의 GUI는 3 개의 JLabels입니다 : jlbl_min : jlbl_seconds : jlbl_millis. 그래서 타이머가 이벤트 디스패처 스레드에서 작동 할 때마다 밀리 초마다 하나 또는 여러 개의 레이블을 다시 그려야합니다. – Dmitry

0

스윙 타이머는 다소 효과가 있지만 다소 부정확 할 수 있습니다. 사실, 부정확성은 두드러 질 수 있습니다. 예를 들어, 스윙 타이머를 사용하여 타이머를 작성한 다음 틱이 표시된대로 숫자를 볼 경우 항상 틱 사이에 정확히 두 번째가 아님을 알 수 있습니다. 즉, 타이머의 해상도가 그렇게 좋지는 않습니다.

스윙 타이머의 대안은 System.nanoTime()입니다. 나는 항상 이것을 사용한다. 훨씬 더 나은 해결책이 있습니다. 현재 시스템 시간을 나노 초 단위로 반환합니다. 내가 SwingWorker 내가 필요한 것 같다 읽었습니다

long previousTime = 0L; 
int seconds = 0; 
while(true) 
{ 
    long currTime = System.nanoTime(); 

    if((currTime - previousTime)/1000000000L >= 1L) 
    { 
     previousTime = currTime; 
     seconds++; 
     System.out.println("Seconds: " seconds) 
    } 
} 
+0

실제로 "타이머"는 잘못된 이름입니다. 당신은 시간을 보내기 위해 그것들을 사용하지 않습니다. 당신은 정기적 인 통보를주기 위해 그것들을 사용합니다. 당신은 일어나, 당신은 시간을 확인합니다 - 가능하면 시스템을 사용하십시오.nanoTime() - 그에 따라 반응하십시오. 어쨌든, 시간을 사용하여 시계의 두 번째 손을 업데이트한다면 250ms 웨이크 업을 할 수 있습니다. 대부분은 무시 될 것입니다. –

+0

답변 해 주셔서 감사합니다! 나는 직접 타이머를 썼다. 그리고 그것은 정말로 잘 작동한다. 문제는 그것이 스윙을 기반으로하고 스윙이 싱글 스레드이기 때문에 별도의 스레드에서 계산을 통해 타이머를 중지하라는 알림을 제공 할 수 없다는 것입니다. – Dmitry

+0

while 루프는 개념 증명을위한 것일 뿐이므로, while 루프의 내용을 코드의 루프로 이동하여 GUI 인터페이스를 업데이트하는 경우, 이는 사용자의 목적에 맞게 작동해야합니다. – jbranchaud

1

우선, 여러분 모두에게 감사드립니다.

이 문제는 usind SwingWorker에 의해 다음과 같이 해결되었습니다. SwingWorker의 자식으로 개발 한 메인 스윙 창. 모든 계산은 doInBackground 메소드에 있습니다. 처리가 진행되는 동안, 별도의 스레드에있는 타이머가 SwingUtilities.invokeLater에서 호출되었습니다. done 메서드에서 모든 계산이 완료되면 타이머가 중지되었습니다.