2012-04-30 4 views
5

Ich habe mehrere Klassen, die den SwingWorker erweitern. Was ich erreichen möchte, ist, jede Klasse nacheinander auszuführen (ohne die nächste Klasse in der Done-Methode der vorherigen Klasse auszuführen). Zum Beispiel können sagen, ich habe:java - führe jede SwingWorker-Klasse nacheinander aus

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

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

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

usw.

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; 
    } 

} 

ich die CSW2 wollen, ist auszuführen, nachdem CSW1 getan, und CSW3 auszuführen, nachdem CSW2 erfolgt. Ich will nicht, dass sie gleichzeitig ausführen. Wie würde ich das erreichen? Danke

+2

Verwendung Ist es zwingend notwendig, Subklassen von 'SwingWorker' zu benutzen? Es ist relevant. –

Antwort

3

Sie könnten das get() method anstelle von execute() verwenden - es wird blockieren, bis der SwingWorker seine Arbeit beendet. Stellen Sie nur sicher, dass Sie es nicht vom EDT aus aufrufen.

Javadoc-Extrakt:

Waits bei Bedarf für die Berechnung abgeschlossen ist, und ruft dann das Ergebnis. Hinweis: Durch den Aufruf von get auf dem Event Dispatch Thread werden alle Ereignisse, einschließlich Repaints, so lange blockiert, bis dieser SwingWorker vollständig ist.

+0

[Gründe für die Verwendung der Methode get()] (http://stackoverflow.com/questions/7053865/cant-get-arrayindexoutofboundexception-from-future-and-swingworker-i-threa) – mKorbel

3
  • Ich schlage vor, bei Executor aufrufen, um ein SwingWorker Beispiel aussehen würde, von

    von Property hören
  • bitte read carrefully this thread, vor allem die Antwort von @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(); 
      } 
     }); 
    } 
} 

mit Ausgabe von Property

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 fasst die JLS zusammen: "Jede Aktion in einem Thread passiert-vor jede Aktion in diesem Thread, die später in der Reihenfolge des Programms kommt." Einfach wieder Faktor doInBackground() in einem separaten Verfahren der jeder Arbeiter und jeder in Folge nennen:

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

Wie wäre es 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); 
    } 
    } 
} 
Verwandte Themen