我试图随机生成一个字符串,并不断更新JTextArea。我知道程序在无限循环中被卡在runTest()方法中。我试图循环显示此结果,直到用户按下停止按钮为止。有什么建议吗?谢谢
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class MyApplication extends JFrame {
private JTextArea textArea;
private JButton b;
private String toChange = "";
// Called from non-UI thread
private void runQueries() {
while (true) {
runTest();
updateProgress();
}
}
public void runTest() {
while (true) {
if (toChange.length() > 10) {
toChange = "";
}
Random rand = new Random();
toChange += rand.nextInt(10);
}
}
private void updateProgress() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(toChange);
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MyApplication app = new MyApplication();
app.setVisible(true);
}
});
}
private MyApplication() {
this.setLayout(null);
this.setResizable(false);
this.setLocation(100, 100);
this.setSize(900, 600);
final Panel controlPanel = new Panel();
controlPanel.setLayout(new BorderLayout());
controlPanel.setSize(600, 200);
controlPanel.setLocation(50, 50);
setDefaultCloseOperation(this.EXIT_ON_CLOSE);
textArea = new JTextArea("test");
textArea.setSize(100, 100);
textArea.setLocation(200, 200);
this.add(textArea);
JButton b = new JButton("Run query");
b.setSize(100, 75);
b.setLocation(100, 50);
this.add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread queryThread = new Thread() {
public void run() {
runQueries();
}
};
queryThread.start();
}
});
}
}
最佳答案
int initialDelay = 1000; // start after 1 seconds
int period = 1000; // repeat every 1 seconds
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
if (toChange.length() > 10) {
toChange = "";
}
Random rand = new Random();
toChange += rand.nextInt(10);
};
timer.scheduleAtFixedRate(task, initialDelay, period);
您将想要像我刚刚做的上述事情。否则,您只是冻结线程,因此,永远不会调用
updateProgress();
。关于这一点,为什么在
while (true)
方法中甚至需要runTest()
循环?无论如何,它始终由runQueries()
中的while true循环运行和更新,这意味着while (true)
循环似乎没有任何意义。澄清:
我说的是,您应该将runTest()和updateProgress()放在延迟的任务中,而不是一会儿真正的循环-否则,您只是通过将其他任务放在相同的线程中来阻止其他任务。
但是,更改此设置也可以解决此问题:
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int initialDelay = 100; // start after 0.1 seconds
int period = 100; // repeat every 0.1 seconds
{
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
runTest();
};
timer.scheduleAtFixedRate(task, initialDelay, period);
}
{
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
updateProgress();
};
timer.scheduleAtFixedRate(task, initialDelay, period);
}
}
});
}
和runTest()..
public void runTest() {
if (toChange.length() > 10) {
toChange = "";
}
Random rand = new Random();
toChange += rand.nextInt(10);
}
和updateProgress()。
private void updateProgress() {
textArea.append(toChange);
}
请注意,我是在SO编辑器中而不是在IDE中键入代码。抱歉,没有语法错误。