可以不使用定时器
Possible not to use timer
大家好,我想问一下,是否可以不在 Java netbeans 中使用计时器来在我的 JLabel 上显示我的变量 "counter" 使用 while 循环的所有值。这是我的示例代码。
int counter = 0;
while (counter < 10) {
lblDisplay.setText("Completed " + Integer.toString(counter));
try {
Thread.sleep(1000);
lblDisplay.setText("Completed " + Integer.toString(counter));
} catch (InterruptedException ex) {
Logger.getLogger(Increment.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
在使用 system.out.println 时显示了它,但在我的标签中没有显示。
是的,可以避免使用 Swing Timer 来实现这一点,但是如果您这样做了:
- 您必须确保循环和
Thread.sleep(...)
在 Swing 事件线程之外的后台线程中 运行。如果您不这样做,您将冻结事件线程,从而冻结您的 GUI 并使其变得无用。
- 然后您必须确保当您仅从后台线程进行 Swing 调用时,您会煞费苦心地将这些调用排队到 Swing 事件分派线程中。如果您不这样做,您将 运行 有导致偶尔很难调试线程错误的风险。
由于涉及的额外工作和出错的风险,您会发现仅使用 Swing 计时器 更简单、更安全。例如,您发布的代码看起来很有可能使整个 GUI/application 进入睡眠状态,因为它同时具有 while 循环和 Thread.sleep(...)
调用而不考虑线程。
例如,如果没有计时器,您的代码可能类似于(注意:代码未编译或测试):
new Thread(new Runnable() {
public void run() {
int counter = 0;
while (counter < 10) {
lblDisplay.setText("Completed " + Integer.toString(counter));
try {
Thread.sleep(1000);
final int finalCounter = counter;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
lblDisplay.setText("Completed " + finalCounter);
}
});
} catch (InterruptedException ex) {
Logger.getLogger(Increment.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
}
}).start();
这比我喜欢的要复杂一些,而 Swing Timer 可能看起来像:
int delay = 1000;
new Timer(delay, new ActionListener() {
private int count = 0;
@Override
public void actionPerformed(ActionEvent e) {
if (count < 10) {
lblDisplay.setText("Completed " + counter);
} else {
((Timer) e.getSource()).stop(); // stop the Timer
}
counter++;
}
}).start();
比之前的更简单、更安全。
大家好,我想问一下,是否可以不在 Java netbeans 中使用计时器来在我的 JLabel 上显示我的变量 "counter" 使用 while 循环的所有值。这是我的示例代码。
int counter = 0;
while (counter < 10) {
lblDisplay.setText("Completed " + Integer.toString(counter));
try {
Thread.sleep(1000);
lblDisplay.setText("Completed " + Integer.toString(counter));
} catch (InterruptedException ex) {
Logger.getLogger(Increment.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
在使用 system.out.println 时显示了它,但在我的标签中没有显示。
是的,可以避免使用 Swing Timer 来实现这一点,但是如果您这样做了:
- 您必须确保循环和
Thread.sleep(...)
在 Swing 事件线程之外的后台线程中 运行。如果您不这样做,您将冻结事件线程,从而冻结您的 GUI 并使其变得无用。 - 然后您必须确保当您仅从后台线程进行 Swing 调用时,您会煞费苦心地将这些调用排队到 Swing 事件分派线程中。如果您不这样做,您将 运行 有导致偶尔很难调试线程错误的风险。
由于涉及的额外工作和出错的风险,您会发现仅使用 Swing 计时器 更简单、更安全。例如,您发布的代码看起来很有可能使整个 GUI/application 进入睡眠状态,因为它同时具有 while 循环和 Thread.sleep(...)
调用而不考虑线程。
例如,如果没有计时器,您的代码可能类似于(注意:代码未编译或测试):
new Thread(new Runnable() {
public void run() {
int counter = 0;
while (counter < 10) {
lblDisplay.setText("Completed " + Integer.toString(counter));
try {
Thread.sleep(1000);
final int finalCounter = counter;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
lblDisplay.setText("Completed " + finalCounter);
}
});
} catch (InterruptedException ex) {
Logger.getLogger(Increment.class.getName()).log(Level.SEVERE, null, ex);
}
counter++;
}
}
}).start();
这比我喜欢的要复杂一些,而 Swing Timer 可能看起来像:
int delay = 1000;
new Timer(delay, new ActionListener() {
private int count = 0;
@Override
public void actionPerformed(ActionEvent e) {
if (count < 10) {
lblDisplay.setText("Completed " + counter);
} else {
((Timer) e.getSource()).stop(); // stop the Timer
}
counter++;
}
}).start();
比之前的更简单、更安全。