Java loading gif freeze while processing data?

前端 未结 2 1391
萌比男神i
萌比男神i 2020-12-12 03:03

I call a method which lists all the files in a directory, and adds them to a JTable:

    addFilesWithSubsButton.addActionListener(new ActionListener() {
             


        
相关标签:
2条回答
  • 2020-12-12 03:50

    My guess would be that your addFilesWithSubs2-Method is blocking the UI thread. If you have long running tasks, than you have to execute them in a separate thread e.g. SwingWorker

    0 讨论(0)
  • 2020-12-12 04:03

    That's why because all files are loaded in the EDT (Event Dispatch Thread) (hopefully you launch your application using SwingUtilities.invokerLater() method) which cause all swing components to freeze. For more details read this java document by oracle: Initial Threads.

    In order to solve your problem, you have to use a SwingWorker. A class responsible for heavy background tasks in Swing applications. With a simple google search, you can take an idea from here: How do I use SwingWorker in Java?

    UPDATE in order to answer OP's comment.

    The truth is that your code is a little bit big, and the most important, it is not an SSCCE.

    In order to give you one more hand to find the solution you are looking for, i have created an SSCCE, using a SwingWorker that does something "heavy". In our case, the something heavy, is to write 1000 lines in a .txt file, but each line, thread (our worker) will sleep for 10ms.

    Take it a look, run it if you want (i recommend it). Some extra comments inside the code, do not forget to check them.

    package test;
    
    import java.awt.BorderLayout;
    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.util.List;
    
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.SwingWorker;
    
    public class SwingWorkerExample extends JFrame {
        /*
         * Worker has Void doInBackground a.k.a, doInBackground method needs to return nothing.
         * Worker needs to process-publish Integers.
         */
        private SwingWorker<Void, Integer> writeToFileWorker = null;
        private JLabel gifLabel;
        private JButton doSomethingHeavy;
    
        public SwingWorkerExample() {
            super("Just a test.");
            createWorker();
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            getContentPane().setLayout(new BorderLayout());
            gifLabel = new JLabel();
            ImageIcon gif = new ImageIcon("C:/Users/George/Desktop/giphy.gif");
            gifLabel.setIcon(gif);
            gifLabel.setVisible(false); //Initialy non visible
            gifLabel.setHorizontalTextPosition(JLabel.CENTER);
            gifLabel.setVerticalTextPosition(JLabel.BOTTOM);
            gifLabel.setHorizontalAlignment(JLabel.CENTER);
            getContentPane().add(gifLabel, BorderLayout.CENTER);
    
            doSomethingHeavy = new JButton("Do something heavy in another thread and start dancing...");
            doSomethingHeavy.addActionListener(e -> {
                //Before start the worker, show gif and disable the button
                doSomethingHeavy.setEnabled(false);
                gifLabel.setVisible(true);
                writeToFileWorker.execute();
            });
            getContentPane().add(doSomethingHeavy, BorderLayout.PAGE_END);
            setSize(500, 300);
            setLocationRelativeTo(null);
        }
    
        private void createWorker() {
            writeToFileWorker = new SwingWorker<Void, Integer>() {
                @Override
                protected Void doInBackground() throws Exception {
                    File fileToWrite = new File(System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "hello_worlds.txt");
                    try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileToWrite));) {
                        for (int line = 0; line < 1000; line++) {
                            writer.append("Hello World! My name is Swing Worker.");
                            writer.append(System.lineSeparator());
                            Thread.sleep(10);
                            publish(line);
                        }
                    }
                    return null;
                }
    
                /*
                 * Runs in Event Dispatch Thread (EDT)
                 */
                @Override
                protected void process(List<Integer> chunks) {
                    int line = chunks.get(0);//First parameter is the line
                    gifLabel.setText("Written " + line + " lines in the txt.");
                    super.process(chunks);
                }
    
                /*
                 * Runs in Event Dispatch Thread (EDT)
                 */
                @Override
                protected void done() {
                    //When swing worker is finished, a.k.a the heavy work, stop the gif and enable the button
                    gifLabel.setVisible(false);
                    doSomethingHeavy.setEnabled(true);
                    super.done();
                }
            };
    
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                SwingWorkerExample swe = new SwingWorkerExample();
                swe.setVisible(true);
            });
        }
    }
    

    Small preview:

    0 讨论(0)
提交回复
热议问题