2011-03-24 4 views
6

대부분의 Java 프로그래머가 알고 있듯이 Swing GUI에 대한 업데이트는 AWT 이벤트 발송 스레드에서만 수행해야하며 장기 실행 프로세스는 "작업자"스레드에서 실행되어야하며, 업데이트는 SwingUtilities.invokeAndWait() 또는 SwingUtilities.invokeLater()을 사용하여 이벤트 발송 스레드로 전송됩니다.작업자 스레드에서 Java Swing 사용자를 차단하기위한 패턴

장시간 진행되는 프로세스가 완료되는 동안 사용자가 응용 프로그램을 계속 사용하지 못하게하려면 어떻게합니까? 컨트롤을 회색으로 처리하고 위에서 언급 한 SwingUtilities 호출을 사용하여 작업자 스레드에서 다시 활성화 할 수 있습니까?

더 나은 대체 패턴이 있습니까?

+1

사용자가 응용 프로그램을 사용하지 못하게하는 이유는 무엇입니까?가능하다면 그 일을 피하고 계속 지내고 싶을 것입니다. 그래도 모달 대화 상자는 어떻습니까? 컨트롤을 사용하지 않도록 설정할 수도 있습니다. – justkt

+0

좋은 질문입니다. ProgressMonitor를 제외하고는 표준 답변을 모릅니다. – keuleJ

+0

@justkt : 장기 실행 프로세스가 표시되는 것에 영향을주는 경우 사용자가 작업을 취소하는 것을 제외하고는 다른 작업을 수행하지 않을 수도 있습니다. 일반적으로 "취소"버튼을 제외하고는 버튼이 비활성화 된 모달 대화 상자가 있지만 좀 더 일반적인 패턴을 원합니다. – Ralph

답변

3

나는 3 개 솔루션을 고려할 것입니다 :

  • 패널의 구성 요소를 사용하지 : 그것은 내가 뭘 일반적입니다. 불행히도 Swing은 패널과 모든 자식을 비활성화하는 간단한 방법을 제공하지 않지만 재귀를 수행하는 것은 쉽습니다 (이에 대해서는 this other SO answer 참조). 또 다른 문제는 활성화되거나 비활성화 될 때 (예 : JList)
  • 의 카드를 CardLayout으로 패널을 숨기고 CardLayout이있는 패널에 숨기고 2 개의 구성 요소를 추가하는 경우에도 일부 스윙 구성 요소가 동일하게 보입니다. 첫 번째는 비활성화 할 구성 요소를 호스팅하는 패널이고 두 번째는 "로드 중"또는 "기다려주십시오"메시지를 표시하는 패널입니다. 단순한 JLabelGridbaglayout입니다. 그런 다음 하나에서 다른 것으로 전환해야합니다. 계산/요청 결과가 표시 될 장소에이 기술을 사용합니다.
  • 마우스 이벤트을 소비하는 패널 상단에 구성 요소를 넣으십시오 : LayeredPane으로 직접 할 수도 있고 전용 유틸리티를 사용할 수도 있습니다. JXLayer (JXLayer가 Java 7에 포함될 것이므로이 문제에 대한 '표준'솔루션이 될 수 있음을 읽었습니다.)
0

내가 한 일은 보니 Jframe.setGlassPane()을 사용하고 모든 이벤트를 먹는 구성 요소를 설정하는 것입니다. 창의력을 발휘하고 유리판에서 회전 대기중인 GIF 플래시를 사용할 수도 있습니다. 그러나 유리판을 세우는 것이 당신이 원하는 전부는 아닐 수도 있습니다. 고급 요구 사항의 경우, 이벤트 대기열을 가지고 놀아야 할 수도 있습니다.

2

GUI의 디자인과 레이아웃에 따라 여러 가지 방법과 선택 방법이 있습니다.

  • 를 사용하여 진행 바 - 패널 또는 사용자가 진행률 표시 줄과 접촉하지 않는 영역을 교체합니다. 이렇게하면 아직 원하지 않는 이벤트를 처리하지 않고 사용자에게 배경에서 어떤 일이 일어나고 있음을 분명히 알 수 있습니다.
  • 단추를 비활성화하고 대기 커서를 추가하십시오. - 작업이 완료되는 동안 setEnable (false)을 사용하고 커서가 대기 커서로 변경 될 수 있습니다. 이것은 일시적인 기간에만 옵션을 사용할 수 없다는 것을 다시 한번 분명히합니다.
  • 이벤트에 응답하지 않거나 GlassPane을 위로내어 - 응용 프로그램이 응답하지 않는 것처럼 보이기 때문에 사용자 친구가 적습니다. 그러나 상황에 따라 적절할 수도 있습니다.
관련 문제