我调用一个列出目录中所有文件并将其添加到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);
}
另一种方法改变了加载.gif的JLabel的可见性。
public void reverseLoadingVisibility(JLabel loaderLabel) {
loaderLabel.setVisible(!loaderLabel.isVisible());
}
问题是:在将文件添加到JTable时,gif无法播放,冻结。
更新:加载gif冻结仍然存在问题
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();
}
}
});
公共类AddFiles扩展了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);
}
...
答案 0 :(得分:2)
这就是原因,因为所有文件都已加载到EDT(事件调度线程)中(希望您使用SwingUtilities.invokerLater()
方法启动应用程序),这会导致所有摆动组件冻结。有关更多详细信息,请阅读oracle的以下Java文档:Initial Threads.
为了解决您的问题,您必须使用SwingWorker。一个类,负责Swing应用程序中的繁重的后台任务。通过简单的Google搜索,您可以从这里获取一个想法:How do I use SwingWorker in Java?
更新,以回答OP的评论。
事实是,您的代码有点大,最重要的是,它不是SSCCE.
为了给您更多帮助,找到您正在寻找的解决方案,我创建了一个SSCCE,使用SwingWorker
做一些“繁重的工作”。在我们的例子中,最麻烦的是在.txt文件中写入1000行,但是每行,线程(我们的工作程序)将休眠10毫秒。
看看,如果需要,可以运行它(我推荐)。代码中包含一些额外的注释,请不要忘记对其进行检查。
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);
});
}
}
小预览:
答案 1 :(得分:1)
我的猜测是您的addFilesWithSubs2-Method正在阻止UI线程。如果您的任务运行时间长,则必须在单独的线程中执行它们,例如SwingWorker