# SwingWorker Thread pausieren



## Liathne (31. Okt 2007)

Guten Morgen zusammen,

ich habe eine GUI von welcher ein SwingWorker Thread gestartet wird. Während der SwingWorker arbeitet möchte ich einen Button einblenden um diesen Thread gegebenenfalls zu pausieren oder zu beenden. 
Das Erscheinen der Buttons zu realisieren ist kein Problem, jedoch fehlt mir zu der Möglichkeit den SwingWorker zu pausieren oder zu beenden momentan jeder Ansatz.

Vielen Dank für Eure Hilfe.

   Liathne


----------



## Lex (31. Okt 2007)

Morgen,

eine einfache Lösung um das zu realisieren wären zwei geschachtelte while-Schleifen in deiner doInBackground.


```
while (alive){
         while(!pause){
            //Verarbeitung
         }
}
```

Dazu dann noch zwei Methode in deinem SwingWorker, die du aus deiner Oberfläche aufrufen kannst.


```
public void kill(){
      alive = false;
}
   
public void tooglePause(){
      pause = !pause;
}
```

Is zugegeben nicht die optimalste Lösung sollte aber den Zweck erfüllen ;-)

MfG
Lex


----------



## JuVman5KL (19. Jan 2009)

Hallo Lex,
um das Thema nochmal aufzugreifen, muss ich leider sagen, dass der Ansatz bei dem folgenden Programm nicht funktioniert (GUI mit zwei Buttons zum Starten um Stoppen des SwingWorkers, als rechenintensive Aufgabe werden alle Verzeichnisse und Dateien des Systems ausgegeben).


```
import java.awt.BorderLayout;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class NewClass extends JFrame{
    static DefaultListModel listModel = new DefaultListModel();
    static boolean alive = true;

    JButton jButton1 = new JButton("SwingWorker starten");
    JButton jButton2 = new JButton("SwingWorker beenden");

    public NewClass() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        listModel.addElement("abc");
        JList jList1 = new JList();
        jList1.setModel(listModel);
        jList1.setDoubhttp://www.buecherbillig.de/category/Programmierung_Java.html?ref=38leBuffered(true);
        JScrollPane jScrollPane1 = new JScrollPane(jList1);
        
        add(jButton1, BorderLayout.NORTH);
        add(jButton2, BorderLayout.SOUTH);
        add(jScrollPane1, BorderLayout.CENTER);

        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt){
                worker.execute();
            }
        });

        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt){
                worker.kill();
            }
        });
    }

    public static void nextDirectory(String directory) {
        File firstDirectory = new File(directory);
        File[] firstDirectoryArray = firstDirectory.listFiles();
        for(int a = 0; a < firstDirectoryArray.length; a++){
            final File[] firstDirectoryArray1 = firstDirectoryArray;
            final int a1 = a;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    listModel.addElement(firstDirectoryArray1[a1]);
                }
            });

            if(firstDirectoryArray[a].isDirectory() && firstDirectoryArray[a].list() != null){
                nextDirectory(firstDirectoryArray[a].toString());
            }
        }
    }
    
    static class Worker extends SwingWorker{
        @Override
        protected Void doInBackground() {
            while(alive){
                nextDirectory("C:\\Users");
            }
            return null;
        }

        public void kill(){
            alive = false;
        }
    }

    Worker worker = new Worker();

    public static void main(String[] args) {
        NewClass window = new NewClass();
        window.setVisible(true);
        window.setSize(300, 300);
    }
}
```

Ich hoffe, dass das Thema jetzt als aktuell angezeigt wird. Für Lösungsvorschläge und -ansätze bin ich wie immer sehr dankbar.

Viele Grüße


----------



## Gast (20. Jan 2009)

Naja der SwingWorker ist eigentlich dafür da etwas im Hintergrund durchzuführen und sich zu melden wenn es fertig ist.

Benutz doch lieber nen Thread.


----------



## Ebenius (20. Jan 2009)

Lex hat gesagt.:
			
		

> Morgen,
> 
> eine einfache Lösung um das zu realisieren wären zwei geschachtelte while-Schleifen in deiner doInBackground.
> 
> ...


 Worum geht's hier? Den Prozessor mit einem pausierten Thread so gut wie möglich auszulasten? ;-)

Ebenius


----------



## Marco13 (20. Jan 2009)

Wenn nach dem "Verarbeitung"-Block  irgendwo ein "wait()" vorkommt, nicht unbedingt :wink:


----------



## Ebenius (20. Jan 2009)

Und wenn noch ein notify steht... Und beides auf dem selben Objekt... Und natürlich in je einem synchronized-Block... Und wenn das Beispiel dann natürlich ganz anders aussieht... 

Ebenius


----------



## JuVman5KL (20. Jan 2009)

Hallo Gast, der du mir empfohlen hast, einen Thread zu benutzen,
wenn ich in der Klasse Worker nun Thread statt SwingWorker ableite und die doInBackground()-Methode durch run() ersetze (ansonsten alles wie vorher (abgesehen von Zeile 25)), habe ich ebenso meine Probleme, den Thread mit 

