2012-04-30 19 views
5

Tengo varias clases que extienden el SwingWorker. Lo que deseo lograr es ejecutar cada clase una tras otra (sin ejecutar la siguiente clase en el método de la clase anterior). Por ejemplo, digamos que tengo:java - ejecuta cada clase SwingWorker una tras otra

ClassSwingW1 csw1 = new ClassSwingW1(); 
csw1.execute; 

ClassSwingW2 csw2 = new ClassSwingW2(); 
csw2.execute; 

ClassSwingW3 csw3 = new ClassSwingW3(); 
csw3.execute; 

y etc

public class ClassSwingW1 extends SwingWorker<Void, Void> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     //do something 

     return null; 
    } 

} 

public class ClassSwingW2 extends SwingWorker<Void, Void> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     //do something 

     return null; 
    } 

} 

public class ClassSwingW3 extends SwingWorker<Void, Void> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     //do something 

     return null; 
    } 

} 

Quiero que el CSW2 a ejecutar después CSW1 está hecho, y csw3 para ejecutar después CSW2 está hecho. No quiero que se ejecuten al al mismo tiempo. ¿Cómo podría lograr esto? Gracias

+2

¿Es obligatorio el uso de subclases de 'SwingWorker'? Es relevante –

Respuesta

3

Puede usar get() method en lugar de execute() - se bloqueará hasta que el SwingWorker termine su trabajo. Solo asegúrate de no llamarlo desde el EDT.

extracto de Javadoc:

Waits si es necesario para el cómputo para completar, y después recupera su resultado. Nota: al llamar get al Event Dispatch Thread, se bloquean todos los eventos, incluidos los repintados, hasta que se complete este SwingWorker.

+0

[razones para el uso del método get()] (http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundsexception-from-future-and-swingworker-if-threa) – mKorbel

3
  • estaría sugiero mirar Executor invocar una instancia SwingWorker, escuchando de PropertyChangeListener

  • favor read carrefully this thread, especialmente la respuesta por @trashgod

Executor & SwingWorker & PropertyChangeListener & Swing GUI

enter image description here

enter image description here

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.List; 
import java.util.Random; 
import java.util.concurrent.Executor; 
import java.util.concurrent.Executors; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.Timer; 
import javax.swing.border.EmptyBorder; 

public class ExecutorAndSwingWorker2 { 

    private JFrame frame = new JFrame(); 
    private JButton button1; 
    private JButton button2; 
    private JButton button3; 
    private JButton button4; 
    private JPanel buttonPanel = new JPanel(); 
    private Executor executor = Executors.newCachedThreadPool(); 
    private javax.swing.Timer timer1; 
    private javax.swing.Timer timer2; 
    private javax.swing.Timer timer3; 
    private javax.swing.Timer timer4; 
    private Random random = new Random(); 

