Problem mit Swing und Threads


M

michael3939

Hallo,

Ich versuche schon seit längerem ein Problem zu lösen. Ich hoffe Ihr könnt mir dabei helfen.

Und zwar möchte ich eine JProgressBar im Indeterminate-Modus während einer größeren Berechnung anzeigen. Nach der Berechnung soll die JProgressBar dann verschwinden und der nachfolgende Code ausgeführt werden. Der nachfolgende Code soll also warten bis die größere Berechnung fertig ist und erst dann ausgeführt werden.

Ich habe das Problem in einem kleinen Beispielprogramm isoliert:

In dieser Klasse wird die Berechnung durch Drücken des Button gestartet. Es ist sehr wichtig, dass "further processsing" erst beginnt, wenn die StartThreads beendet sind.
Code:
package swingThreadTest;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;

public class Test {

	
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setSize(800, 600);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		final JButton button = new JButton("Click");
		frame.add(button);
		
		ActionListener listener = new ActionListener(){
			
			public void actionPerformed(ActionEvent e) {
				Click clickClass = new Click(button);
				clickClass.clicked();
			}				
		};
		
		button.addActionListener(listener);
		
		frame.setVisible(true);
		
	}
}
class Click {
	
	JButton button;

	public Click(JButton aButton){
		button = aButton;
	}
	
	public void clicked() {
		//Start threads
		StartThreads startThreads = new StartThreads(this, button);
		startThreads.run();
		
		//Further processing
		
		System.out.println();
		for (int i= 0; i < 20; i++){
			System.out.println("Further processing...");
		}
	}

}

Started die Threads für die Berechnung und die ProgressBar.
Code:
package swingThreadTest;

import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;

public class StartThreads extends Thread implements Observer{

	ProgressTab progressTab;
	Calculation calc;
	
	JButton button;
	Click click;
	
	public StartThreads(Click click, JButton button) {
		this.click = click;
		this.button = button;
	}
	
	public void run() {
		progressTab = new ProgressTab(this, this.button);		
		calc = new Calculation(this);
		
		Thread thread1 = new Thread(progressTab);
		thread1.start();
		
		Thread thread2 = new Thread(calc);
		thread2.run();
	}
	
	public void update(Observable o, Object arg) {
		progressTab.destroy();
	}
}

Hier läuft die größere Berchnung
Code:
package swingThreadTest;

import java.util.Observable;

public class Calculation extends Observable implements Runnable{
		
	public Calculation(StartThreads startThreads){
		this.addObserver(startThreads);
	}
	
	public void run() {
		System.out.println("Calculation started.");
		for (int i = 0; i < 100000; i++){
			System.out.println(i);
		}
		System.out.println("Calculation finished.");
		this.setChanged();
		this.notifyObservers();
	}

}

Erstellt die Progressbar.
Code:
package swingThreadTest;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Observable;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class ProgressTab extends Observable implements Runnable{

	private JButton parent;
	private JPanel panel = new JPanel();
	private JDialog waitingDialog = new JDialog(new JFrame(),
			"Please wait while calculating", true);

	public ProgressTab(StartThreads startThreads, JButton parent) {
		this.parent = parent;
		this.addObserver(startThreads);
	}
	

	public void run() {
		
		JProgressBar progressBar = new JProgressBar(0, 100);
		waitingDialog.setAlwaysOnTop(true);
		waitingDialog.setModal(true);
		waitingDialog.getContentPane().setLayout(new BorderLayout());
		waitingDialog.setSize(new Dimension(400, 60));
		waitingDialog.setLocationRelativeTo(parent);
		progressBar.setLayout(new FlowLayout());
		progressBar.setIndeterminate(true);
		progressBar.setVisible(true);
		progressBar.setStringPainted(false);
		panel.add(progressBar);
		waitingDialog.getContentPane().add(panel, BorderLayout.CENTER);
		waitingDialog.addNotify();
		waitingDialog.setVisible(true);
				
	}

	public boolean isWaitingDialogVisible(){
		return waitingDialog.isVisible();
	}
	
	public void destroy() {
		waitingDialog.setVisible(false);
		waitingDialog.dispose();
		
	
	}

}

Ich habe es bis jetzt geschafft "further processing" auf des Ende der Berechnung warten zu lassen. Dann ist allerdings der Balken der ProgressBar nicht sichtbar (GUI blockiert).
Davor habe ich es geschafft den Balken für die Berechnung anzuzeigen. In dem Fall hat allerdings "further processing" nicht gewartet bis die Berechnung fertig ist.

Jetzt bräuchte ich die Kombination aus beiden und hoffe Ihr könnt mir helfen.

Vielen Dank und Gruesse,
Michael
 
M

michael3939

Das Problem hat sich erledigt.
Ich konnte es mit SwingWorker lösen.

Trotzdem Danke für die zahlreichen Antworten :-(!

Gruss,
Michael
 

Neue Beiträge