2015-01-31 78 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