java - JLabel 不会更新,除非有什么东西导致方法挂起

标签 java swing text jlabel concurrency

首先,抱歉,虽然我认为我可以很好地解释情况并解决我的问题,但为此重建 SSCCE 真的很难,

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

那么,有没有人对我如何解决这种情况有任何建议,而不是无缘无故地显示消息框之类的事情?

提前致谢

最佳答案

确保您没有在 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

关于java - JLabel 不会更新,除非有什么东西导致方法挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8916221/

相关文章:

java - 如何为包含多个 JPanel、JButton 和 JLabel 的 JFrame 设置背景颜色?

java - Swing:创建一个 UWP ("Metro")–like 按钮

ios - iPhone 导航栏标题文本颜色在 iOS 11 中的 viewWillAppear() 或 viewWillDisappear 函数中不会改变

java - 异常 block 上的 JMockit NullPointerException?

java - 在其他项目中重用 Cucumber-JVM 步骤定义

java - 这段代码SQL注入(inject)安全吗?

java - ListCellRenderer 和区分下拉列表中的显示和内联显示

java - JFreeChart getSeriesStroke/Paint/Shape 返回 null

javascript - 在 Javascript 中动画文本

php - FPDF:在单元格内更改文本颜色?