顯然,OP已經解決了他的問題,但我認爲這是一個有趣的和常見的問題,所以我創建了我的推薦方法的Minimal, Complete and Verifiable Example,供將來參考。
您可以在下面查看,或者您可以從the GitHub repository獲得完整的項目。
(評論,建議,修改和反饋,也歡迎!)
主要的JFrame:
/**
* @author Rodrigo Legendre Lima Rodrigues (AKA ArchR/AlmightyR)
* <[email protected]>
*/
public class Main extends javax.swing.JFrame {
/**
* A public method so we can enable/disable state from outside the class
* (while keeping the components encapsulated).
*
* @param enabled The input state the components should assume.
*/
public void setInputState(boolean enabled) {
this.startProcessButton.setEnabled(enabled);
}
/**
* Creates new form Main
*/
public Main() {
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() {
startProcessButton = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Primary Frame");
startProcessButton.setText("Process");
startProcessButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
startProcessButtonActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(startProcessButton, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(startProcessButton)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
@SuppressWarnings("Convert2Lambda")
private void startProcessButtonActionPerformed(java.awt.event.ActionEvent evt) {
//We need a non-annonymous reference for this frame to use within our annonymous 'run()'.
Main main = this;
//Here is were we disable input for (the components of) this frame before running the secondary frame.
this.setInputState(false);
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Secondary(main).setVisible(true);
}
});
}
/**
* @param args the command line arguments
*/
@SuppressWarnings("Convert2Lambda")
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 | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Main().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton startProcessButton;
// End of variables declaration
}
次要的JFrame:
/**
*
* @author Rodrigo Legendre Lima Rodrigues (AKA ArchR)
* <[email protected]>
*/
public class Secondary extends javax.swing.JFrame {
/**
* A variable to hold a reference to the main frame. We need this to enable
* the input of main again after this frame's work is done.
*/
private Main main;
/**
* A self-reference to this frame. We need this to hide the frame from
* within the worker, after it's job is done.
*/
private Secondary secondary;
/**
* A SwingWorker executes a process without interfering with the UI's
* execution, which could otherwise cause delays or complete "locking" of
* the visual and input processes.
*/
SwingWorker<Integer, Integer> swingWorker = new SwingWorker<Integer, Integer>() {
@Override
@SuppressWarnings("SleepWhileInLoop")
protected Integer doInBackground() throws Exception {
//Execute the process...
for (int i = 0; i <= 100; i++) {
progressBar.setValue(i);
Thread.sleep(100);
}
//We handle reactivating the main frame's inputs on the closing event,
//to make sure they get enabled after this frame is closed,
//regardless of sucess, cancelation or failure.
//We close and dispose of the secondary frame.
//Note: We have set default close behavior for this frame to be disposing, so we simply send it a closing event.
secondary.dispatchEvent(new WindowEvent(secondary, WindowEvent.WINDOW_CLOSING));
//Alternatively:
//main.setInputState(true);
//secondary.setVisible(false);
//secondary.dispose();
return 100;
}
};
/**
* In order to start the process while keeping all related code contained
* within this class, we make it listen to it's own WindowOpened event.
*
* In order to avoid calling an overridable method ('addListener()') from
* the constructor, which could be "forgotten" on extensions, we create a
* private method to initialize all self-listeners.
*/
private void initSelfListeners() {
WindowListener taskStarterWindowListener = new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
//This starts the process when the window opens.
System.out.println("Performing task...");
swingWorker.execute();
}
//<editor-fold defaultstate="collapsed" desc="UNUSED EVENTS/METHODS">
@Override
public void windowClosing(WindowEvent e) {
//Do nothing.
}
@Override
public void windowClosed(WindowEvent e) {
//Do nothing.
}
@Override
public void windowIconified(WindowEvent e) {
//Do nothing.
}
@Override
public void windowDeiconified(WindowEvent e) {
//Do nothing.
}
@Override
public void windowActivated(WindowEvent e) {
//Do nothing.
}
@Override
public void windowDeactivated(WindowEvent e) {
//Do nothing.
}
//</editor-fold>
};
//Here is where the magic happens. We make (a listener within) the frame start listening to the frame's own WindowOpened event.
this.addWindowListener(taskStarterWindowListener);
}
/**
* Creates new form Secondary
*/
@SuppressWarnings("LeakingThisInConstructor")
private Secondary() {
initComponents();
initSelfListeners();
this.secondary = this;
}
public Secondary(Main main) {
this();
this.main = main;
}
/**
* 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() {
processingLabel = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("Secondary Frame");
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
formWindowClosing(evt);
}
});
processingLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
processingLabel.setText("Processing...");
progressBar.setStringPainted(true);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(processingLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(processingLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void formWindowClosing(java.awt.event.WindowEvent evt) {
//When the window is closed, we enable the input in the main frame again.
//This is advantageous as it handles most cases in one go...
//The cases were the window closes after the process is complete,
//the cases there the window closes due to cancelation,
//or the cases where it is closed by the user (after an error message) after a failure.
main.setInputState(true);
}
/**
* @param args the command line arguments
*/
@SuppressWarnings("Convert2Lambda")
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 | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Secondary.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Secondary().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel processingLabel;
private javax.swing.JProgressBar progressBar;
// End of variables declaration
}
爲了得到更好的幫助,請儘快發佈[mcve]不是整個班級 – Frakcool
@Frakcool,但還需要什麼?我編寫了所有使用的代碼並描述了問題。 – bukashka101
正是!你寫了**所有**代碼!我們不需要所有的代碼,儘可能簡單地從頭開始創建一個新項目,一個按鈕和'onImageCreated'方法,如果你可以使用一個,你可以儘可能多地做到這一點。這就是爲什麼我沒有要求你的整個代碼,但一個最小的例子,仍然可運行 – Frakcool