2014-08-30 45 views
-1

我有一個關於JLabels的問題。我正試圖編寫一個帶有許多JLabel的窗口(使用JFrame設置)的應用程序。無論如何,我想知道是否有辦法讓窗口顯示,然後修改JLabels的文本。我遇到的問題是,直到課程到達課程結束時纔會顯示窗口。有什麼方法可以解決這個問題嗎?我必須使用線程嗎?如果是這樣,我該怎麼做。 謝謝, 〜萊恩如何在不使用ActionListener的情況下修改窗口中的JLabel?

例子:在你進入while循環前的構造

public class Start extends JFrame{ 
    private static final long serialVersionUID = 1L; 
    Random random = new Random(); 

    JPanel panel = new JPanel(); 
    JLabel label = new JLabel("Label"); 

    panel.add(label); 
    add(panel); 

    while(true){ 
    int rnd = random.nextInt(4); 
    label.setText("" + rnd); 
    } 

} // I want to do that, but the window won't show until the loop ends. In this case, the loop 
    // never will end. How would I do something like this if not the same exact thing? 
+0

您是否考慮過放置計時器以允許您閱讀新標籤? (隨後刷新幀) – mlwn 2014-08-30 16:40:47

+0

是的。儘管沒有使用線程,程序仍然等待計時器完成。 – Rane 2014-08-30 16:51:49

+0

閱讀http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html和http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html – 2014-08-30 16:57:19

回答

-1

呼叫setVisibile。

public class Start extends JFrame { 
    private static final long serialVersionUID = 1L; 

    public Start() { 
     Random random = new Random(); 

     JPanel panel = new JPanel(); 
     JLabel label = new JLabel("Label"); 

     panel.add(label); 
     add(panel); 

     this.setVisible(true); //IMPORTANT PART 

     while(true){ 
      int rnd = random.nextInt(4); 
      label.setText("" + rnd); 
     } 
    } 
} 
+0

它的工作。謝謝! – Rane 2014-08-30 17:22:50

+2

請參閱[*初始線程*](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)瞭解更多關於此方法不正確的原因; [*如何使用Swing定時器*](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)以獲得更好的方法。 – trashgod 2014-08-30 18:49:08

2

讓我們開始的事實,Swing不是線程安全的,所有交互和修改UI應該在事件指派線程的contentext內進行。

這也意味着您不會在事件調度線程的上下文中執行任何長時間運行或耗時的操作,因爲這將阻止它處理EventQueue上的新事件,包括重新繪製請求。

查看Concurrency in Swing瞭解更多詳情。

最簡單的解決方案是使用javax.swing.Timer。這將允許你安排這是保證要在美國東部時間範圍內引發了普通回撥,使其安全地更新UI

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class RandomLabels { 

    public static void main(String[] args) { 
     new RandomLabels(); 
    } 

    public RandomLabels() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JLabel label; 
     private Random rnd; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      label = new JLabel(); 
      add(label); 

      rnd = new Random(); 

      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        label.setText(Integer.toString(rnd.nextInt())); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 

這也意味着你可以控制Timer,啓動它,並停止它當你想/需要輕鬆。

您可以使用Thread,但管理要求會增加......您將負責管理UI更新的同步,並且必須實現功能以實際停止線程。

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.lang.reflect.InvocationTargetException; 
import java.util.Random; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class RandomLabels { 

    public static void main(String[] args) { 
     new RandomLabels(); 
    } 

    public RandomLabels() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JLabel label; 
     private Random rnd; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      label = new JLabel(); 
      add(label); 

      rnd = new Random(); 

      Thread t = new Thread(new Randomizer()); 
      t.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     public class Randomizer implements Runnable { 

      @Override 
      public void run() { 
       while (true) { 
        try { 
         EventQueue.invokeAndWait(new Runnable() { 
          @Override 
          public void run() { 
           label.setText(Integer.toString(rnd.nextInt())); 
          } 
         }); 
        } catch (InterruptedException | InvocationTargetException exp) { 
         exp.printStackTrace(); 
        } 
        try { 
         Thread.sleep(40); 
        } catch (InterruptedException ex) { 
        } 
       } 
      } 

     } 

    } 

} 

另一種解決辦法可能是使用SwingWorker(不是使用Thread更好)。這將允許您在後臺執行長時間運行/阻塞/耗時的操作,但提供了將更新自動輕鬆發送回UI的功能。

採取在How to use Swing TimersWorker Threads and SwingWorker細看了解更多詳情

最後,看看Initial Threads。您必須確保您的UI在EDT的環境中啓動/構建以及...

相關問題