    public ExecutorAndSwingWorker2() { 
     button1 = new JButton(" Executor + SwingWorker Thread No.1 "); 
     button1.setFocusable(false); 
     button2 = new JButton(" Executor + SwingWorker Thread No.2 "); 
     button3 = new JButton(" Executor + SwingWorker Thread No.3 "); 
     button4 = new JButton(" Executor + SwingWorker Thread No.4 "); 
     buttonPanel = new JPanel(); 
     buttonPanel.setBorder(new EmptyBorder(15, 15, 15, 15)); 
     buttonPanel.setLayout(new GridLayout(2, 2, 20, 20)); 
     buttonPanel.add(button1); 
     buttonPanel.add(button2); 
     buttonPanel.add(button3); 
     buttonPanel.add(button4); 
     frame.setTitle("Shaking Button Demo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLayout(new BorderLayout()); 
     frame.add(buttonPanel); 
     frame.setPreferredSize(new Dimension(700, 170)); 
     frame.setLocation(150, 100); 
     frame.pack(); 
     frame.setVisible(true); 
     executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT 
    } 

    private void startButton1() { 
     System.out.println("Starting long Thread == startButton1()"); 
     try { 
      Thread.sleep(15000); 
     } catch (InterruptedException ex) { 
     } 
    } 

    private void startButton2() { 
     System.out.println("Starting long Thread == startButton2()"); 
     try { 
      Thread.sleep(17500); 
     } catch (InterruptedException ex) { 
     } 
    } 

    private void startButton3() { 
     System.out.println("Starting long Thread == startButton3()"); 
     try { 
      Thread.sleep(12500); 
     } catch (InterruptedException ex) { 
     } 
    } 

    private void startButton4() { 
     System.out.println("Starting long Thread == startButton4()"); 
     try { 
      Thread.sleep(20000); 
     } catch (InterruptedException ex) { 
     } 
    } 

    private void colorAction1() { 
     timer1 = new Timer(1000, new AbstractAction() { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       random = new Random(); 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         button1.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128))); 
         button1.validate(); 
         button1.repaint(); 
        } 
       }); 
      } 
     }); 
     timer1.setDelay(500); 
     timer1.setRepeats(true); 
     timer1.start(); 
    } 

    private void colorAction2() { 
     timer2 = new Timer(1200, new AbstractAction() { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       random = new Random(); 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         button2.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128))); 
         button2.validate(); 
         button2.repaint(); 
        } 
       }); 
      } 
     }); 
     timer2.setDelay(500); 
     timer2.setRepeats(true); 
     timer2.start(); 
    } 

    private void colorAction3() { 
     timer3 = new Timer(1400, new AbstractAction() { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       random = new Random(); 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         button3.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128))); 
         button3.validate(); 
         button3.repaint(); 
        } 
       }); 
      } 
     }); 
     timer3.setDelay(500); 
     timer3.setRepeats(true); 
     timer3.start(); 
    } 

    private void colorAction4() { 
     timer4 = new Timer(1600, new AbstractAction() { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       random = new Random(); 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         button4.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128))); 
         button4.validate(); 
         button4.repaint(); 
        } 
       }); 
      } 
     }); 
     timer4.setDelay(500); 
     timer4.setRepeats(true); 
     timer4.start(); 
    } 

    private void endButton1() { 
     timer1.stop(); 
     button1.setBackground(null); 
     System.out.println("Long Thread Ends == startButton1()"); 
     executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton3")); // non on EDT 
    } 

    private void endButton2() { 
     timer2.stop(); 
     button2.setBackground(null); 
     System.out.println("Long Thread Ends == startButton2()"); 
    } 

    private void endButton3() { 
     timer3.stop(); 
     button3.setBackground(null); 
     System.out.println("Long Thread Ends == startButton3()"); 
     executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton2")); // non on EDT 
     executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton4")); // non on EDT 
    } 

    private void endButton4() { 
     timer4.stop(); 
     button4.setBackground(null); 
     System.out.println("Long Thread Ends == startButton4()"); 
     executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT 
    } 

    private class MyTask extends SwingWorker<Void, Integer> { 

     private String str; 
     private String namePr; 
     private JDialog dialog = new JDialog(); 

     MyTask(String str) { 
      this.str = str; 
      addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr)); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      if (str.equals("startButton1")) { 
       colorAction1(); 
       startButton1(); 
      } else if (str.equals("startButton2")) { 
       colorAction2(); 
       startButton2(); 
      } else if (str.equals("startButton3")) { 
       colorAction3(); 
       startButton3(); 
      } else if (str.equals("startButton4")) { 
       colorAction4(); 
       startButton4(); 
      } 
      return null; 
     } 

     @Override 
     protected void process(List<Integer> progress) { 
      System.out.println(str + " " + progress.get(progress.size() - 1)); 
     } 

     @Override 
     protected void done() { 
      if (str.equals("startButton1")) { 
       endButton1(); 
      } else if (str.equals("startButton2")) { 
       endButton2(); 
      } else if (str.equals("startButton3")) { 
       endButton3(); 
      } else if (str.equals("startButton4")) { 
       endButton4(); 
      } 
     } 
    } 

    private class SwingWorkerCompletionWaiter implements PropertyChangeListener { 

     private JDialog dialog; 
     private String str; 
     private String namePr; 

     SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) { 
      this.dialog = dialog; 
      this.str = str; 
      this.namePr = namePr; 
     } 

     @Override 
     public void propertyChange(PropertyChangeEvent event) { 
      if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) { 
       System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue()); 
      } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.PENDING == event.getNewValue()) { 
       System.out.println("Thread Status with Mame :" + str + ", SwingWorker Status is " + event.getNewValue()); 
      } else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.STARTED == event.getNewValue()) { 
       System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue()); 
      } else { 
       System.out.println("Thread Status with Name :" + str + ", Something wrong happends "); 
      } 
     } 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ExecutorAndSwingWorker2 executorAndSwingWorker = new ExecutorAndSwingWorker2(); 
      } 
     }); 
    } 
} 

con salida de PropertyChangeListener

