7

스윙, 스레딩, invokeLater(), SwingWorker 등등에 대해 많이 읽었지 만, 그저 내 머리를 맞대고있는 것처럼 보이지 않으므로 설명하기에 정말 간단한 프로그램을 만들려고 노력하고있었습니다. . 많은 예제를 살펴 보았지만 그 중 아무 것도 내가하려고하는 것을 보여주는 것 같지 않습니다. Java로 프로그래밍 한 이후 오랜 시간이 지났습니다. 2003 년 고교에서 AP 컴퓨터 과학을 택한 이래로 Java로는 아무 것도하지 못했습니다. 그래서 나와 양육하십시오.EDT 외부에서 Swing 구성 요소를 업데이트합니까?

다음은 필자가 실제로 시도한 것입니다. 단추와 레이블이 있는데 단추를 클릭하면 레이블 텍스트에 마침표를 추가하기 전에 3 초 동안 프로그램을 일시 중지하려고합니다. 3 초 동안 GUI가 정상적으로 나타나고 추가 클릭에 계속 응답하려고합니다.

import javax.swing.SwingWorker; 

public class NewJFrame extends javax.swing.JFrame 
{ 
    private javax.swing.JButton jButton1; 
    private javax.swing.JLabel jLabel1; 

    public NewJFrame() 
    { 
     initComponents(); 
    } 
    private void initComponents() 
    { 
     jButton1 = new javax.swing.JButton(); 
     jLabel1 = new javax.swing.JLabel(); 
     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     jButton1.setText("Button"); 
     jButton1.addActionListener(new java.awt.event.ActionListener() 
     { 
      public void actionPerformed(java.awt.event.ActionEvent evt) 
      { 
       jButton1ActionPerformed(evt); 
      } 
     }); 
     getContentPane().add(jButton1, java.awt.BorderLayout.CENTER); 
     jLabel1.setText("Text"); 
     getContentPane().add(jLabel1, java.awt.BorderLayout.PAGE_END); 
     pack(); 
    } 

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
    { 
     SwingWorker worker=new SwingWorker() 
     { 
      protected Object doInBackground() 
      { 
       try{Thread.sleep(3000);} 
       catch (InterruptedException ex){} 
       return null; 
      } 
     }; 
     worker.execute(); 
     jLabel1.setText(jLabel1.getText()+"."); 
    } 

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

를이 코드와 함께, 내가 버튼을 클릭하면 내가 만들고 백그라운드 스레드을 자고하고 있기 때문에, 기간이 즉시 EDT를 떠나, 나에게 의미가 레이블에 추가됩니다 : 여기에 내가 쓴거야 라벨을 즉시 업데이트 할 수 있습니다. 그래서 난이 시도 :

이 거의 EDT 버튼 레이블의 텍스트 기간을 추가하기 전에 3 초 동안 파란색으로 원인 그것이 블록을 제외하고 작동
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
{ 
    Thread thread = new Thread(); 
    try{ thread.sleep(3000);} 
    catch (InterruptedException ex){} 
    jLabel1.setText(jLabel1.getText()+"."); 
} 

.

이 일 것으로 보인다
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
{ 
    SwingWorker worker=new SwingWorker() 
    { 
     protected Object doInBackground() 
     { 
      try{Thread.sleep(3000);} 
      catch (InterruptedException ex){} 
      jLabel1.setText(jLabel1.getText()+"."); 
      return null; 
     } 
    }; 
    worker.execute(); 
} 

만이 아닌 내가 jLabel1를 호출이 나는 버튼이 정말 빠르게 클릭 한 경우가 전체 3 초 동안 누르고있는 것처럼보고 싶지 않아, 그래서 시도 .setText (...) 백그라운드 스레드 및 EDT, 따라서 따라서 "스윙 단일 스레딩 규칙"위반? 그렇다면 원하는 효과를 얻는 더 좋은 방법이 있습니까? 그렇지 않다면 이유를 설명해 주시겠습니까?

+2

+1 노력과 연구를 위해! – MadProgrammer

답변

4

당신은 정말 가까이에있어 ...

대신이 같은 것을 시도해보십시오.

SwingWorker worker=new SwingWorker() 
{ 
    protected Object doInBackground() 
    { 
     try{ 
      Thread.sleep(3000); 
     }catch (InterruptedException ex){} 
     return null; 
    } 

    // This is executed within the context of the EDT AFTER the worker has completed...  
    public void done() { 
     jLabel1.setText(jLabel1.getText()+"."); 
    } 
}; 
worker.execute(); 
당신은 또한 쉽게 할 수있는 javax.swing.Timer를 사용할 수

업데이트 EventQueue.isDispatchingThread()

의 사용을 통해 EDT에서 실행하고 있는지 확인할 수 있습니다

...

Timer timer = new Timer(3000, new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     jLabel1.setText(jLabel1.getText()+"."); 
    } 
}); 
timer.setRepeats(false); 
timer.start(); 
+0

신속하고 간결한 답변 주셔서 감사합니다! 그 done() 메소드는 내가 찾고있는 것을 정확하게 수행한다. 타이머도 꽤 멋지다. –

+0

정말 좋은 질문을 주셔서 감사합니다! – MadProgrammer

관련 문제