JLabel will not update unless something causes the method to hang

烂漫一生 提交于 2019-12-11 07:37:11

问题


Firstly, apologies but it would be really hard to reconstruct a SSCCE for this, though I think I can explain the situation considerably well and get my question across,

My situation is as thus: I have a JLabel that serves as a status indicator (e.g. that will display "Loading..." or "Ready") and I call the setText method in a MouseAdapter before another method is called to do the actual action. However, the JLabel text never changes, unless I do something like call JOptionPane.showMessageDialog() in which case the text does update.

So, does anybody have any suggestions as to how I can resolve this situation without doing something like displaying a message box for (what would be) no reason whatsoever?

Thanks in advance


回答1:


Make sure you don't run your task (your "Loading..." procedure) on the EDT (Event Dispatch Thread); if you do so, your GUI won't get updated.

You have to run your application code (unless it's very fast, say less than 100ms, no network access, no DB access, etc) on a separate thread. The SwingWorker (see javadocs) class might come handy for this purpose.

The EDT (e.g. code blocks inside user interface listeners) should only contain code for updating the GUI, operating on Swing components, etc. Everything else you should run on its own Runnable object.

--

EDIT: reponse to Andy's comment. Here's a raw example (written on the fly, it might have typos and such and might not run as-is) of how you can use the SwingWorker class

Put this in your mouse listener event or whatever makes your task start

//--- 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



回答2:


Do you call the setText() method from the EDT?



来源:https://stackoverflow.com/questions/8916221/jlabel-will-not-update-unless-something-causes-the-method-to-hang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!