我正在尝试使用尽可能少的资源创建一个时钟,并且只依赖于我(有限的)Java知识。然而,我来到了路障。我写的时钟工作,除了被替换的jlabel中的文本,它重叠自己。我试过通过清除timeStamp的值来解决这个问题,但它似乎没有用。
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();
}
}
}
答案 0 :(得分: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 :(得分:0)
您应该使用SwingWorker来更新时钟。目前,您正在事件调度线程上执行此操作,从而干扰UI呈现。
除此之外,您应该重复使用标签,而不是为每个时间戳创建一个新标签。目前,您正在将标签堆叠在一起,因为{{1}}只会添加新标签,而不会删除旧标签。
答案 2 :(得分:0)
为什么要在循环的每次迭代中创建一个新的JLabel? 不要那样做。 只需在Clock的构造函数中创建一个标签。
此外,更改标签的文本应该在事件线程上完成,而不是主线程。
答案 3 :(得分:0)
虽然您编写的代码"工作",但您缺少一些东西来制作稳定的Swing GUI。
您必须始终使用SwingUtilities invokelater方法启动Swing应用程序。这将Swing组件的创建和执行放在Event Dispatch thread (EDT)。
我将GUI的创建与GUI的执行分开。关注点分离使每个部分的编码更容易。
在Timer Runnable中,我再次使用SwingUtilities invokeLater方法确保在EDT上更新带有时间的JTextField。
我退出前停止线程。通常,您应该停止任何启动的线程,而不是依靠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;
}
}
}