2015-01-31 57 views
0

我起草了下面的应用程序,以循环访问字符串数组(我是一个初学者)。目标是使用JLabel在JFrame上显示数字1到5;每秒更换一次。JFrame;首先显示for循环的数组元素[1],而不是[0]

当JFrame在屏幕上弹出时,奇怪地显示数组“1”处的数字“2”。这与我的期望相反,我无法弄清楚为什么。

我被初始化为1;存储在“temp”中;然后将其添加到JLabel中,最后添加到JFrame中。使用这种方法会有延迟吗?即JLabel更新的时间; for循环已经推进了?或者,我了解Java.swing有线程问题...?

您的帮助将不胜感激。

Ĵ

package testApplication; 

import javax.swing.JFrame; 
import javax.swing.JLabel; 

public class Count { 

    public static void main (String args[]){ 

     String[] numbers = {"one","two","three","four","five"}; 
     JLabel numToDisplay = new JLabel(""); 
     String temp; 

     //Initiate JFrame 
     JFrame frame = new JFrame("Counting Application"); 
     frame.setSize(275,100); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 

     for (int i=0; i < numbers.length; i++){ 
      temp = numbers[i]; 
      numToDisplay.setText(temp); 
      frame.add(numToDisplay); 
      try { 
       Thread.sleep(1000); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

    } 
} 
+0

您阻止事件调度线程 - 使用Swing的定时器来代替 – MadProgrammer 2015-01-31 22:47:45

回答

3

不要使用了Thread.sleep而是使用一个Swing计时器,以免把你的GUI睡觉。

例如,

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 
import javax.swing.Timer; 

public class Count { 
    private static int index = 0; 

    public static void main(String args[]) { 

     final String[] numbers = { "one", "two", "three", "four", "five" }; 
     final JLabel numToDisplay = new JLabel("", SwingConstants.CENTER); 
     String temp; 

     // Initiate JFrame 
     JFrame frame = new JFrame("Counting Application"); 
     frame.setSize(275, 100); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(numToDisplay); 
     numToDisplay.setText(numbers[index]); 
     frame.setVisible(true); 
     int delay = 1000; 
     new Timer(delay, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      index++; 
      if (index >= numbers.length) { 
       ((Timer) e.getSource()).stop(); 
      } else { 
       numToDisplay.setText(numbers[index]); 
      } 
     } 
     }).start(); 

    } 
} 

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class Count2 extends JPanel { 
    private static final String[] NUMBERS = { "one", "two", "three", "four", "five" }; 
    private static final int PREF_W = 300; 
    private static final int PREF_H = 100; 
    private static final int TIMER_DELAY = 1000; 
    private JLabel numToDisplay = new JLabel("", SwingConstants.CENTER); 
    private int index = 0; 

    public Count2() { 
     numToDisplay.setFont(numToDisplay.getFont().deriveFont(Font.BOLD, 60f)); 
     setLayout(new BorderLayout()); 
     numToDisplay.setText(NUMBERS[index]); 
     add(numToDisplay); 
     new Timer(TIMER_DELAY, new TimerListener()).start(); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     Dimension superSize = super.getPreferredSize(); 
     if (isPreferredSizeSet()) { 
     return superSize; 
     } 
     int w = Math.max(PREF_W, superSize.width); 
     int h = Math.max(PREF_H, superSize.height); 
     return new Dimension(w, h); 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     index++; 
     if (index >= NUMBERS.length) { 
      ((Timer) e.getSource()).stop(); 
     } else { 
      numToDisplay.setText(NUMBERS[index]); 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     Count2 mainPanel = new Count2(); 

     JFrame frame = new JFrame("Count2"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

可以切换添加/调用setVisible语句,但它是可能的setText无论如何将使容器无效 – MadProgrammer 2015-01-31 22:49:38

+0

1+,使用定时器。但不确定问题在于让GUI进入睡眠状态,因为代码没有在Event Dispatch Thread上执行。该代码对我来说在Windows 7上使用JDK7的效果很好,所以它在其他平台上必须是某种线程问题。 @jake,阅读[并发在Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html)以更好地理解这些评论。 – camickr 2015-01-31 22:56:22