2014-08-30 43 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的环境中启动/构建以及...

相关问题