2013-02-26 4 views
0

JTabbedPane을 사용하여 여러 탭을 표시하는 응용 프로그램이 있습니다. 이 탭 중 하나에는 내용을 표시하기 위해 실행중인 스레드가 있습니다. 탭이 보이지 않을 때 이미 스레드를 멈추기 위해 ComponentListener를 구현했습니다. 탭을 선택하면 스레드가 활성화되고 스레드가 보이지 않을 때 스레드가 예상대로 움직이는 것을 볼 수 있습니다.JTabbedPane가 더 이상 표시되지 않을 때 JTabbedPane의 내용에 ComponentEvent (componentHidden)가 수신되도록하려면 어떻게해야합니까?

스레드가있는 탭을 선택하지 않으면 응용 프로그램을 닫으면 모든 것이 잘되고 응용 프로그램이 닫힙니다. 스레드가있는 탭이 표시 될 때 응용 프로그램을 닫으면 탭에 ComponentEvent가 수신되지 않으므로 스레드가 활성 상태로 유지되고 응용 프로그램을 수동으로 종료해야합니다 (Eclipse의 콘솔에서 Terminate 단추 사용).

응용 프로그램을 닫는 데 System.exit() 메서드를 사용하지 말고 모든 스레드를 중지하고 모든 창을 삭제하는 것이 좋습니다. 이것은 스레드와 함께 하나의 탭을 제외하고는 매력처럼 작동합니다.

나는 이미 내 창이나 removeAll()을 삭제하기 전에 JTabbedPane을 보이지 않게 설정하려고했습니다. 기대했던 결과도 없었습니다. removeAll()은 반대의 결과조차 가져왔다. 탭이 액티브하지 않았던 경우는, ComponentEvent가 표시되고있는 것을 나타 내기 위해서 ComponentEvent를받습니다 (실제로는 모든 탭이 이벤트를 차례 차례 수신합니다 만, 실제로는 componentHidden를 취득하지 않습니다).

분명히 스레드는 파일 메뉴를 통해 창을 닫을 때 (일부 컨트롤이 있고 removeAll 및 setVisible (false) 메서드를 테스트 한 곳)와 창을 닫을 때 모두 중지해야합니다 사용자가 창 모서리에서 십자 기호를 클릭하기 때문입니다.

업데이트

내가 제안 데몬 스레드로 실행 문제를 일으킬 것으로 보인다 스레드를 만들 수있는 방법을 발견했다. 그러나 이로 인해 예기치 않은 문제가 발생했습니다. 문제가있는 스레드를 시작한 클래스는 내가 사용하고있는 JUNG 소프트웨어 패키지의 VisRunner 클래스입니다. 스레드가 시작되는 "relax"메소드를 포함합니다. 나는 같은 이완제로드

import edu.uci.ics.jung.algorithms.layout.util.VisRunner; 
import edu.uci.ics.jung.algorithms.util.IterativeContext; 

public class MyVisRunner extends VisRunner { 

    public MyVisRunner(final IterativeContext process) { 
     super(process); 
    } 

    @Override 
    public void relax() { 
     // in case it's running 
     Log.d("Relaxing"); 
     stop(); 
     stop = false; 
     thread = new Thread(this); 
     thread.setPriority(Thread.MIN_PRIORITY); 
     thread.setDaemon(true); 
     thread.start(); 
    } 
} 

:

@Override 
    public void relax() { 
     // in case its running 
     stop(); 
     stop = false; 
     thread = new Thread(this); 
     thread.setPriority(Thread.MIN_PRIORITY); 
     thread.start(); 
} 

나는 MyVisRunner 클래스를 생성 한 나는이 예상 한 것

visModel = new DefaultVisualizationModel<>(layout); 
    visModel.setRelaxer(new MyVisRunner(layout)); 

이 문제를 해결하기 위해,하지만 그것은 단지 증가 문제. 지금 소프트웨어를 시작할 때 문제가있는 탭이 보이지 않더라도 (탭이 구성되어 있지만 보이지는 않지만) 멈추지 않습니다. 이 경우에는 MyVisRunner의 relax 메소드가 호출되지 않았습니다. 스레드는 VisRunner 클래스의 다른 곳에서는 초기화되지 않습니다. setRelaxer 행을 주석 처리하면이 추가 문제점 (원래의 문제점을 분명하게 유지함)을 해결할 수 있습니다. 나는 마침내 문제를 해결 한 2

업데이트. 나는 내 자신의 이완기를 설정할 때 이미 이완기가 작동하고 있다는 것을 깨닫지 못했습니다. 코드를 다음과 같이 조정했습니다 :

이 문제는 원래의 문제점과 추가로 해결되었습니다.

+0

물론이 문제를 해결하는 다른 방법 (ComponentEvent 제외)도 환영합니다. – Stefan

+0

'Thread.setDaemon (true)'를 사용 했습니까? – oliholz

+0

@oliholz, Thread.setDaemon()에 대한 MouseEvent의 대답에 대한 필자의 반응을 참조하십시오. – Stefan

답변

1

당신은 데몬 스레드로 스레드를 설정해야합니다

myThread.setDaemon(true); 

가상 머신이 종료됩니다 더 이상 실행 비 데몬 스레드가없는 경우.


BTW 당신은 ​​당신의 JFramewindowClosing에 대한 이벤트에 WindowListener를 추가 할 수 있습니다.

+0

팁 주셔서 감사합니다, 그 세부 사항을 몰랐습니다. 불행하게도, 실행중인 쓰레드는 써드 파티 라이브러리에있는 쓰레드입니다. 수정하지 않아도 좋지만, 쓰레드를 비 데몬 쓰레드로 변경하도록 요청할 수는 있습니다. – Stefan

+0

@Stefan 글쎄, 당신이 그 스레드에 대한 참조를 얻을 수 있다면, 당신은 직접 변경할 수 있습니다. – Mordechai

+0

아쉽게도 라이브러리 (JUNG, [link] (http://jung.sourceforge.net/))가 스레드에 대한 참조를 제공하지 않습니다. – Stefan