2017-04-21 3 views
0

In Netbeans habe ich ein GUI-Projekt erstellt, das das Frame-Frontend verwendet, das ich Komponenten hinzufügen und doppelklicken kann, um ihre Ereignisse zu bearbeiten. Ich beziehe mich auf das Fenster mit den Registerkarten "Source", "Design" und "History".java SwingWorker Dialog wird nicht angezeigt

Hier sind die Komponenten und Beziehungen:

1- A-Knopf, die eine Dateiauswahl wird geöffnet.

2- eine TextArea, um das Ergebnis der Dateiauswahl anzuzeigen. Wenn der Benutzer eine Datei auswählt, wird der Dateiname in der TextArea angezeigt. Andernfalls wird "Vom Benutzer abgebrochen" geschrieben.

3- Zwischenzeit, wenn der Benutzer eine Datei auswählt, möchte ich einen "Bitte warten" -Dialog mit der Nummer SwingWorker öffnen und einige Arbeiten im Hintergrund ausführen.

Problem ist, dass, wenn der Benutzer eine Datei auswählt, sehe ich nicht den bitte warten-Dialog !! Der vollständige von Netbeans generierte Code ist unter pastebin verfügbar. Ein Teil des Codes wird hier gezeigt:

private void OpenSongFileActionPerformed(java.awt.event.ActionEvent evt) {            
    // TODO add your handling code here: 
    JFileChooser fileChooser = new JFileChooser(); 
    fileChooser.setAcceptAllFileFilterUsed(false); 
    FileNameExtensionFilter filter = new FileNameExtensionFilter("MP3 files", "mp3"); 
    fileChooser.addChoosableFileFilter(filter); 
    fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); 
    int result = fileChooser.showOpenDialog(this); 
    if (result != JFileChooser.APPROVE_OPTION) { 
     //ReadInfo.setText("No song has been selected"); 
     System.out.println("OpenSongFile canceled by user"); 
     return; 
    } 
    final JDialog loading = new JDialog(this); 
    JPanel p1 = new JPanel(new BorderLayout()); 
    p1.add(new JLabel("Please wait..."), BorderLayout.CENTER); 
    loading.setUndecorated(true); 
    loading.getContentPane().add(p1); 
    loading.pack(); 
    loading.setLocationRelativeTo(this); 
    loading.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
    loading.setModal(true); 
    SwingWorker<String, Void> worker = new SwingWorker<String, Void>() { 
     @Override 
     protected String doInBackground() throws InterruptedException { 
      for (int i = 0; i < 10000; i++) 
       for (int j = 0; j < 10000; j++) 
        ; 
      return "hello"; 
     } 
     @Override 
     protected void done() { 
      loading.dispose(); 
     } 
    }; 
    worker.execute(); 
    loading.setVisible(true); 
    try { 
     worker.get(); 
    } catch (Exception e1) { 
     e1.printStackTrace(); 
    } 

    File selectedFile = fileChooser.getSelectedFile(); 
    ReadInfo.setText("Selected file: " + selectedFile.getAbsolutePath()); 
}        

P. S: Ich habe die Swingworker Code here erläutert.

Antwort

1

worker.get(); wird blockiert, bis die SwingWorker zurückkehrt, was bedeutet, dass Sie den EDT blockieren und verhindern, dass der Dialog angezeigt wird.

Stattdessen Nutzung der PropertyChangeListener Unterstützung s SwingWorker machen und Monitor für die START und DONE Ereignisse

SwingWorker<String, Void> worker = new SwingWorker<String, Void>() { 
    @Override 
    protected String doInBackground() throws InterruptedException { 
     Thread.sleep(5000); 
     return "hello"; 
    } 

    @Override 
    protected void done() { 
     loading.dispose(); 
    } 
}; 
worker.addPropertyChangeListener(new PropertyChangeListener() { 
    @Override 
    public void propertyChange(PropertyChangeEvent evt) { 
     System.out.println(evt.getPropertyName()); 
     Object value = evt.getNewValue(); 
     if (value instanceof SwingWorker.StateValue) { 
      SwingWorker.StateValue state = (SwingWorker.StateValue) value; 
      switch (state) { 
       case DONE: { 
        try { 
         String result = worker.get(); 
         JOptionPane.showMessageDialog(null, result); 
        } catch (InterruptedException | ExecutionException ex) { 
         ex.printStackTrace(); 
        } 
       } 
       break; 
      } 
     } 
    } 
}); 
worker.execute(); 
loading.setVisible(true); 

Das andere Problem ist, dass Ihre Schleife wahrscheinlich so schnell ausgeführt wird, dass das Fenster geschlossen ist, bevor es realisiert ist auf dem Bildschirm.

Zum Beispiel habe ich einfach Thread.sleep die doInBackground Methode für 5 Sekunden Pause ...

import java.awt.BorderLayout; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.concurrent.ExecutionException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

public class Memory extends JFrame { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       makeItSo(); 
      } 
     }); 
    } 

    public static void makeItSo() { 
     final JDialog loading = new JDialog(); 
     JPanel p1 = new JPanel(new BorderLayout()); 
     p1.add(new JLabel("Please wait..."), BorderLayout.CENTER); 
     loading.setUndecorated(true); 
     loading.getContentPane().add(p1); 
     loading.pack(); 
     loading.setLocationRelativeTo(null); 
     loading.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 
     loading.setModal(true); 
     SwingWorker<String, Void> worker = new SwingWorker<String, Void>() { 
      @Override 
      protected String doInBackground() throws InterruptedException { 
       Thread.sleep(5000); 
       return "hello"; 
      } 

      @Override 
      protected void done() { 
       loading.dispose(); 
      } 
     }; 
     worker.addPropertyChangeListener(new PropertyChangeListener() { 
      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 
       System.out.println(evt.getPropertyName()); 
       Object value = evt.getNewValue(); 
       if (value instanceof SwingWorker.StateValue) { 
        SwingWorker.StateValue state = (SwingWorker.StateValue) value; 
        switch (state) { 
         case DONE: { 
          try { 
           String result = worker.get(); 
           JOptionPane.showMessageDialog(null, result); 
          } catch (InterruptedException | ExecutionException ex) { 
           ex.printStackTrace(); 
          } 
         } 
         break; 
        } 
       } 
      } 
     }); 
     worker.execute(); 
     loading.setVisible(true); 
    } 

} 
+0

Ich bezweifle es die Hintergrundaufgabe ausgeführt wird, weil die keine Operation Schleifen (Verzögerungen) nicht ausgeführt. Bitte erläutern Sie mehr. – mahmood

+0

Woher wissen Sie, dass Sie in der Methode 'doInBackground' nichts drucken. Ich habe keinen Zweifel, es funktioniert, es sei denn 'if (Ergebnis! = JFileChooser.APPROVE_OPTION) {' ist 'true', muss es ausgeführt werden. Ich habe auch keinen Zweifel, dass "Get" eine Blockierungsmethode ist, es ist ein Dokument als solches. Versuchen Sie das aktualisierte Beispiel. Wenn es immer noch nicht funktioniert, müssen Sie ein ausführbares Beispiel angeben, das Ihr Problem veranschaulicht. Das andere Problem wäre, dass der Worker so schnell fertig ist, dass das Fenster geschlossen wird, bevor es auf dem Bildschirm dargestellt werden kann. – MadProgrammer

+0

Welche der Import-Zeilen bezieht sich auf 'addPropertyChangeListener'? – mahmood

Verwandte Themen