文件搜索器:如何在主线程执行时使用JFrame?



这是我的第一篇文章,所以如果有什么问题,我会尝试修复它。 我正在处理的测试任务是使文件搜索器具有导航文本等的能力。我完成了这部分,除了一件事:应用程序需要允许用户在目录中搜索文件时使用它。

我已经阅读了很多关于多线程的信息,但仍然无法得到如何做到这一点的答案......这是当用户在我的 JFrame("GUI"类中按"选择文件夹"时执行的代码(:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
DefaultTreeModel model = (DefaultTreeModel) jTree1.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
int j = jTree1.getRowCount() - 1;
final JFileChooser fc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(jComboBox1.getSelectedItem().toString() + " files", jComboBox1.getSelectedItem().toString());
fc.setFileFilter(filter);
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setDialogTitle("Choose a folder to fing ." + jComboBox1.getSelectedItem().toString() + " files");
jLabel4.setText("Searching files in folder, please wait");
if (fc.showOpenDialog(jButton3) == JFileChooser.APPROVE_OPTION) {
root.setUserObject("Your root");
jTextArea1.setText("");
jTextField1.setText("");
if (jTree1.getRowCount() > 0) {
for (int i = 0; i < j; i++) {
model.removeNodeFromParent((MutableTreeNode) model.getChild(root, 0));
}
}
long startTime = System.currentTimeMillis();
File f2 = new File(fc.getSelectedFile().getAbsolutePath());
String name2 = "." + jComboBox1.getSelectedItem().toString();
//FilenameFilter filter1 = (File dir, String name1) -> name1.endsWith(name2);
ArrayList<File> files = new ArrayList<>();
new NewТhread();
listf(f2, files, name2);
root.setUserObject(f2);
model.nodeChanged(root);
for (int i = 0; i < files.size(); i++) {
DefaultMutableTreeNode child = new DefaultMutableTreeNode(files.get(i).getAbsolutePath().replace(f2.toString(), ""));
root.add(child);
model.reload();
jLabel4.setText("Done! Now type text to search and press "Search files"");
}
System.out.println("Time used for getting files: " + (System.currentTimeMillis() - startTime) / 1000 + "sec");
JOptionPane.showMessageDialog(null, "Directory opened:" + fc.getSelectedFile().getAbsolutePath());
System.out.println("Main thread finished");
} else if (fc.showOpenDialog(jButton3) == JFileChooser.CANCEL_OPTION) {
jLabel4.setText("Please, choose folder and extension to find files");
}
}

Listf 也是一种检查所有子目录的方法:

public ArrayList<File> listf(File directory, ArrayList<File> files, String extension) {
File[] flist = directory.listFiles();
for (int i = 0; i < flist.length; i++) {
if (flist[i].isFile() && flist[i].getName().endsWith(extension) == true) {
files.add(flist[i]);
} else if (flist[i].isDirectory()) {
listf(flist[i], files, extension);
}
}
return files;
}

NewThread是一个我仍然无法进入的类。现在它看起来像这样:

class NewТhread extends Thread {
NewТhread() {
super("Demo");
start();
}
public synchronized void run() {
try {
for (int i = 3; i > 0; i--) {
Thread.sleep(500);
System.out.println(i);
GUI gui = new GUI();
gui.setVisible(true);
}
} catch (InterruptedException е) {
System.out.println("Interrupted");
}
}

在 3-2-1 计数后,它应该打开新的 GUI 对象 (JFrame(,该对象应该允许执行所有操作。现在,对象 GUI gui 的所有元素在主线程执行时被冻结(并且仅在搜索完成时解冻(。 你能帮忙吗?

您可以通过仅将不需要用户交互的代码放入线程的 run 方法中来启动线程,如下所示:

new Thread()
{
public void run()
{
// code which does not require user's interaction
}
}.start();

在您的情况下,要放置在run方法中的代码将是编写在"jButton1ActionPerformed"动作侦听器中的代码。

谢谢大家。我找到了执行器服务的决定,它允许在加载数据时不冻结项目。

最新更新