Java在处理数据时加载gif冻结? [英] Java loading gif freeze while processing data?

查看:33
本文介绍了Java在处理数据时加载gif冻结?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我调用一个列出目录中所有文件并将其添加到JTable的方法:

  addFilesWithSubsButton.addActionListener(new ActionListener(){公共无效actionPerformed(ActionEvent e){reverseLoadingVisibility(loaderLabel);//设置可见addFilesWithSubs2(chooser,loaderLabel);}});public void addFilesWithSubs2(JFileChooser选择器,JLabel loaderLabel){//加载所有文件...//列出每个文件时://设置不可见reverseLoadingVisibility(loaderLabel);} 

另一种方法改变了加载.gif的JLabel的可见性.

  public void reverseLoadingVisibility(JLabel loaderLabel){loaderLabel.setVisible(!loaderLabel.isVisible());} 

问题是:在将文件添加到JTable时,gif无法播放,冻结.

更新:加载gif冻结仍然存在问题

  addFilesButton.addActionListener(new ActionListener(){公共无效actionPerformed(ActionEvent arg0){reverseLoadingVisibility(loaderLabel);尝试 {新的AddFiles().doInBackground(选择者CHOOSERTITLE,lastDictionary,sdf,filesTable,模型,columnNames,loaderLabel);} catch(Exception e){e.printStackTrace();}}}); 

公共类AddFiles扩展了SwingWorker {

  @Override受保护的Void doInBackground()引发异常{返回null;}受保护的void doInBackground(JFileChooser选择器,字符串CHOOSERTITLE,字符串lastDictionary,SimpleDateFormat sdf,JTable文件表,DefaultTableModel模型,String [] columnNames,JLabel loaderLabel)引发异常{//设置可见reverseLoadingVisibility(loaderLabel);Chooser.setDialogTitle(CHOOSERTITLE);choicer.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);//choicer.setAcceptAllFileFilterUsed(true);//TODO:已更改为选择器如果(chooser.showOpenDialog(chooser)== JFileChooser.APPROVE_OPTION){//创建一个实际上是目录的文件File aDirectory =新文件(chooser.getSelectedFile().toString());lastDictionary =选择器.getSelectedFile().toString();//获取目录中所有文件的清单String [] filesInDir = aDirectory.list();//去做System.out.println(文件数:" + filesInDir.length);//拥有我需要的一切,现在就打印为(int i = 0; i< filesInDir.length; i ++){文件currentFile =新文件(aDirectory +"\\" + filesInDir [i]);System.out.println(filesInDir [i]);System.out.println(aDirectory);System.out.println(currentFile.length()/1024 +"KB");System.out.println(sdf.format((currentFile).lastModified()));//避免重复int行= 0;布尔重复=假;for(; row< filesTable.getRowCount(); row ++){如果(model.getValueAt(row,1).equals(filesInDir [i])&&model.getValueAt(row,3).equals(aDirectory)){重复=真;休息;}System.out.println("model.getValueAt(row,1)" + model.getValueAt(row,1));System.out.println(filesInDir [i]);System.out.println("model.getValueAt(row,3)" + model.getValueAt(row,3));System.out.println(aDirectory);}if(!duplicate&& currentFile.isFile()){model.addRow(new Object [] {filesTable.getRowCount()+ 1,filesInDir [i],空值,目录,currentFile.length()/1024 +"KB",sdf.format((currentFile).lastModified())});}}}别的 {System.out.println(无选择");}//重新调整列AdjustTableColumns(filesTable,columnNames);//设置不可见reverseLoadingVisibility(loaderLabel);} 

...

解决方案

这就是原因,因为所有文件都已加载到EDT(事件调度线程)中(希望您使用 SwingUtilities.invokerLater()启动应用程序)>方法),从而导致所有摆动组件冻结.有关更多详细信息,请阅读oracle的以下Java文档:

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

    addFilesWithSubsButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            reverseLoadingVisibility(loaderLabel); //set Visible
            addFilesWithSubs2(chooser, loaderLabel);
        }
    });

public void addFilesWithSubs2(JFileChooser chooser, JLabel loaderLabel) {
    //loading all files ....

    //when every file is listed:
    //Set invisible
    reverseLoadingVisibility(loaderLabel);
}

The another method change reverse the visibility of the JLabel in which the loading .gif is.

public void reverseLoadingVisibility(JLabel loaderLabel) {
    loaderLabel.setVisible(!loaderLabel.isVisible());
}

The problem is: the gif doesn't play, freezes while the files are added to the JTable.

UPDATE: Still have problem the loading gif freezes

addFilesButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                reverseLoadingVisibility(loaderLabel);
                try {
                    new AddFiles().doInBackground(
                            chooser, CHOOSERTITLE, 
                            lastDictionary,
                            sdf,
                            filesTable,
                            model,
                            columnNames,
                            loaderLabel);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

public class AddFiles extends SwingWorker{

@Override
protected Void doInBackground() throws Exception {
    return null;
}

protected void doInBackground(JFileChooser chooser, String CHOOSERTITLE, 
        String lastDictionary,
        SimpleDateFormat sdf,
        JTable filesTable,
        DefaultTableModel model,
        String[] columnNames,
        JLabel loaderLabel) throws Exception {
    //Set visible
    reverseLoadingVisibility(loaderLabel);


    chooser.setDialogTitle(CHOOSERTITLE);
    chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
    //
    chooser.setAcceptAllFileFilterUsed(true);
    //TODO: this changed to chooser    
    if (chooser.showOpenDialog(chooser) == JFileChooser.APPROVE_OPTION) { 

      // create a file that is really a directory
      File aDirectory = new File(chooser.getSelectedFile().toString());
      lastDictionary = chooser.getSelectedFile().toString();

      // get a listing of all files in the directory
      String[] filesInDir = aDirectory.list();
      // TODO
      System.out.println("Number of files: " + filesInDir.length);

      // have everything i need, just print it now


      for ( int i=0; i<filesInDir.length; i++ )
          {
            File currentFile = new File(aDirectory + "\\" + filesInDir[i]);

            System.out.println(filesInDir[i] );
            System.out.println(aDirectory );
            System.out.println(currentFile.length()/1024 + " KB");



            System.out.println(sdf.format((currentFile).lastModified()));

            // Avoid duplicates
            int row = 0;
            boolean duplicate = false;
            for (; row < filesTable.getRowCount(); row++) {
                if (model.getValueAt(row, 1).equals(filesInDir[i]) &&
                    model.getValueAt(row, 3).equals(aDirectory)
                ) {
                    duplicate = true;
                    break;
                }
                System.out.println("model.getValueAt(row, 1) " + model.getValueAt(row, 1));
                System.out.println(filesInDir[i]);
                System.out.println("model.getValueAt(row, 3) " + model.getValueAt(row, 3));
                System.out.println(aDirectory);
            }

            if (!duplicate && currentFile.isFile()) {
                model.addRow(new Object[]{
                        filesTable.getRowCount()+1, 
                        filesInDir[i],
                        null,
                        aDirectory,
                        currentFile.length()/1024 + " KB",
                        sdf.format((currentFile).lastModified())
                });


            }


          }
      }
    else {
      System.out.println("No Selection ");
    }

    // Readjust columns
    adjustTableColumns(filesTable, columnNames);

    //Set unvisible
    reverseLoadingVisibility(loaderLabel);
}

...

解决方案

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:

这篇关于Java在处理数据时加载gif冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