我有一个带有 GUI 的 FileFinder.java 和 Loading.java 类。 FileFinder.java 允许用户选择一个目录并在该目录中搜索文件。现在,对于更大的目录,搜索需要一些时间才能完成,并且我不希望用户怀疑它是否真的在搜索,因此我尝试显示另一个框架(Loading.java)。
这是我单击“搜索”按钮时的代码:
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String dirName = "";
String username = System.getProperty("user.name");
if(cdriveButton.isSelected()){
dirName = "C:/Users/" + username;
}
else if(pdriveButton.isSelected()){
dirName = "P:";
}
else if(xdriveButton.isSelected()){
dirName = "X:";
}
else if(customButton.isSelected()){
dirName = JOptionPane.showInputDialog(rootPane, "Enter the directory you would like to search in: ", "Enter Directory", HEIGHT);
}
String search = filenameText.getText();
File root = new File(dirName);
resultText.setText("");
Loading show = new Loading();
show.setVisible(true);
displayDirectoryContents(root, search);
show.setVisible(false);
}
这是Loading.java:
public class Loading extends javax.swing.JFrame {
/**
* Creates new form Loading
*/
public Loading() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("Please wait...");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(148, 148, 148)
.addComponent(jLabel1)
.addContainerGap(186, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(122, 122, 122)
.addComponent(jLabel1)
.addContainerGap(164, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
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(Loading.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Loading.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Loading.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Loading.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Loading().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
// End of variables declaration
}
一切正常,除了一个小问题:它没有在加载框架内正确显示 GUI。当我按下按钮时,它会弹出,并保持在那里,直到搜索完成,并正确关闭,但它应该显示一个标签,上面写着“请稍候...”。它没有显示该标签,只是显示一个空白的白框。
Edit1:下面找到解决方案。转换为 JDialog Pane 而不是 JFrame 并添加 SwingWorker:
JDialog jDialog = new JDialog();
jDialog.setLayout(new GridBagLayout());
jDialog.add(new JLabel("Please wait..."));
jDialog.setMinimumSize(new Dimension(150, 50));
jDialog.setResizable(false);
jDialog.setModal(false);
jDialog.setUndecorated(true);
jDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
jDialog.setLocationRelativeTo(null);
jDialog.setVisible(true);
SwingWorker swingWorker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
displayDirectoryContents(root, search);
return null;
}
};
最佳答案
您的问题在这里:
displayDirectoryContents(root, search);
您正在 Java 事件线程或 EDT(事件调度线程)上运行它。当运行时间超过一段时间时,它会阻止 EDT 并阻止它执行需要执行的操作,包括显示加载窗口(顺便说一句,该窗口应该是一个对话框窗口,例如 JDialog 和不是应用程序窗口或 JFrame)。
解决方案:在后台线程(例如由 SwingWorker 提供的线程)中运行此方法调用。显示您的对话框窗口,并使用回调来通知您何时工作完成,从而何时不应再显示加载对话框窗口。
例如:
String search = filenameText.getText();
File root = new File(dirName);
resultText.setText("");
Loading show = new Loading();
show.setVisible(true);
displayDirectoryContents(root, search);
show.setVisible(false);
可以更改为类似的内容(注意代码未测试)
String search = filenameText.getText();
File root = new File(dirName);
resultText.setText("");
Loading show = new Loading();
show.setVisible(true);
// create our worker
new SwingWorker<Void, Void> worker = new SwingWorker<>(){
@Override
protected Void doInBackground() throws Exception {
displayDirectoryContents(root, search);
return null;
}
};
worker.addPropertyChangeListener(evt -> {
if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
// you should also call get() on the worker allowing
// you to capture and handle all exceptions it might throw
show.setVisible(false);
}
});
worker.execute(); // run the worker
关于java - 创建 'loading...' 动画帧以在执行方法时显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38103526/