Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GUI在运行ActionEvent之前未进行可视化更新_Java_Swing_User Interface_Swingworker_Actionevent - Fatal编程技术网

Java GUI在运行ActionEvent之前未进行可视化更新

Java GUI在运行ActionEvent之前未进行可视化更新,java,swing,user-interface,swingworker,actionevent,Java,Swing,User Interface,Swingworker,Actionevent,更详细地说,我有一个GUI,它看起来像: 然后我在OK按钮上有一个动作监听器,它的启动方式如下: //OK Button Action Listener private void okButtonActionPerformed(ActionEvent e) { //Enable/Disable Buttons okButton.setEnabled(false); cancelButton.setEnabled(true); updateCheckbox.

更详细地说,我有一个GUI,它看起来像:

然后我在OK按钮上有一个动作监听器,它的启动方式如下:

//OK Button Action Listener
private void okButtonActionPerformed(ActionEvent e) {   
    //Enable/Disable Buttons
    okButton.setEnabled(false);
    cancelButton.setEnabled(true);
    updateCheckbox.setEnabled(false);
    //Move on to a series of other methods here...
从理论上讲,这应该实现:

但是,在完成所有方法和连接到OK按钮的其他事情之前,我会得到以下结果:

这显然不可能发生,因为这样做的目的是使取消按钮和OK按钮以及其他几个勾选框在程序期间不可用(图2),相反,它在半状态下冻结(图3)。有什么办法可以解决这个问题吗

//在这里继续讨论一系列其他方法


确保您没有用长时间运行的操作阻塞GUI线程(EDT)。改为使用。

您是否在处理GUI的同一线程上进行处理?您可能希望查看一个
SwingWorker
线程,以便在后台执行繁重的任务,这样您的UI才能保持响应。是的,这是因为您已使用其他方法使用EDT进行了阻止

您需要使用另一个
线程
在后台执行工作,否则GUI将被阻止

在Swing应用程序中,建议在
SwingWorker
上执行任何长时间运行的任务

请看下面的介绍

SwingWorker
将执行给定的任务,完成后可以向GUI报告。这将以非阻塞方式完成,以便在执行任务时仍然可以使用GUI


如果希望能够取消后台任务,则需要保留对
SwingWorker
的引用,以便调用
cancel
方法。在这种情况下,工作方法需要是可中断的,否则无法取消任务。

每次从GUI执行逻辑时,您都应该以以下方式使用SwingWorker:

SwingWorker myWorker= new SwingWorker<String, Void>() {
    @Override
    protected String doInBackground() throws Exception {
        //Execute your logic
        return null;
    }
};
myWorker.execute();
有了它,您可以确保您的逻辑和GUI都保持响应

编辑:


如果这更适合您的需要,您还可以使用
invokeAndWait

呃不多。
SwingWorker
中有一个非常好的框架,用于使用
publish
过程传回中间更新;你到底为什么要使用调用器呢?!我遵循的逻辑是:你能解释一下为什么你认为它不适用吗?我的意思是-这确实很容易。因为
SwingWorker
已经有了一个异步任务队列,您可以通过它将项目传递到
进程
,然后EDT将调用
发布
。您可以覆盖
publish
,并使用该项更新GUI。您的方法需要创建另一个匿名类(即<代码> Runnaby<代码>),如果您想将任何数据传递到它,则必须是“代码>最终< /代码>等。此外,您需要考虑线程安全性,因为EDT将调用<代码> Runnaby<代码>。您可以将它添加到您的解决方案中,这样有两种方法可以实现这一点。我以前从未实际使用过SwingWorker。在最基本的形式中,我是否基本上想要将所有与SwingWorker内部GUI没有直接关系的ActionListener代码包装在ActionEvent方法中?在这种情况下,Cancel将完全退出程序,而不是中断它。从各种答案听起来的方式来看,似乎可能需要对代码进行重大重组,而我不想这样做。不过,我可能把它理解错了。您是否建议使用SwingWorker包装所有与GUI无关的操作侦听器代码?是的,这是您应该做的。如果您希望在处理过程中提供GUI更新,则可以使用
publish
方法发布更新,并覆盖
process
方法。
process
方法将在EDT上运行,因此不会破坏Swing的单线程模型。我现在正在进行研究,但在逻辑上有一点问题。例如,如果我想在运行
doSomething()
方法时执行
cancelButton.setEnabled(true)
,那会是什么样子?这里的逻辑的可视化表示将帮助我最好地应用它。这正是我正在做的,我知道我做错了什么。我现在只需要试着理解如何实现另一个线程。actionListener中的所有内容(在屏幕上)都在一瞬间完成,在所有代码行执行完毕后,请确定真正的目标是什么。我很难准确理解您的意思,但本质上,我有一个长期运行的过程,需要在保持GUI可用的同时进行。基于其他答案,我应该通过
SwingWorker
使用另一个线程。我有一个长期运行的过程--->然后在这里遵循并接受其中一个答案,一堆代码示例,其中一些具有出色的描述:-)这个问题和答案就像是基于猜测和粘贴图像的疯狂短片,很好,非常好,但你会得到一个答案
SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        //To update your GUI
    }
});