2011-08-25 2 views
51

내 질문은 SwingUtilities.invokeLater과 관련있다. 언제 사용해야합니까? GUI 구성 요소를 업데이트해야 할 때마다 사용해야합니까? 정확히 무엇을합니까? 직관적이지 않고 겉으로보기에 불필요한 코드를 추가하기 때문에 대안이 있습니까?SwingUtilities.invokeLater

+2

이는 'Control.BeginInvoke'와 같습니다. – SLaks

+0

@SLaks 사용하지 않아도되는 스레드가 하나 있다면 어떻게됩니까? – FadelMS

+4

@FadelMS Swing 프레임 워크는 자체 스레드 (EDT)를 생성하므로 항상 해당 스레드가 있습니다. (예를 들어, 사용자 클릭 등을 처리하는 "메시지 검사"루프가 없다면, 다양한 'actionPerformed'메소드가 어떻게 호출 될까요? EDT!) 그래서 당신이 * 하나를 가지고 있다고 말할 때 * thread, 나는 당신이 * 오직 * EDT를 가지고 있다고 (즉, GUI를 버리고 메인 메소드의 가장자리에서 떨어져서) intepret해야 할 것이다. 이 경우, 당신은 * invokeLater를 사용할 필요가 없을 것이다. 그러나 "백그라운드"처리를 수행 할 수는 없습니다. 그렇게하면 GUI가 완전히 잠길 것입니다 ... – aioobe

답변

52

GUI 구성 요소를 업데이트해야 할 때마다 사용해야합니까?

아니, 당신은 클릭 및 선택과 같은 사용자 시작 이벤트에 응답 할 때 항상의 ​​경우 이벤트 처리 쓰레드 (EDT)에 이미 있다면. 에서 당신이 그러나 EDT에 하지을하고있어 일부 타이머 스레드에서 GUI를 업데이트 할 경우 (GUI 업데이트를 수행 할 경우

합니다 (actionPerformed 방법은, 항상. 동부 서머 타임에 의해 호출 등), 또는 일부 네트워크 스레드 등), EDT에서 수행 할 업데이트 일정이 필요합니다. 그것이 바로이 방법입니다.

스윙은 기본적으로 스레드가 안전하지 않습니다. 즉, 해당 API와의 모든 상호 작용은 단일 스레드 (EDT)에서 수행되어야합니다. 다른 스레드 (타이머 스레드, 네트워킹 스레드 등)에서 GUI 업데이트를 수행해야한다면 언급 한 메서드 (SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, ...)를 사용해야합니다.

+0

@ Jens : 즉, 같은 스레드 (스윙)에 있거나 런타임에 작업을 수행 할 때 수행 할 수 있음을 의미합니다. – FadelMS

+1

글쎄, "또는 런타임에 일을"매우 정확하지 않습니다. 런타임에, 말하자면 타이머 스레드에서 일을한다면, 그런 다음, 이런 유형의 메소드 없이는 할 수 없습니다. – aioobe

+0

감사합니다. aioobe, 알겠습니다. – FadelMS

7

는 모든 스윙 응용 프로그램이 2 개 이상의 스레드가 있습니다

  1. 응용 프로그램
  2. 동부 서머 타임을 (이벤트 실 파견) 실행 메인 스레드가 UI를 업데이트하는 스레드를 (그래서 UI는 동결되지 않습니다).

UI를 업데이트하려면 EDT 내에서 코드를 실행해야합니다. SwingUtilities.invokeLater, SwingUtilities.invokeAndWait, EventQueue.invokeLater, EventQueue.invokeAndWait와 같은 메소드를 사용하면 EDT로 코드를 실행할 수 있습니다.

+0

간단하고 이해하기 쉽습니다. – Yahya

3

대부분의 사용자 시작 이벤트 (클릭 수, 키보드)는 이미 EDT에 있으므로 SwingUtilities를 사용할 필요가 없습니다. 이것은 EDT를 업데이트하는 main() 스레드 및 작업자 스레드를 제외하고 많은 경우를 포함합니다.

+0

대부분이 아닙니다. _ALL_ – kleopatra

+0

글쎄, 사용자는 GUI를 업데이트하는 스레드가 모니터링하는 파일을 업데이트 할 수 있습니다. –

+1

음 ...사용자가 시작한 이벤트 (사용자가 시작한 이벤트) : 사용자가 OST를 트리거하는 파일 (EDT에서 스윙 안쪽)을 업데이트하고 EDT에서 버튼을 클릭하여 저장합니다. 파일 갱신 이벤트 (외부 스윙, 오프 EDT) 통지, 그 통지는 EDT에서 GUI를 갱신하는 모니터 (오프 EDT)에 도달합니다 – kleopatra

7

제 질문은 이번에는 SwingUtilities.invokeLater과 관련이 있습니다. 언제 사용해야합니까?

Java에서 이해할 수있는 핵심은 스윙 관련 이벤트를 처리하는 별도의 스레드 (EDT)가 있다는 것입니다.

invokeLater()을 사용하면 현재 스레드에서 수행하려고 시도하는 대신 데스크톱 응용 프로그램의 기본 JFrame을 표시해야합니다 (예 :). 또한 나중에 응용 프로그램을 정상적으로 종료 할 수있는 컨텍스트를 만듭니다.

대부분의 애플리케이션에서 사용 가능합니다.

GUI 구성 요소를 업데이트해야 할 때마다 사용해야합니까? 정확히 무엇을합니까?

GUI 구성 요소를 수정하면 나중에 Swing에 의해 디스패치되도록 등록 된 이벤트를 트리거합니다. 이 이벤트에 대한 청취자가있는 경우 EDT 스레드가이를 어딘가에 호출합니다. invokeLater()을 사용할 필요가 없으며 구성 요소에서 리스너를 올바르게 설정하면됩니다.

이 스레드는 화면의 프레임 등을 그리는 스레드와 같습니다. 따라서 청취자는 복잡한/긴/CPU 집중적 인 작업을 수행하면 안됩니다. 그렇지 않으면 화면이 멈 춥니 다.

직관적이지 않고 겉으로보기에 불필요한 코드가 추가 되었기 때문에 대안이 있습니까?

구성 요소에 관심이있는 청취자와 invokeLater()으로 애플리케이션을 표시하는 것보다 더 많은 코드를 작성할 필요는 없습니다. 나머지는 스윙에 의해 처리됩니다.

12
Swing is single threaded and all changes to the GUI must be done on EDT 

기본 사용법에 대한 invokeLater()

    주요 방법은 항상 invokeLater()에 싸여해야

  1. 는 지연 (비동기식) EventQueue의 마지막에 액션/이벤트,

  2. EDT가 없으면를 사용하여 새 EDT를 만들어야합니다. 10. 당신은 if (SwingUtilities.isEventDispatchThread()) {...

  3. invokeAndWait()이 존재 그것을 테스트 할 수 있지만 현재까지 I (내보기) 대신 invokeLater()invokeAndWait()를 사용하는 이유를 찾을 수없는, GUI (JTree에 &의 JTable)에 하드 변경을 제외하고,하지만 단지 백그라운드 작업의 모든 출력이 invokeLater()

    에 싸여해야 Concurrency in Swing

  4. :

  5. 기본 재료 Substance L&F (동부 서머 타임에 이벤트의 테스트 일관성 우수한)와