好吧,我现在已经处理了一段代码,差不多2天了,无法解决问题。
渴望行为
以下代码应该以aprox的间隙逐个显示10个字符串(下一个替换前一个字符串)。 200毫秒。
Q1 Q2 Q3 ......等到q10
当用户按下ENTER键时,此显示顺序开始。
反思行为
屏幕等待aprox。按下后2秒,然后显示q10。
更多信息
stringText
在执行期间(我通过写入控制台找到)更改了值,但屏幕上没有更新(JFrame)。displayQuestion(int number)
有一些不必要的行。我把它们都放了,因为我不确定它会起作用。实际上,没有任何效果!代码
package sush4;
import java.util.Date;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Sush4 {
// Timer control variables
static long holdTimeWord = 200L;
static long elapsedTime = 0L;
// Counter for Strings displayed
static int i = 0;
// Strings in use
static String[] questionStack = {"q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10"};
// UI: String display variables
static JLabel stringText;
static JFrame mainWindow;
// Key binding action object
private static Action userKeyCommand;
/// Display the question
private static void displayQuestion(int number) {
mainWindow.remove(stringText);
stringText.setText(questionStack[number]);
mainWindow.add(stringText);
mainWindow.setVisible(true);
mainWindow.revalidate();
mainWindow.repaint();
}
private static void q120(){
//// Initiate the text
for(i = 0; i < questionStack.length; i++) {
displayQuestion(i);
//// And wait for Word hold time
long startTime = System.currentTimeMillis();
elapsedTime = 0L;
// Now wait for event to happen
while ( (elapsedTime < holdTimeWord) ) {
elapsedTime = (new Date()).getTime() - startTime;
}
}
}
Sush4() {
//// Create the Window
mainWindow = new JFrame("Sush");
mainWindow.setSize(700, 500);
mainWindow.setLayout(new FlowLayout());
//// And add key bindings for user events
userKeyCommand = new UserKeyCommand();
JRootPane rootPane = mainWindow.getRootPane();
rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ENTER"), "doEnterAction");
rootPane.getActionMap().put("doEnterAction", userKeyCommand);
// Terminate the program when the user closes the application.
mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainWindow.setResizable(false);
//// Add the text label
stringText = new JLabel("Random Text");
mainWindow.add(stringText);
//// Finally, display the frame.
mainWindow.setVisible(true);
}
static class UserKeyCommand extends AbstractAction {
public void actionPerformed( ActionEvent tf ) {
q120();
}
}
public static void main(String[] args) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Sush4();
}
});
}
}
答案 0 :(得分:3)
计时器是通过一个循环 - 这可能不是大多数人喜欢的,但暂时忘记它。
实际上,我们不能忘记这个循环,因为这是造成麻烦的原因。请参阅,单击按钮时调用q120()
方法:
static class UserKeyCommand extends AbstractAction {
@Override // don't forget @Override annotation
public void actionPerformed( ActionEvent tf ) {
q120();
}
}
这意味着此代码在Event Dispatch Thread (EDT)的上下文中执行。这是一个单一且特殊的线程,其中必须创建/更新Swing组件并且必须执行事件处理(即:动作事件)。如果我们在此线程中有一个循环等待某些条件继续,我们将阻止EDT并且GUI无法重新绘制自己,直到线程被解锁。
对于重复性任务(例如问题中的任务),请考虑使用Swing Timer。对于具有中期结果的繁重任务,请考虑使用SwingWorker代替。