2009-10-15 8 views
0

NetBeans를 사용하여 Swing에서 응용 프로그램을 만들고 있습니다. 창을 보이게 한 후 (예 : 한 번만) 시작하는 동안 일부 구성 요소를 조작 할 수 있기를 원합니다 (예 : 진행률 막대 업데이트). 이를 위해, 나는 응용 프로그램의 메인 클래스라는 MainWindow를이 :프로그램 시작시 Swing 구성 요소를 조작하는 올바른 방법은 무엇입니까?

public class MainWindow extends JFrame 
{ 

public MainWindow() 
{ 
    initComponents(); // NetBeans GUI builder-generated function for setting 
         // up the window components 

} 

public void Init() 
{ 
    loadLabel.setText("Loading...."); 
    loadProgressBar.setValue(20); 
    doSomething(); 
    loadProgressBar.setValue(40); 
    doSomething(); 
    loadProgressBar.setValue(80); 
    doSomething(); 
    loadProgressBar.setValue(100); 

    loadLabel.setVisible(false); 
    loadProgressBar.setVisible(false); 
} 

/* .... */ 

public static void main(String args[]) 
{ 
    java.awt.EventQueue.invokeLater(new Runnable() 
    { 
     public void run() 
     { 
      mainHandle = new MainWindow(); 
      mainHandle.setVisible(true); 
      mainHandle.Init(); 
     } 
    }); 
} 

} 

문제는 초기화 내에서 진행 표시 줄을 업데이트 (또는 다른 GUI 구성 요소를 조작)에 대한 진술의 효과() 함수를 할 수있다 관찰되지 않습니다. Init() 함수가 위와 같이 main() 함수에서 호출되면, 윈도우는 나타나지만 비어 있습니다. Init() 함수는 실행 후 윈도우가 내용을 그려야 만 Init() 창문이 비어 있고 전체 시간 동안 비활성 이었기 때문에 눈에 보이지 않습니다. Window가 완전히 그려진 후에 실행되는 windowOpened() AWT 이벤트에서 init을 호출 해 보았습니다. 그러나 놀랍게도 구성 요소를 조작하기위한 모든 명령문을 두는 것은 효과가없는 것 같습니다. 또는 오히려 대기열에 넣고 빠르게 실행되었습니다. 어떤 점은 연속적으로 나타납니다. 따라서 마지막 요소 (요소 숨기기)의 영향 만 관찰 할 수 있습니다. 필자가 관리 할 수 ​​있었던 유일한 방법은 전체 invokeLater (새로운 Runnable() ...) 만트라를 제거하고 새 MainWindow(), setVisible(), Init() 시퀀스를 main()에 직접 삽입하는 것이 었습니다. 매우 추한이며 스레드 방식으로 실행 GUI의 개념을 깨고. 이 작업을 수행하는 올바른 방법은 무엇입니까? gui를 조작 할 준비가되었을 때 코드를 가장 먼저 실행하려면 어디에서 명령문을 실행하고 제어를 메인 이벤트 루프로 리턴해야합니까?

Init() 함수가 작동하는 동안 gui 구성 요소의 모든 작업이 일시 중단됩니다 (드로잉 스레드가 분리되어 있지 않고 Init()가 조작이 실행되기 전에 완료). 어쩌면 Init()를 새로운 스레드로 만들어야 만합니다 ... 어떻게 그리고 어떤 종류 만?

감사합니다.

답변

1

EventQueue.invokeLater()를 invokeAndWait()로 변경하고 init()에 대한 호출을 두 번째 EventQueue.invokeLater() 호출로 이동할 수 있습니다.

doSomething()이 눈에 띄는 시간이 소요되면 Init 코드를 SwingWorker의 본문으로 옮기는 것이 좋습니다. 이것은 MainWindow() 생성자에서 실행되거나 main에서 setVisible() 호출 후에 실행될 수 있으며 반응 GUI를 사용하는 관용적 인 방법입니다 (사용자가 지루하고 기다리고 싶어하는 경우).

doSomething() 호출 사이의 진행률 막대를 업데이트하는 방법에 대한 자세한 내용은 processpublish 메서드를 참조하십시오.

ProgressMonitors을보고 대화 상자 등을 다루는 다른 방법을 찾아 볼 수도 있습니다.

1

당신이 할 수있는 몇 가지가 있습니다 Windows 용

  1. (예 : JFrame 또는 JDialog로) 당신의 WindowListener를 첨부 할 수 있습니다와의 windowOpened 방법에 조작을한다.
  2. addNotify 메서드를 덮어 쓰고 거기에서 제어 조작을 수행하십시오.
  3. HierarchyListener을 첨부하고 구성 요소의 표시 가능성이 변경 될 때마다 조작하십시오.

항상 EDT에서 구성 요소 조작을 수행해야합니다.간단한 UI 업데이트에는 SwingUtilities.invokeLater, 장기 실행 작업에는 SwingWorker을 사용하십시오.

+0

광고 1 : 나는 어떤 것을 얻지는 못했지만 시도하는 것에 대해 언급 한 것으로 보이고 작동하지 않습니다. – neuviemeporte

+0

내가 제공 한 3 가지 방법 중 하나를 시도해 볼 수 있습니다. 귀하의 경우 # 2를 사용하고 addNotify에서 init을 호출하기 만하면됩니다 (super.addNotify를 호출하는 것을 잊지 마십시오) –

관련 문제