Java - 如何每秒更新一次面板
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19727449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java - How to update a panel every second
提问by Warbinator
I'm trying to create a Java GUI which displays the current time. Currently, I can make it display the current time, but only on startup. It then simply remains on that time forever. The reason is that I cannot figure out how to make it automatically load in the new current time every second. Here is my relevant code thus far:
我正在尝试创建一个显示当前时间的 Java GUI。目前,我可以让它显示当前时间,但只能在启动时显示。然后它只是永远停留在那个时间。原因是我无法弄清楚如何让它每秒在新的当前时间自动加载。到目前为止,这是我的相关代码:
// Getting the current time...
long epoch = System.currentTimeMillis() / 1000;
String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(epoch * 1000));
// Creating the panel...
JLabel lblThetime = new JLabel(date);
sl_panel.putConstraint(SpringLayout.NORTH, lblThetime, 55, SpringLayout.SOUTH, lblIBeA);
sl_panel.putConstraint(SpringLayout.WEST, lblThetime, 139, SpringLayout.WEST, panel);
lblThetime.setFont(new Font("Avenir Next", Font.PLAIN, 40));
// Adding the time to the panel
panel.add(lblThetime);
// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
removeAll();
validate();
repaint();
}
}, 1000, 1000);
I attempted to make a refresher using information from this thread, but to no avail, the window (when run) is just blank. I then tried making a different refresher using information from this thread, and created this:
我尝试使用来自该线程的信息进行复习,但无济于事,窗口(运行时)只是空白。然后我尝试使用来自该线程的信息进行不同的复习,并创建了这个:
// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
contentPane.remove(lblThetime);
contentPane.add(lblThetime);
}
}, 1000, 1000);
With contentPane
having been defined as private JPanel contentPane;
与contentPane
已经被定义为private JPanel contentPane;
Which also didn't work, however only the time itself is blank, the rest of the content in the window (One other JLabel (just some text)) remains as normal.
这也不起作用,但是只有时间本身是空白的,窗口中的其余内容(另一个 JLabel(只是一些文本))保持正常。
Without any refresher it behaves as described above, whereby it just displays the time when it started and remains on that time forever.
没有任何刷新,它的行为如上所述,因此它只显示它开始的时间并永远保持在那个时间。
I'm using Eclipse with WindowBuilder. (And I'm (probably evidently) a complete noob to Java GUI stuff xD)
我将 Eclipse 与 WindowBuilder 一起使用。(而且我(可能显然)是 Java GUI 东西的完全菜鸟 xD)
采纳答案by dic19
First of all you are using java.util.Timerinstead of javax.swing.Timer. You need use this second class when working with Swing components to ensure GUI updates are made on the Event Dispatch Thread. Also take a look to Concurrency in Swingtutorial.
首先,您使用的是java.util.Timer而不是javax.swing.Timer。在使用 Swing 组件时需要使用第二个类,以确保在Event Dispatch Thread上进行 GUI 更新。另请查看Swing教程中的并发性。
As suggested in other answers, there is no need to remove/add JLabel
each time you want to update its text. Just call JLabel.setText()method.
正如其他答案中所建议的那样,JLabel
每次要更新其文本时都无需删除/添加。只需调用JLabel.setText()方法。
If you still want remove/add the JLabel
each time, then be aware of this:
如果您仍然希望JLabel
每次都删除/添加,请注意:
From Container.add()javadoc:
来自Container.add()javadoc:
This method changes layout-related information, and therefore, invalidates the component hierarchy. If the container has already been displayed, the hierarchy must be validated thereafter in order to display the added component.
此方法更改与布局相关的信息,因此使组件层次结构无效。如果容器已被显示,则此后必须验证层次结构以显示添加的组件。
Then you'll need to call Component.revalidate()method. Like this:
然后你需要调用Component.revalidate()方法。像这样:
contentPane.remove(lblThetime);
contentPane.add(lblThetime);
contentPane.revalidate();
回答by kerberos84
Instead of removing and adding the label to the panel you should change the string of the label every second.
您应该每秒更改标签的字符串,而不是删除和添加标签到面板。
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date() );
lblThetime.setText(date);
}
}, 1000, 1000);
// Creating the panel...
JLabel lblThetime = new JLabel(date);
回答by alex2410
You can try to use Swing Timer for that task, for example:
您可以尝试将 Swing Timer 用于该任务,例如:
private static JLabel l;
public static void main(String[] args) {
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
l.setText(new Date().toString());
}
});
timer.start();
JFrame f = new JFrame();
l=new JLabel(new Date().toString());
f.getContentPane().add(l);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
That example update JLabel with new date every second
该示例每秒用新日期更新 JLabel
回答by Kili Liam
Clue 1: really search for Timer classes in Java. Did you pick the correct one?
线索 1:真正在 Java 中搜索 Timer 类。你选对了吗?
Clue 2: update the label text instead.
线索 2:改为更新标签文本。
HIH
HIH
KL
吉隆坡
回答by Warbinator
I discovered the solution!
我发现了解决方案!
I tried all the solutions given as answers here, and none which gave code fully worked, however all answers pointed me in the right direction. I found the solution to the problem on a website which I have forgotten the name of, but I used its suggestion and came up with this final solution which worked:
我尝试了此处作为答案给出的所有解决方案,但没有一个可以使代码完全正常工作,但是所有答案都为我指明了正确的方向。我在一个忘记名称的网站上找到了该问题的解决方案,但我使用了它的建议并提出了这个最终解决方案,该解决方案有效:
// New timer which works!
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(System.currentTimeMillis()));
lblThetime.setText(date);
}
};
new Timer(delay, taskPerformer).start();
Thank you to all who answered as without said answers I probably would not have been able to find this solution :D
感谢所有没有回答的人,我可能无法找到这个解决方案:D
回答by tomekch6
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
label.setText(new Date().toString());
}
}, 1000, 1000);
Isn't it simpler?
不是更简单吗?