Execute process in Java without JFrame freezing

蹲街弑〆低调 提交于 2019-11-27 16:31:00

Yes you can use a SwingWorker the idea is that a task that takes a lot of time you run in a separate thread (background thread) then you don't block your gui and your JFrame is not gonna to freeze. Here is a complete example i really like Swing Worker Example.

Basically as an example you create your own class that extends SwingWorker override doInBackground.

NOTE: You can have fields like a normal class.

Example :

class Worker extends SwingWorker<Void, String> {
    private SomeClass businessDelegate;    
    private JLabel label;

    @Override
    protected Void doInBackground() throws Exception {
       //here you make heavy task this is running in another thread not in EDT
        businessDelegate.callSomeService();
        setProgress(30); // this is if you want to use with a progressBar
        businessDelegate.saveToSomeDataBase();
        publish("Processes where saved");
        return null;
    }

    @Override
    protected void process(List<String> chunks){
       //this is executed in EDT you can update a label for example
       label.setText(chunks.toString());
    }

   //add setters for label and businessDelegate    
}

You also read about process(..) publish(..) and done().

And in your client code just put.

SwingWorker<Void,String> myWorker = new Worker();
myWorker.execute();

You need to run the code in a separate Thread. The keyword for running and coordinating multiple paths of code in a program is "concurrency":

http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html

Multithreaded code can become quite tricky and difficult to debug, but Java provides some higher level abstractions/concepts that make working with multi-threaded code somewhat less error-prone.

Take a look at the java.util.concurrent package for these concepts.

Since multithreading is an issue you're bound to run into when working with AWT/Swing, there are some utility classes/methods especially designed to facilitate multithreading in graphics applications. SwingWorker is one one of them (another one is e.g. SwingUtilities.invokeLater()). It would be a good idea to familiarize yourself with them, they can make your life easier, especially for simple tasks that are just long enough to otherwise freeze the GUI.

If you are using Swing, SwingWorker is the way to do it.

Since you have mentioned that you don't understand how it works, I will give a simple explanation.

Swing event handling code is done in the event dispatch thread. So if a user clicks a button (say update button which fetches the data from server and shows them in the window), the ActionListener of that button is called in the event dispatch thread.

If you fetch the data in the same thread then the UI would freeze, because it cannot process any events (you are running code in the event dispatch thread).

So you should fetch the data in a separate thread. But after fetching the data, you should set it to the view in the event dispatch thread.

The Swing worker makes this easy for you. You put the heavy task in the doInBackground method(in our case fetching the data) and return the output of the heavy task (in our case the data) from the method.

In the done method of the swing worker you call the get method which will give you the data returned in the doInBackground method. There, you update the view with the new data(For example add the data to a TableModel).

When you call exectue on your swing worker now, it will take care of running the doInBackground in a separate thread (which is not the Event Dispatch Thread) and it will run the done method in the event dispatch thread.

So by using the SwingWorker, you don't have to worry about the internals of handling UI events in the EDT and the time consuming tasks in another thread.

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