2016-05-26 5 views
0

Ich mache ein Programm, das in der Lage sein sollte, den gesamten Prozess auf Knopfdruck zu stoppen.Wie kann done() in einem SwingWorker-Thread abgebrochen werden?

Ich habe sw.cancel(true); zu tun, aber die SwingWorker Methode protected void done() ist noch in Betrieb.

Wie kann ich auf Knopfdruck das Ganze abbrechen? Nicht nur die doInBackground() Methode?

Hier ist die ganze relevante Code unten für diejenigen, die interessiert sind:

sw = new SwingWorker() { 
    protected Object doInBackground() throws Exception { 
     //Pravljenje timera 
     t = new Timer(0, new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
      } 
     }); 

     //Provera stanja checkboxova 
     if(jCheckBox2.isSelected()) { 
      try { 
       int delay =(int) jSpinner2.getValue(); 
       jCheckBox1.setSelected(false); 
       Thread.sleep(delay*60000); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(App_Gui.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

     if(jCheckBox1.isSelected()) { 
      jCheckBox2.setSelected(false); 

      Date delay2 = (Date) jSpinner1.getValue(); 
      userCal = Calendar.getInstance(); 
      System.out.println("delay2: " + delay2); 
      userCal.setTime(delay2); 
      System.out.println("userCal:" + userCal); 
      Calendar sysCal = Calendar.getInstance(); 
      System.out.println("sysCal: " + sysCal); 
      timerAtDate = 
       (((int) userCal.get(Calendar.HOUR_OF_DAY) - (int) sysCal.get(Calendar.HOUR_OF_DAY)) * 60 * 60 * 1000 + 
       ((int) userCal.get(Calendar.MINUTE) - (int) sysCal.get(Calendar.MINUTE)) * 60 * 1000 + 
       ((int) userCal.get(Calendar.SECOND) - (int) sysCal.get(Calendar.SECOND)) * 1000); 
      Thread.sleep(timerAtDate); 
     } 

     return null; 
    } 

    @Override 
    protected void done() { 
     System.out.println("Done!"); 

     t.start(); 
     t.setRepeats(false); 
     JDialog dialog = new JDialog(); 
     dialog.setLocation(700, 300); 
     dialog.setSize(600, 400); 
     dialog.setVisible(true); 
     try { 
      Thread.sleep(jSlider1.getValue()); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(App_Gui.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     System.out.println("Zapravo gotov"); 
     dialog.getContentPane().setBackground(jLabel2.getBackground()); 
     dialog.setModal(true); 
     Assignment_Tajmer_Aplikacija.f.setVisible(false); 
    } 
}; 

sw.execute(); 

private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) { 
    // TODO add your handling cosadde here: 
    jSlider1.addChangeListener(new ChangeListener() { 
     public void stateChanged(ChangeEvent e) { 
      JSlider source = (JSlider) e.getSource(); 
      //System.out.println(source.getValue()); 
     } 
    }); 
}          

private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) { 
    // TODO add your handling code here: 
    JColorChooser jcc = new JColorChooser(); 
    Color c = jcc.showDialog(null, "Choose background color", Color.yellow); 
    jLabel2.setForeground(c); 
    jLabel2.setBackground(c); 
    jLabel2.setText("Color: " + c.getRGB() + "(RGB)"); 
}           

private void jCheckBox2ActionPerformed(java.awt.event.ActionEvent evt) { 
    // TODO add your handling code here: 
    jCheckBox1.setSelected(false); 
}           

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { 
    // TODO add your handling code here: 
    sw.cancel(true); 
}           

private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) { 
    // TODO add your handling code here: 
    jCheckBox2.setSelected(false); 
}           
+0

'SwingWorker' wird im Allgemeinen für zeitraubende Verarbeitung im Hintergrund verwendet, so dass es die Benutzeroberfläche nicht einfriert. Sie können auch Aktualisierungen an die Benutzeroberfläche senden, um beispielsweise eine Fortschrittsanzeige zu aktualisieren. In Ihrem Fall kann ich nichts dergleichen sehen, was mich wundern lässt, warum Sie überhaupt 'SwingWorker' benutzen? –

+0

Es gibt mehr zum Code, ich benutze einen SwingWorker, weil der Timer 10 Jahre in der Zukunft eingestellt werden kann, ich habe nie das Maximum eingestellt, ich will nicht, dass das Programm für 10 Jahre einfriert: P Und auch zu Erleichtern Sie das Drücken der "Stop" -Taste, wodurch der Timer abgebrochen wird und der Benutzer auf die anderen Tasten erneut zugreifen kann (Da alle Tasten außer "stop" auf "start" klicken, kann nicht geklickt werden) ~ –

+0

Ihre Implementierung von 'doInBackground () 'ist falsch synchronisiert; Manipulieren Sie Swing-GUI-Objekte _only_ im [Ereignisversand-Thread] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). Bitte aktualisieren Sie Ihre Frage, um das [* aktuelle Problem *] zu erklären (http://meta.stackoverflow.com/q/66377/163188). – trashgod

Antwort

1

Verwenden Sie die isCancelled() Methode am Anfang von done(), um zu sehen, ob Sie die Operationen ausführen sollten oder nicht.

+0

Warte, also am Anfang der done() Methode tippe ich sw.isCancelled(), und was danach? Es sollte den Status des SwingWorker zurückgeben, wie kann ich den zurückgegebenen Wert verwenden, um die done() Methode zu stoppen, mit dem Code fortzufahren? Vielen Dank im Voraus! –

+0

Nun, wie Sie sich denken können, 'isCancelled()' gibt einen booleschen Wert zurück. Es würde sehr gut zusammen mit einem 'if' Statement funktionieren. – Kayaman

+0

Also, wenn es "wahr" zurückgibt, gehe ich voran und schreibe: if (sw.isCancelled == wahr) { // Stoppen Sie die Methode } Aber was soll ich anstelle des Kommentars schreiben, um die Methode tatsächlich zu stoppen? –

0

Sie es nicht abbrechen können, aber Sie können es Kurzschluss, so dass es früh beendet. Verwenden Sie ein Flag für den gemeinsamen Status zwischen Ihren Threads, um zu signalisieren.

+0

Also mache ich eine Methode in DoInBackground() aufgerufen? Und diese Methode stoppt die Methode done()? Aber was soll ich in der Methode schreiben? Das war die Frage da oben: D –

Verwandte Themen