2015-06-23 56 views
1

我正在嘗試使用盡可能少的資源來製作時鐘,並僅依賴於我對Java的(有限的)瞭解。然而,我已經來到了路障。我寫作的時鐘除了被替換的jlabel中的文本之外,它與自身重疊。我試圖通過清除timeStamp的值來解決這個問題,但它似乎並沒有工作。JLabel在GUI中重疊文本

public class Clock extends JFrame{ 
public static void main (String args[]) {  

    Clock gui = new Clock(); 
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    gui.setSize(50,50); 
    gui.setVisible(true); 
    gui.setTitle("Clock"); 

    int a = 1; 
    while (a == 1){   
     String timeStamp = new SimpleDateFormat("hh:mm:ss a").format(Calendar.getInstance().getTime());   
     JLabel label; 
     label = new JLabel(); 
     label.setText(String.valueOf(timeStamp)); 
     timeStamp = ""; 
     gui.add(label); 
     label.revalidate(); 
    } 
      } 
} 

回答

1

你不應該創建一個新的JLabel每次迭代。

JLabel label = new JLabel(); 
gui.add(label); 
while (a == 1){   
    String timeStamp = new SimpleDateFormat("hh:mm:ss a").format(Calendar.getInstance().getTime()); 
    label.setText(String.valueOf(timeStamp)); 
    timeStamp = ""; 
    label.revalidate(); 
} 
+1

這樣做,謝謝!可用時將選擇作爲答案 – Dave

0

您應該使用SwingWorker更新時鐘。目前,您正在使用事件分派線程執行此操作,從而干擾UI呈現。

除此之外,您應該重複使用標籤,而不是爲每個時間戳創建一個新標籤。目前,您將標籤堆疊在一起,因爲gui.add()只會添加新標籤,而不會刪除舊標籤。

0

爲什麼在循環的每次迭代中創建一個新的JLabel? 不要這樣做。 只需在Clock的構造函數中創建一個標籤。

此外,更改標籤的文本應該在事件線程上完成,而不是在主線程上完成。

0

雖然您編寫的代碼「有用」,但您錯過了一些製作穩定Swing GUI的方法。

  1. 您必須始終使用SwingUtilities invokelater方法啓動Swing應用程序。這會將Swing組件的創建和執行置於Event Dispatch thread (EDT)上。

  2. 我將GUI的創建從GUI的執行中分離出來。分離關注點使得編碼每個部分變得更容易。

  3. 在Timer Runnable中,我再次使用SwingUtilities invokeLater方法來確保在EDT上發生帶有時間的JTextField更新。

  4. 我退出前停止線程。通常,您應該停止啓動任何線程,而不要依賴JVM來爲您清理。

這是時鐘。

​​

而這裏的代碼。

package com.ggl.testing; 

import java.awt.Color; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 

public class SimpleClock implements Runnable { 

    private JFrame frame; 

    private JPanel panel; 

    private JTextField clockDisplay; 

    private Timer timer; 

    @Override 
    public void run() { 
     frame = new JFrame("Clock"); 
     frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 
     frame.addWindowListener(new WindowAdapter() { 
      @Override 
      public void windowClosing(WindowEvent event) { 
       exitProcedure(); 
      } 
     }); 

     panel = new JPanel(); 
     panel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 6)); 

     clockDisplay = new JTextField(12); 
     clockDisplay.setEditable(false); 
     clockDisplay.setHorizontalAlignment(JTextField.CENTER); 

     panel.add(clockDisplay); 

     frame.add(panel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 

     timer = new Timer(this); 
     new Thread(timer).start(); 
    } 

    public void exitProcedure() { 
     timer.setRunning(false); 
     frame.dispose(); 
     System.exit(0); 
    } 

    public void setText(String text) { 
     clockDisplay.setText(text); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Clock()); 
    } 

    public class Timer implements Runnable { 

     private volatile boolean running; 

     private SimpleClock clock; 

     private SimpleDateFormat timeFormat; 

     public Timer(SimpleClock clock) { 
      this.clock = clock; 
      this.running = true; 
      this.timeFormat = new SimpleDateFormat("h:mm:ss a"); 
     } 

     @Override 
     public void run() { 
      while (running) { 
       displayTime(); 
       sleep(); 
      } 

     } 

     public void displayTime() { 
      final Calendar calendar = Calendar.getInstance(); 
      Date date = calendar.getTime(); 
      final String s = timeFormat.format(date); 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        clock.setText(s); 
       } 
      }); 
     } 

     public void sleep() { 
      try { 
       Thread.sleep(200L); 
      } catch (InterruptedException e) { 
      } 
     } 

     public synchronized void setRunning(boolean running) { 
      this.running = running; 
     } 

    } 

}