Swing调用EANDWAIT
我正在学习Swing并创建了一个示例GUI。我正试图以准确的顺序实现以下目标Swing调用EANDWAIT,swing,events,user-interface,Swing,Events,User Interface,我正在学习Swing并创建了一个示例GUI。我正试图以准确的顺序实现以下目标 用户在某些文本字段中输入文本 用户单击“启动”按钮 将禁用“启动”按钮。 后台线程生成并处理文本字段中的文本 背景线结束 再次启用“启动”按钮。 我试图使用invokeandwait,如下所示,但我得到“无法从事件调度程序线程调用invokeandwait”。我的主要方法在同一个.class文件中,我不太确定“事件调度程序线程”到底是什么。对于这样的事情,最好的方法是什么?我是否需要在我的工作线程中设置某种警报以路由回
private void launchButtonActionPerformed(java.awt.event.ActionEvent evt) {
launchButton.setEnabled(false);
try {
java.awt.EventQueue.invokeAndWait(new MyTestThread());
} catch (Exception e) {
}
launchButton.setEnabled(true);
}
工作线程
public class MyTestThread extends Thread {
private int i = 0;
public void run() {
while (i < 5) {
try {
System.out.println(i++);
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class WorkerThread extends SwingWorker<Integer[], Void> {
@Override
public Integer[] doInBackground() {
System.out.println("Doing in background");
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
System.out.println("Doing in background" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
public void done() {
System.out.println("Swingworker is Done");
}
}
事件分派线程(EDT)是唯一允许访问Swing类和(几乎所有)方法的线程。GUI的所有初始化和事件都由EDT执行。要在EDT中执行某些操作,必须使用SwingUtilities.invokeLater
或invokeAndWait
(这相当于EventQueue.invokexx
)。这就是为什么所有Swing程序都以SwingUtilities.invokeLater()开头的主要原因:在EDT中执行GUI初始化
当EDT繁忙时,UI冻结,这就是为什么后台线程很有用。当您需要独立于UI进行大量工作(计算、I/O、传输等)时,您必须使用“工作线程”
有关Swing中线程的更多信息,请参见本教程:
现在,您试图完成的是正确的,但您使用的工具却不是
您需要知道两件事:如何处理事件(如按钮按下)和如何创建后台线程
有关第一个示例,请参见本教程:
您只需将ActionListener
添加到按钮,每当按钮抛出事件时,将在EDT中执行侦听器的actionPerformed
方法
最简单的例子:
JButton button = new JButton("Test button");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The button was pressed.");
}
}
event
变量包含有用的信息,例如event.getSource()返回抛出事件的对象,在本例中为按钮
现在,当按下按钮时,您要做的是创建一个工作线程。工作线程是使用SwingWorker类创建的,正如您在并发教程中看到的那样。在那里,您可以定义将在后台线程中执行的一段代码(在doInBackground()
方法中)和将在后台工作完成后在EDT中执行的一段代码(在done()
方法中)
所以你想做这样的事情:
private static JButton _button;
//...
_button = new JButton("Test button");
_button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The button was pressed.");
_button.setEnabled(false);
SwingWorker worker = new SwingWorker()
{
@Override
protected Object doInBackground() throws Exception
{
//do something useful in the background thread
return null;
}
@Override
protected void done()
{
_button.setEnabled(true);
}
}
worker.execute();
}
}
关于这件事有很多信息。阅读这些类的Java参考资料,阅读官方教程并在SO中搜索。关于SwingWorkers的另一个很好的教程是:不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用Thread.sleep(n)
为长时间运行的任务实现SwingWorker
。有关更多详细信息,请参阅。感谢您的详细回复!很抱歉我迟了回复,自从我上一次发帖后,有一些事情发生了。。。解决方案已附加到我原来的帖子中
private static JButton _button;
//...
_button = new JButton("Test button");
_button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The button was pressed.");
_button.setEnabled(false);
SwingWorker worker = new SwingWorker()
{
@Override
protected Object doInBackground() throws Exception
{
//do something useful in the background thread
return null;
}
@Override
protected void done()
{
_button.setEnabled(true);
}
}
worker.execute();
}
}