我正在尝试编写简单的GUI倒计时。我在网上发现了一些代码,但它对我来说已经过于花哨了。我想尽量保持简单。所以,我只想要一个窗口说“你剩下10秒钟”。秒数应该每秒从10减少到0.我写了一个代码。而且我认为我接近工作解决方案。但我仍然遗漏了一些东西。你能请求帮助我找出问题所在吗?这是我的代码:
import javax.swing.*;
public class Countdown {
static JLabel label;
// Method which defines the appearance of the window.
private static void showGUI() {
JFrame frame = new JFrame("Simple Countdown");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel("Some Text");
frame.add(label);
frame.pack();
frame.setVisible(true);
}
// Define a new thread in which the countdown is counting down.
static Thread counter = new Thread() {
public void run() {
for (int i=10; i>0; i=i-1) {
updateGUI(i,label);
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
}
};
// A method which updates GUI (sets a new value of JLabel).
private static void updateGUI(final int i, final JLabel label) {
SwingUtilities.invokeLater(new Runnable(i,label) {
public Runnable(int i, JLabel label) {
this.i = i;
this.label = label;
}
public void run() {
label.setText("You have " + i + " seconds.");
}
});
}
// The main method (entry point).
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
showGUI();
//counter.start();
}
});
//counter.start();
}
}
我对这段代码有几个具体的问题:
我应该在哪里放置counter.start();
? (在我的代码中,我把它放在2个位置。哪一个是正确的?)
为什么编译器会抱怨Runnable的构造函数?它说我有一个无效的方法声明,我需要指定返回的类型。
增加: 我提出了建议的更正。然后我执行代码并得到:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Worker.run(Worker.java:12)
在第12行的Worker.java中,我有:label.setText("You have " + i + " seconds.");
。
答案 0 :(得分:2)
在runnable中调用counter.start()
:
// The main method (entry point).
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
showGUI();
counter.start();
}
});
}
你真的想要一个特定的调用顺序,如果你将它放在线程之外,那么计数器将在GUI存在之前启动,它将失败。
关于第二个问题:
// A method which updates GUI (sets a new value of JLabel).
private static void updateGUI(final int i, final JLabel label) {
SwingUtilities.invokeLater(new Worker(i, label));
}
这是工人:
import javax.swing.JLabel;
public class Worker implements Runnable{
private int i;
private JLabel label;
public Worker(int i, JLabel label) {
this.i = i;
this.label = label;
}
public void run() {
label.setText("You have " + i + " seconds.");
}
}
现在你的主力:
// The main method (entry point).
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Countdown.showGUI();
counter.start();
}
});
}
<强>更新强>
或者,如果您仍想使用匿名模式,那么:
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class Countdown {
static JLabel label;
// Method which defines the appearance of the window.
public static void showGUI() {
JFrame frame = new JFrame("Simple Countdown");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel("Some Text");
frame.add(label);
frame.pack();
frame.setVisible(true);
}
// Define a new thread in which the countdown is counting down.
public static Thread counter = new Thread() {
public void run() {
for (int i=10; i>0; i=i-1) {
updateGUI(i,label);
try {Thread.sleep(1000);} catch(InterruptedException e) {};
}
}
};
// A method which updates GUI (sets a new value of JLabel).
private static void updateGUI(final int i, final JLabel label) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
label.setText("You have " + i + " seconds.");
}
}
);
}
}
答案 1 :(得分:1)
答案中的匿名示例完美无缺。
对于第一个答案,计数器工作,但没有显示GUI,并且每秒出现以下异常
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.aramco.ecc.licenseoptimizer.gui.Worker.run(Worker.java:23)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)