7

Swing, threading, invokeLater(), SwingWorker, vb. Hakkında çok şey okudum, ancak kafamı her tarafa gezdiremiyorum, bu yüzden göstermek için gerçekten basit bir program yaratmaya çalışıyordum. . Çok fazla örnek gördüm, ama hiçbiri yapmaya çalıştığım şeyi göstermiyor. Java'da programladığımdan bu yana uzun bir zaman geçti (2003 yılında AP Bilgisayar Bilimine girdiğimden beri Java'da hiçbir şey yapmadım), bu yüzden lütfen benimle çıplak ol.EDT dışındaki Swing bileşenini güncelliyor muyum?

İşte benim örneğimde yapmaya çalıştığım şey. Düğmem ve etiketim var ve düğmeyi tıkladığımda, programın etiketine bir süre eklemeden önce programın 3 saniye duraklamasını istiyorum. Bu 3 saniye boyunca, GUI'nin normal görünmesini ve ek tıklamalara yanıt vermeye devam etmesini istiyorum.

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); } 
     }); 
    } 
} 

bu kodla, ben butonuna tıklayın eğer oluşturarak ve bir arka plan iş parçacığı uyuyorum çünkü dönem hemen EDT bırakarak, bana mantıklı etiket, eklenir: Burada yazdıklarımı var Etiketi hemen güncellemek için kullanılabilir. Yani bu çalıştı:

Bu neredeyse EDT düğme etiketin metnine dönemini eklemeden önce üç saniye maviye dönüşür neden o blokları dışında çalışır
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) 
{ 
    Thread thread = new Thread(); 
    try{ thread.sleep(3000);} 
    catch (InterruptedException ex){} 
    jLabel1.setText(jLabel1.getText()+"."); 
} 

.

Bu işe görünmektedir
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(); 
} 

ama değil ben jLabel1 çağırarak: Bu ben düğmesi gerçekten sadece hızlı bir şekilde tıklandığında bu bütün üç saniye boyunca basılı uğramış gibi görünmek istemiyorum, bu yüzden denedim .setText (...) EDT değil arka plan iş parçacığından ve bu nedenle "Swing Tek Threading Kuralı?" Eğer öyleyse, istenen etkiyi elde etmek için daha iyi bir yol var mı? Eğer değilse, nedenini açıklayabilir misiniz?

Gerçekten yakınsın
+2

+1! – MadProgrammer

cevap

4

...

yerine böyle bir şey deneyin.

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(); 
Sen de daha kolay olabilecek bir javax.swing.Timer kullanabilirsiniz

Güncelleme EventQueue.isDispatchingThread()

kullanımı yoluyla EDT çalıştırıyorsanız olmadığını kontrol edebilirsiniz

...

Çaba ve araştırma için
Timer timer = new Timer(3000, new ActionListener() { 
    public void actionPerformed(ActionEvent evt) { 
     jLabel1.setText(jLabel1.getText()+"."); 
    } 
}); 
timer.setRepeats(false); 
timer.start(); 
+0

Hızlı ve özlü cevaplar için teşekkürler! Bu done() yöntemi tam olarak aradığım şeyi yapar. Zamanlayıcı da oldukça şık. –

+0

Gerçekten iyi ve düşünülmüş bir soru sorduğunuz için teşekkür ederiz! – MadProgrammer