```
<Thread-Objekt>.interrupt()
<Thread-Objekt> = null;
```

oder einer Methode wie z. B.

```
public void kill() {
    alive = false;
}
```


```
import java.awt.BorderLayout;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class NewClass extends JFrame{
    static DefaultListModel listModel = new DefaultListModel();
    static boolean alive = true;

    JButton jButton1 = new JButton("Thread starten");
    JButton jButton2 = new JButton("Thread beenden");

    public NewClass() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        listModel.addElement("abc");
        JList jList1 = new JList();
        jList1.setModel(listModel);
        jList1.setDoubleBuffered(true);
        JScrollPane jScrollPane1 = new JScrollPane(jList1);
        
        add(jButton1, BorderLayout.NORTH);
        add(jButton2, BorderLayout.SOUTH);
        add(jScrollPane1, BorderLayout.CENTER);

        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt){
                Worker worker1 = new Worker();
                worker1.start();
            }
        });

        jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt){
                kill();
            }
        });
    }

    public void kill(){
        alive = false;
    }

    public static void nextDirectory(String directory) {
        File firstDirectory = new File(directory);
        File[] firstDirectoryArray = firstDirectory.listFiles();
        for(int a = 0; a < firstDirectoryArray.length; a++){
            final File[] firstDirectoryArray1 = firstDirectoryArray;
            final int a1 = a;
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    listModel.addElement(firstDirectoryArray1[a1]);
                }
            });

            if(firstDirectoryArray[a].isDirectory() && firstDirectoryArray[a].list() != null){
                nextDirectory(firstDirectoryArray[a].toString());
            }
        }
    }
    
    private class Worker extends Thread {

        @Override
        public void run() {
            while(alive){
                nextDirectory("C:\\Users");
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable () {
            public void run() {
                NewClass window = new NewClass();
                window.setVisible(true);
                window.setSize(300, 300);
            }
        });
    }
}
```

Wie kann ich mich über Threads informieren? Das Java-Tutorial (http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html) und die Infos auf http://openbook.galileocomputing.de/javainsel7/ sind nicht sehr ergiebig.


----------



## JuVman5KL (23. Jan 2009)

Hallo zusammen,
ich bin bei dem Problem leider noch nicht weiter gekommen, brauche die Lösung des Problems aber immer noch. Ich habe einiges gelesen. Im Wikibook Java (http://de.wikibooks.org/wiki/Java_Standard:_Threads#Threads_anhalten) werden die Möglichkeiten, einen Thread zu beenden ja aufgeführt, weitere habe ich auch nicht gefunden.


----------



## Gast2 (23. Jan 2009)

nur mal so nebenbei bei buttons benutzt man ActionsListener und keine MouseListener...


----------



## JuVman5KL (23. Jan 2009)

Ja, das stimmt. Das wusste ich bis jetzt noch nicht. Allerdings löst der Einsatz von ActionListenenern das Problem nicht. Der jButton1, der den Thread startet, funktioniert immerhin auch mit einem MouseListener.

Für weitere Hilfe bin ich sehr dankbar.

Viele Grüße


----------



## Gast2 (23. Jan 2009)

hab deine klasse bischen gekürzt so funktionierts... kannst ja auf dein bsp. anwenden...

```
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class NewClass extends JFrame{

    private boolean alive = true;

    JButton jButton1 = new JButton("Thread starten");
    JButton jButton2 = new JButton("Thread beenden");

    public NewClass() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        add(jButton1, BorderLayout.NORTH);
        add(jButton2, BorderLayout.SOUTH);

        jButton1.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				   new Worker().start();	
			}
        
        });

        jButton2.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				   kill();
			}
        
        });
    }

    public void kill(){
    	System.out.println("Thread beendet");
        alive = false;
    }

   
    private class Worker extends Thread {

        @Override
        public void run() {
            while(alive){
                System.out.println("Thread läuft");
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable () {
            public void run() {
                NewClass window = new NewClass();
                window.setVisible(true);
                window.setSize(300, 300);
            }
        });
    }
}
```


----------



## JuVman5KL (25. Jan 2009)

Hallo SirWayne,
ich bin dir sehr dankbar, dass du dir für das Problem Zeit genommen hast, allerdings hat gerade das Kürzen der Klasse dazu geführt, dass beim Ersetzen der einfachen System.out.println-Anweisung durch die nextDirectory-Methode (die ja in sich nochmal eine SwingUtilities.invokeLater-Anweisung enthält) sich der Thread eben nicht mehr beenden lässt.
Die Klasse sollte aber natürlich auch mit der nextDirectory-Methode laufen.

Falls du oder jemand anders eine Lösung, die auch das Einbinden der nextDirectory-Methode berücksichtigt, meldet euch bitte.

Viele Grüße


----------

