除非导致方法挂起,否则JLabel不会更新

And*_*ndy 1 java concurrency swing text jlabel

首先,道歉但是要为此重建一个SSCCE真的很难,虽然我认为我可以很好地解释这个情况并提出我的问题,

我的情况是这样的:我有一个JLabel作为一个状态指示器(例如,它将显示"正在加载......"或"就绪"),我调用该setText方法MouseAdapter之前调用另一个方法来执行实际操作.但是,JLabel文本永远不会更改,除非我执行类似调用的操作,JOptionPane.showMessageDialog()在这种情况下文本会更新.

那么,有没有人有任何建议可以解决这种情况,而不会像显示一个消息框(什么是)没有任何理由?

提前致谢

Una*_*ivi 6

确保不在EDT(事件调度线程)上运行任务("正在加载..."程序); 如果这样做,您的GUI将不会更新.

您必须在单独的线程上运行您的应用程序代码(除非它非常快,比如说不到100毫秒,没有网络访问,没有数据库访问等).SwingWorker为了这个目的,(参见javadocs)类可能会派上用场.

EDT(例如用户界面侦听器中的代码块)应该只包含用于更新GUI,在Swing组件上运行等的代码.其他所有内容都应该在自己的Runnable对象上运行.

-

编辑:回应安迪的评论.这是一个原始示例(动态编写,可能有拼写错误,可能不会按原样运行)如何使用SwingWorker该类

把它放在你的鼠标监听器事件或任何使你的任务开始的事情中

//--- code up to this point runs on the EDT
SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>()
{

    @Override
    protected Boolean doInBackground()//This is called when you .execute() the SwingWorker instance
    {//Runs on its own thread, thus not "freezing" the interface
        //let's assume that doMyLongComputation() returns true if OK, false if not OK.
        //(I used Boolean, but doInBackground can return whatever you need, an int, a
        //string, whatever)
        if(doMyLongComputation())
        {
            doSomeExtraStuff();
            return true;
        }
        else
        {
            doSomeExtraAlternativeStuff();
            return false;
        }
    }

    @Override
    protected void done()//this is called after doInBackground() has finished
    {//Runs on the EDT
        //Update your swing components here
        if(this.get())//here we take the return value from doInBackground()
            yourLabel.setText("Done loading!");
        else
            yourLabel.setText("Nuclear meltdown in 1 minute...");
        //progressBar.setIndeterminate(false);//decomment if you need it
        //progressBar.setVisible(false);//decomment if you need it
        myButton.setEnabled(true);
    }
};
//---code under this point runs on the EDT
yourLabel.setText("Loading...");
//progressBar.setIndeterminate(true);//decomment if you need it
//progressBar.setVisible(true);//decomment if you need it
myButton.setEnabled(false);//Prevent the user from clicking again before task is finished
sw.execute();
//---Anything you write under here runs on the EDT concurrently to you task, which has now been launched
Run Code Online (Sandbox Code Playgroud)