2015-09-26 1 views
1

essayer de faire une partie de l'application Java Swing, qui devrait faire:application minuterie à l'intérieur SwingWorker Java Swing ne fonctionne pas

  • quand un bouton est cliqué, prend valeur de l'utilisateur (entier) de « minutes » de un champ de texte;
  • instancie et objet qui est en fait un thread SwingWorker, qui va démarrer un compte à rebours à zéro utilisateur "minutes" puis effectuer une action (lancer un autre JFrame) dans done(), après que doInBackground() se termine;

Je mis des impressions sur certains points dans le code et il semble que le code prend minutes d'entrée de textField, passe au constructeur en classe de compte à rebours, mais exécute simplement fait(), sans courir doInBackground() premier .

Si quelqu'un a un indice pourquoi est-ce que cela se produit, je serais reconnaissant, j'ai essayé toutes mes idées et rien ne fonctionne.

Voici la première partie, le code du bouton:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { 

userCountTime = Integer.parseInt(jTextField2.getText()); 
     userCountTime = userCountTime * 60; 
     System.out.println("Preuzeto iz dugmeta " + userCountTime); 

     if (jRadioButton2.isSelected()){ 
      Countdown countDown= new Countdown (userCountTime); 
} 

Voici le compte à rebours de la classe:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.SwingWorker; 
import javax.swing.Timer; 

/** 
* 
* @author Glupko 
*/ 
public class Countdown extends SwingWorker{ 
    public Timer timer; 
    static int userCountTime; 
    static ActionListener timerListener; 

    //Constructor 
     public Countdown (int userCountTime){ 
     Countdown.userCountTime = userCountTime; 
     System.out.println("In constructor: " + Countdown.userCountTime); 
     this.execute(); 
     } 

    @Override 
    protected Object doInBackground() throws Exception { 
     //defining listener 
     timerListener = new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent actionEvent) { 
        System.out.println("In action performed value is: " + userCountTime); 

        //for each tick we subtract 1, every second 
        while (userCountTime >= 0){ 
         userCountTime--; 
        System.out.println("In actionPerformed there is number of seconds: " + userCountTime);} 
       timer = new Timer(1000, timerListener); 
       //start timer 
       timer.start(); 
       }};} 
    @Override 
      protected void done(){ 
       System.out.println("From done: timer elapsed"); 
       ChangingWindow window = new ChangingWindow(); 
       } 
     } 

Un grand merci à l'avance!

+0

1) Vous ne devriez pas démarrer un minuteur Swing à partir de la méthode 'doInBackground' de SwingWorker. Cela va à l'encontre de tous les objectifs, car une minuterie d'oscillation doit être exécutée sur le thread d'événement Swing ou EDT. 2) La méthode done de votre SwingWorker sera appelée immédiatement puisque le 'timer.start()' est non-bloquant –

+0

Merci Hovercraft Full Of Eels, je l'ai fonctionné :) Juste pour la curiosité - dans mon cas quand la minuterie fonctionne tout les boutons sont bloqués et l'application attend juste la fin de la minuterie et c'est bien. Dans le cas d'une application plus importante, cela bloquerait l'EDT entière, n'est-ce pas? Comment pourrais-je mettre en œuvre le minuteur pour une tâche très spécifique dans ce cas? Encore une fois, merci beaucoup pour votre aide! – junior

+0

Si cela est fait correctement, le temporisateur ** ne devrait pas ** bloquer. Avez-vous d'autres codes qui bloquent l'EDT et que nous ne connaissons pas? –

Répondre

2
  1. Vous ne devriez pas être à partir d'une minuterie Swing dans une méthode de SwingWorker doInBackground. Cela va à l'encontre de tous les objectifs, car une minuterie d'oscillation doit être exécutée sur le thread d'événement Swing ou EDT.
  2. La méthode done de SwingWorker sera appelée immédiatement puisque le timer.start() est non-bloquant.

Au lieu de se débarrasser du SwingWorker et simplement utiliser le Timer seul.

Pour une aide plus complète sur le code, veuillez créer et poster votre minimal code example program pour nous permettre de l'examiner, de le tester et éventuellement de le résoudre.

par exemple,.

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Arrays; 
import javax.swing.*; 

public class CountDownTest extends JPanel { 
    private static final Integer[] SECONDS = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 

    private JSpinner secondsSpinner = new JSpinner(new SpinnerListModel(Arrays.asList(SECONDS))); 

    public CountDownTest() { 
     add(secondsSpinner); 
     add(new JButton(new StartCountDownAction(this, "Start Count Down"))); 
    } 

    public int getSecondsSpinnerValue() { 
     return (Integer) secondsSpinner.getValue(); 
    } 

    private static void createAndShowGui() { 
     CountDownTest mainPanel = new CountDownTest(); 

     JFrame frame = new JFrame("CountDownTest"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

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

class StartCountDownAction extends AbstractAction { 
    private CountDownTest countDownTest; 
    private Timer timer; 

    public StartCountDownAction(CountDownTest countDownTest, String name) { 
     super(name); 
     this.countDownTest = countDownTest; 
     int mnemonic = (int) name.charAt(0); 
     putValue(MNEMONIC_KEY, mnemonic); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (timer != null && timer.isRunning()) { 
      // don't start a new Timer when one is running 
      return; 
     } 
     int seconds = countDownTest.getSecondsSpinnerValue(); 
     timer = new Timer(seconds * 1000, new TimerListener(countDownTest)); 
     timer.setRepeats(false); 
     timer.start(); 
    } 
} 

class TimerListener implements ActionListener { 
    private CountDownTest countDownTest; 

    public TimerListener(CountDownTest countDownTest) { 
     this.countDownTest = countDownTest; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     JOptionPane.showMessageDialog(countDownTest, "Timer Done!"); 
    } 
}