如何使用Swing减少Open文件的加载时间?

时间:2014-08-16 04:40:01

标签: java swing

我想打开一个文件而不花任何时间。当我立即点击打开按钮它已被打开。但是,在我的应用程序中大文件花了两分多钟。我尝试打开一个文件,它大小为44MB。这个文件打开时间超过两分钟。我想快速打开大尺寸文件。一旦检查我的打开操作代码。 以下代码显示了我的应用程序的工作示例。 示例代码:

public class OpenDemo extends javax.swing.JFrame {
JTextPane textPane;
JScrollPane scrollPane;
int i=0;
JTextField status;
public OpenDemo() {
    initComponents();
    textPane=new JTextPane();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    tp = new javax.swing.JTabbedPane();
    jMenuBar1 = new javax.swing.JMenuBar();
    jMenu1 = new javax.swing.JMenu();
    open = new javax.swing.JMenuItem();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jMenu1.setText("File");

    open.setText("Open");
    open.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            openActionPerformed(evt);
        }
    });
    jMenu1.add(open);

    jMenuBar1.add(jMenu1);

    setJMenuBar(jMenuBar1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(tp, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(tp, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

private void openActionPerformed(java.awt.event.ActionEvent evt) {                                     
    JFileChooser fileChooser=new JFileChooser();
    int result = fileChooser.showOpenDialog(this);
                    if (result==JFileChooser.APPROVE_OPTION) {
                        File file = fileChooser.getSelectedFile();
                        try {
                            textPane.setPage(file.toURI().toURL());
                        } catch(Exception e) {
                            e.printStackTrace();
                        }
                    }
      scrollPane=new JScrollPane(textPane);
      tp.add(scrollPane);
      textPane.setCaretPosition(0);   
}                                    

public static void main(String args[]) {
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new OpenDemo().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JMenu jMenu1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem open;
private javax.swing.JTabbedPane tp;
// End of variables declaration                   

}

2 个答案:

答案 0 :(得分:1)

SwingWorker API概述了一种合适的方法。由于尺寸问题,我更新TableModel,如图所示here,而不是文字组件。线条将立即开始出现,而GUI仍然保持响应。聆听JTable只需要render 可见行,您可以使用sorting and filtering

答案 1 :(得分:1)

有一些开销(进度动画)和一些我不会做的事情,比如AWT事件线程阻塞actionPerformed。

将代码转到https://codereview.stackexchange.com/,因为代码审核可能很有用。

我认为可以优化:

StringBuilder提供初始容量。

... = new StringBuilder(1024*64); // (int)file.length()?

使用BufferdReader使用readLine()替换扫描仪。 理想的是检查Files.readAllBytes的速度;是否需要进度指示。

String s = new String(Files.readAllBytes(file.toPath()));

第二次尝试:

首先是一个健全措施:关闭文件。

然后我做的动画进展较少,这肯定会加快速度。 它将不再显示文本窗格中的所有文本,仅显示每百行。

        try (BufferedReader br = new BufferedReader(new FileReader(file))) {
            final int PROGRESS_EVERY = 100;
            while ((line = br.readLine()) != null) {
                lineNumber++;
                text.append(line);
                text.append("\n");
                if (linenumber % PROGRESS_EVERY== 0) {
                    ProgressData data = new ProgressData();
                    data.number = lineNumber;
                    data.line = line;
                    publish(data);
                }
            }
            if (linenumber % PROGRESS_EVERY != 0) {
                ProgressData data = new ProgressData();
                data.number = lineNumber;
                data.line = line;
                publish(data);
            }
        }

然后

    private StringBuilder text = new StringBuilder(1024 * 128);

最后:

textPaneJTextPane更改为JTextArea。速度大幅提升。