Java 如何使用Swing减少打开文件的加载时间?
我想在不占用任何时间的情况下打开一个文件。当我立即单击“打开”按钮时,它已被打开。但是,在我的应用程序中,大文件的打开时间超过了两分钟。我尝试打开一个大小为44MB的文件。此文件的打开时间超过了两分钟。我想快速打开大文件。请检查我的打开操作代码。 下面的代码显示了我的应用程序的工作示例。 示例代码:Java 如何使用Swing减少打开文件的加载时间?,java,swing,Java,Swing,我想在不占用任何时间的情况下打开一个文件。当我立即单击“打开”按钮时,它已被打开。但是,在我的应用程序中,大文件的打开时间超过了两分钟。我尝试打开一个大小为44MB的文件。此文件的打开时间超过了两分钟。我想快速打开大文件。请检查我的打开操作代码。 下面的代码显示了我的应用程序的工作示例。 示例代码: public class OpenDemo extends javax.swing.JFrame { JTextPane textPane; JScrollPane scrollPane; int
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
}
公共类OpenDemo扩展了javax.swing.JFrame{
JTextPane textPane;
JScrollPane滚动窗格;
int i=0;
JTextField状态;
公共OpenDemo(){
初始化组件();
textPane=新的JTextPane();
}
@抑制警告(“未选中”)
//
私有组件(){
tp=newjavax.swing.JTabbedPane();
jMenuBar1=newjavax.swing.JMenuBar();
jMenu1=newjavax.swing.JMenu();
open=newjavax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setText(“文件”);
open.setText(“open”);
open.addActionListener(新java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
执行的开放操作(evt);
}
});
jMenu1.add(打开);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout=newjavax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(布局);
layout.setHorizontalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tp,javax.swing.GroupLayout.Alignment.TRAILING,javax.swing.GroupLayout.DEFAULT\u SIZE,400,Short.MAX\u值)
);
layout.setVerticalGroup(
createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tp,javax.swing.GroupLayout.DEFAULT\u SIZE,279,Short.MAX\u值)
);
包装();
}//
私有void openActionPerformed(java.awt.event.ActionEvent evt){
JFileChooser fileChooser=新的JFileChooser();
int result=fileChooser.showOpenDialog(此);
if(result==JFileChooser.APPROVE\u选项){
File File=fileChooser.getSelectedFile();
试一试{
textPane.setPage(文件.toURI().toul());
}捕获(例外e){
e、 printStackTrace();
}
}
scrollPane=新的JScrollPane(文本窗格);
tp.add(滚动窗格);
textPane.setCaretPosition(0);
}
公共静态void main(字符串参数[]){
试一试{
for(javax.swing.UIManager.LookAndFeelInfo:javax.swing.UIManager.getInstalledLookAndFeels()){
if(“Nimbus”.equals(info.getName())){
setLookAndFeel(info.getClassName());
打破
}
}
}捕获(ClassNotFoundException ex){
getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE,null,ex);
}catch(实例化异常){
getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE,null,ex);
}捕获(非法访问例外){
getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE,null,ex);
}catch(javax.swing.UnsupportedLookAndFeelException ex){
getLogger(OpenDemo.class.getName()).log(java.util.logging.Level.SEVERE,null,ex);
}
//
invokeLater(new Runnable()){
公开募捐{
新建OpenDemo().setVisible(true);
}
});
}
//变量声明-不修改
私有javax.swing.JMenu jMenu1;
私有javax.swing.JMenuBar jMenuBar1;
私有javax.swing.JMenuItem打开;
私有javax.swing.JTabbedPane tp;
//变量结束声明
}
API概述了一种合适的方法。由于大小的原因,我将更新一个表格模型
,如图所示,而不是一个文本组件。行将几乎立即开始出现,而GUI保持响应。监听JTable
只需要可见的行,您可以利用。有一些开销(进度动画)和一些我不会做的事情,比如执行AWT事件线程阻塞操作
使用您的代码访问,因为代码复查可能会很有用
我认为是可优化的:
为StringBuilder
提供初始容量
... = new StringBuilder(1024*64); // (int)file.length()?
使用readLine()
将扫描仪更换为BufferdReader
。
理想的方法是检查文件的速度;是否需要进度指示
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);
最后:
将textPane
从JTextPane
更改为JTextArea
。速度大幅度提高。不要将整个文件读入内存。只阅读屏幕上显示的内容,在滚动时根据需要阅读其余内容。“我试图打开一个文件,它的大小为44MB。”真的吗?为什么要在最终用户上转储44MB?无论如何,这个文件中有什么-图像、视频、文本..?“不花任何时间”将无法实现。但是,如果你不逐行而是以较大的块读取文件,你可以加快速度。在我看来,当你加载这个巨大的文件时,GUI好像挂起了,这就是为什么你希望这么快。如果是这样的话,你也可以提供我的开放式工作或更换的工作例子吗?