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

时间:2012-01-18 19:36:34

标签: java swing text jlabel concurrency

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

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

那么,是否有人建议我如何解决这种情况而不做一些事情,比如显示一个消息框(什么会是)没有任何理由?

提前致谢

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

你是否从EDT调用了setText()方法?