2017-04-18 10 views
-2

버튼을 클릭 할 때 긴 작업을 실행하고 있습니다. 작업이 시작되었다는 메시지를 보여주고 싶습니다. swingworker를 사용하면 (자), JOptionPane는 메세지 박스를 작성 합니다만, 그 내용은 태스크가 완료 할 때까지 아무것도 공백입니다. 내 EDT가 차단되고 GUI가 작업이 완료되지 않으면 업데이트되지 않는다고 생각합니다.SwingWorker thread-doInBackground()에서 메시지 표시 (Joptionpane)

public class myClass { 
private JFrame frame; 
private display1 dis; 

class display1 extends SwingWorker<Void,Void> 
{ 
    public Void doInBackground() throws InterruptedException 
    { 
    JOptionPane.showMessageDialog(null, 
       "Task Started"); 
     return null; 
    } 
} 
public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      try { 
       myClass window = new myClass(); 
       window.frame.setVisible(true); 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 


public myClass() { 
    initialize(); 
} 


private void initialize() { 
    frame = new JFrame(); 
    frame.setBounds(100, 100, 450, 300); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().setLayout(null); 

    JButton btnNewButton = new JButton("New button"); 
    btnNewButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      dis=new display1(); 
      dis.execute(); 

     System.out.println("starting"); 
      for(int i=0;i<10000;i++) 
       System.out.println("this is " +i);// Long task 


     System.out.println("Finished"); 
     } 
    }); 
    btnNewButton.setBounds(166, 228, 89, 23); 
    frame.getContentPane().add(btnNewButton); 

} 
} 
+0

'display1'은 무엇입니까? EDT 컨텍스트에서 UI가 비어있는 이유를 설명하는 긴 작업을 실행 중입니다. – MadProgrammer

+0

display1은 SwingWorker를 구현하는 클래스의 이름입니다. 나는 그것이 작동하지 않는 이유를 안다. 내가 묻는 것은 작업이 시작되고 동시에 작업을 실행할 수있는 대화 상자를 표시하는 방법입니다 (이 작업에는 특정 GUI 구성 요소가 포함되어 있습니다) – sam

+2

[실행 가능한 예제] (https://stackoverflow.com/help/mcve) 제공을 고려하십시오.) 귀하의 문제를 보여줍니다. 이것은 코드 덤프가 아니지만 수행중인 문제의 예를 보여줍니다. 이렇게하면 더 적은 혼란과 더 나은 응답을 얻을 수 있습니다. – MadProgrammer

답변

2

때문에 SwingWorker 이벤트 발송 쓰레드상에서 어떤 PropertyChangeListener 통지 단순히 -이 : 어떤이 표시하는 방법 (swingutils.invokelater를 내가 작업의 시작 디스플레이를 필요로 사용할 수 없습니다) 샘플 코드가 있습니까 바운드 속성 state 들어요. 가능한 valuesDONE, PENDINGSTARTED을 포함합니다. 이 TaskListener은 콘솔에 쓰는 예제이지만, 구현시 레이블 propertyChange()을 업데이트하는 것이 안전합니다. 모달 대화 상자는 허용되지만 불필요합니다.

0

invokeLater(Runnable);에서 실행되는 모든 것은 Event Dispatch Thread "gui-thread"로 전송됩니다. 귀하의 방법 initialize()은 괜찮습니다. EDT에서 실행되었지만 UI와 관련된 모든 작업이 EDT에서 처리되고 있음을 명심해야합니다. 따라서 사용자가 버튼을 클릭하면 EDT에서 ActionListener 코드가 실행됩니다. 다른 UI 이벤트 처리에서 EDT 블록에서 실행되는 장기 실행 태스크. 따라서 스레드 e를 분리하기 위해 "긴 작업"을 이동해야합니다. 지. SwingWorker.

button.addActionListener(new ActionListener() { 
    @Override public void actionPerformed(ActionEvent arg0) { 
     // we are are in EDT = dialog will be displayed without any problems 
     JOptionPane.showMessageDialog(null, "About to start"); 
     // executes SwingWorker's doInBackground task 
     new BackgroundTask().execute(); 
    } 
}); 

다음 코드는 SwingWorker와 함께 작동하는 방법을 보여줍니다 : 당신이 작업을 실행하기 전에 뭔가를 표시해야하는 경우

단지 (주어진 코드가 EDT에서 실행되어 있는지 확인) swingWorker.execute();를 호출하기 전에 넣어

class BackgroundTask extends SwingWorker< 
     String/*background task's result type*/, 
     Integer/*inter-step's result type*/ 
     > 
{ 
    /** 
    * This method is designed to perform long running task in background 
    * i. e. in "non-EDT" thread = in SwingWorker thread. 
    * 
    * After method is completed, {@link #done()} is called, which is 
    * executed in "EDT" (gui-thread). 
    * 
    * Note, you can {@link #publish(Integer)} progress to {@link #process(List<V> chunks)} 
    * which is executed in "EDT" (gui-thread). 
    * 
    * You can also use {@link SwingUtilities#invokeLater(Runnable)} 
    * to send "message" to "EDT" which contains code to be executed 
    * This is similar to {@link #publish(Object)} except not-processed-yet 
    * messages are not collected and processed all at once like in 
    * {@link #publish(Object)} case. 
    */ 
    @Override 
    protected String doInBackground() throws Exception { 
     // or you can put JOptionPane.showMessageDialog(null, "About to start"); 
     // in ActionListener before calling swingWorker.execute(); 
     SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null, "About to start")); 
     // System.out.println("starting"); 
     for(int i = 0; i < 10000; i++) { 
      // System.out.println(i); 
      publish(i); 
     } 
     // result of the background task 
     return "Task completed"; 
    } 

    /** 
    * Method is executed in "EDT" after calling {@link #publish(Integer)}. 
    * 
    * This is the right place to update GUI about inter-step result. 
    * 
    * Note, this method is not executed immediately after calling {@link #publish(Integer)}, 
    * since EDT can process at this time sime other GUI tasks. 
    * Therefore, list contains all inter-step results send from SwingWorker 
    * to EDT which were not processed yet. 
    */ 
    @Override 
    protected void process(List<Integer> chunks) { 
     for (int number : chunks) { 
      textArea.append(number + "\n"); 
     } 
    } 

    /** 
    * Method is executed in "EDT" after {@link #doInBackground()} is finished. 
    * This is the right place to update GUI about final result. 
    */ 
    @Override 
    protected void done() { 
     String result = get(); // returns result of the doInBackground(); 
     JOptionPane.showMessageDialog(null, result); 
    } 
} 
+0

* "작업이 시작되었다는 메시지를 표시하고 싶습니다."* – MadProgrammer

+0

@MadProgrammer가 작성하는 동안 잊어 버리 겠어. 내 대답을 업데이트하십시오. – matoni

+0

[예제] (http://stackoverflow.com/q/35154352/230513)에 대한 안전한 지점에 도달하지 않는 바쁜 루프에도주의하십시오. – trashgod