Starting long Thread == startButton1() 
Thread Status with Name :startButton1, SwingWorker Status is STARTED 
Long Thread Ends == startButton1() 
Thread Status with Name :startButton1, SwingWorker Status is DONE 
Starting long Thread == startButton3() 
Thread Status with Name :startButton3, SwingWorker Status is STARTED 
Long Thread Ends == startButton3() 
Thread Status with Name :startButton3, SwingWorker Status is DONE 
Starting long Thread == startButton2() 
Starting long Thread == startButton4() 
Thread Status with Name :startButton2, SwingWorker Status is STARTED 
Thread Status with Name :startButton4, SwingWorker Status is STARTED 
Long Thread Ends == startButton2() 
Thread Status with Name :startButton2, SwingWorker Status is DONE 
Long Thread Ends == startButton4() 
Thread Status with Name :startButton4, SwingWorker Status is DONE 
Starting long Thread == startButton1() 
Thread Status with Name :startButton1, SwingWorker Status is STARTED 
Long Thread Ends == startButton1() 
Thread Status with Name :startButton1, SwingWorker Status is DONE 
Starting long Thread == startButton3() 
Thread Status with Name :startButton3, SwingWorker Status is STARTED 
Long Thread Ends == startButton3() 
Starting long Thread == startButton2() 
Thread Status with Name :startButton3, SwingWorker Status is DONE 
Starting long Thread == startButton4() 
Thread Status with Name :startButton2, SwingWorker Status is STARTED 
Thread Status with Name :startButton4, SwingWorker Status is STARTED 
Long Thread Ends == startButton2() 
Thread Status with Name :startButton2, SwingWorker Status is DONE 
BUILD SUCCESSFUL (total time: 1 minute 34 seconds) 
2

Memory Consistency Properties resume el JLS: "Cada acción en un hilo ocurre -antes de cada acción en ese hilo que viene más tarde en el orden del programa". Simplemente vuelva a factores de cada trabajador doInBackground() en un método separado, y llame a cada uno en secuencia:

@Override 
protected Void doInBackground() throws Exception { 
    doCsw1(); 
    doCsw2(); 
    doCsw3(); 
    return null; 
} 
2

Cómo sobre el uso Executors.newSingleThreadExecutor()

import java.awt.*; 
import java.awt.event.*; 
import java.beans.*; 
import java.util.*; 
import java.util.concurrent.*; 
import javax.swing.*; 

public class SingleThreadExecutorTest { 
    private Executor executor; 
    private final Box box = Box.createVerticalBox(); 
    public JComponent makeUI() { 
    executor = Executors.newSingleThreadExecutor(); //.newCachedThreadPool(); 
    box.setBorder(BorderFactory.createEmptyBorder(8,8,8,8)); 
    JPanel p = new JPanel(new BorderLayout()); 
    p.add(new JButton(new AbstractAction("add") { 
     @Override public void actionPerformed(ActionEvent evt) { 
     doSomethingUseful(); 
     } 
    }), BorderLayout.SOUTH); 
    p.add(new JScrollPane(box)); 
    return p; 
    } 
    private void doSomethingUseful() { 
    JProgressBar bar = new JProgressBar(0, 100); 
    box.add(bar); box.add(Box.createVerticalStrut(8)); 
    box.revalidate(); 
    SwingWorker<Integer, Void> worker = new SwingWorker<Integer, Void>() { 
     private int sleepDummy = new Random().nextInt(50) + 1; 
     private int lengthOfTask = 120; 
     @Override protected Integer doInBackground() { 
     int current = 0; 
     while(current<lengthOfTask && !isCancelled()) { 
      current++; 
      try { 
      Thread.sleep(sleepDummy); 
      } catch(InterruptedException ie) { 
      break; 
      } 
      setProgress(100 * current/lengthOfTask); 
     } 
     return sleepDummy*lengthOfTask; 
     } 
     @Override protected void done() { 
     try { 
      System.out.println(get()+"ms"); 
     } catch(Exception ignore) { 
      ignore.printStackTrace(); 
     } 
     } 
    }; 
    worker.addPropertyChangeListener(new ProgressListener(bar)); 
    executor.execute(worker); 
    } 
    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new SingleThreadExecutorTest().makeUI()); 
    f.setSize(320, 240); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
class ProgressListener implements PropertyChangeListener { 
    private final JProgressBar progressBar; 
    ProgressListener(JProgressBar progressBar) { 
    this.progressBar = progressBar; 
    this.progressBar.setValue(0); 
    } 
    @Override public void propertyChange(PropertyChangeEvent evt) { 
    String strPropertyName = evt.getPropertyName(); 
    if("progress".equals(strPropertyName)) { 
     progressBar.setIndeterminate(false); 
     int progress = (Integer)evt.getNewValue(); 
     progressBar.setValue(progress); 
    } 
    } 
} 
Cuestiones relacionadas