Bessere Aktualisierung eines Frames

  • Themenstarter Themenstarter Gast
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hi,

ich habe folgendes Problem.

Ich habe ein Programm geschrieben, dass relativ viele aufwändige Berechnungen durchführt.
Damit der User nicht denkt, dass das Programm abgestürtzt ist, habe ich ein zweites JFrame erstellt, dass eine ProgressBar anzeigt.
Das Problem ist, die Aktualisierung der ProgressBar wird niicht durchgeführt.
Wie kann ich es machen, dass das getan wird?

So sieht die aufrufende Methode aus:
Code:
                 PixelOfPicture[][] picture = this.picture.getActualPicture();
		
		//initialize the progressbar
		ProgressBar progress = new ProgressBar(numberOfRemovableRows , "Removing horizontal seams");
		progress.setDescription(0, 0);
		
		for(int i = 0; i < numberOfRemovableRows; i++){
			try{
				picture = RemoveSeam.removeSeam(picture,false);
				
				//update the progress bar
				progress.setDescription(0, i);
				progress.setProgressStatus(i);
			}
			catch(UnableToDeleteSeamException UTDSE){
				break;
			}
		}
		
		progress.closeProgressbar();
		
		this.picture.setActualPicture(picture);

Die Progress bar sieht wie folgt aus:
Code:
	public ProgressBar(int maximumValue , String headline){
		this.maximumValue = maximumValue;
		
		//configure the frame
		this.progressFrame = new JFrame();
		this.progressFrame.setSize(400, 80);
		this.progressFrame.setVisible(true);
		this.progressFrame.setTitle(headline);
		
		//configure the progress bar
		this.progressBar = new JProgressBar();
		this.progressBar.setMinimum(0);
		this.progressBar.setMaximum(maximumValue);
		this.progressBar.setValue(0);
		this.progressBar.setSize(380, 15);
		
		//configure the panel
		this.progressPanel = new JPanel();
		this.progressPanel.setSize(400, 30);
		
		//configure the label
		this.progressLabel = new JLabel();
		
		//link all components
		this.progressFrame.add(this.progressBar);
		this.progressPanel.add(this.progressLabel);
		this.progressFrame.add(this.progressPanel);
		
		//set all positions
		this.progressBar.setLocation(5, 25);
		this.progressPanel.setLocation(0, 0);
		this.progressLabel.setLocation((400 - this.progressLabel.getWidth())/2, 10);
		
		//set the location of the window
	    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	    this.progressFrame.setLocation((screenSize.width - this.progressFrame.getWidth()) / 2 ,
	    							   (screenSize.height - this.progressFrame.getHeight()) / 2);
	}

	public void setDescription(int description , int i){
		switch(description){
			case 0 : progressLabel.setText("Removed " + i + " of " + this.maximumValue + " seams"); break;
			case 1 : progressLabel.setText("Added " + i + " of " + this.maximumValue + " seams"); break;
			default: progressLabel.setText("No description available");
		}
	}

	public void setProgressStatus(int status){
		this.progressBar.setValue(status);
	}

Ich möchte allerdings nicht alzu viel umschreiben (z.B. durch einen thread oder process).
Gibt es eine andere Möglcihkeit?

Danke für eure Hilfe.
 
1. Die Berechnung in einen Thread packen (ist nicht aufwändig)

2. Bevor der Berechnungsthread gestartet wird, eine Instanz der Klasse Progressbar an diesem
übergeben. (Progressbar als Membervariable in der Berechnungsthread-Klasse)

3 Thread starten

eventuell: - Swingworker.invokeLater einsetzen (ist hier im Forum sicher irgendwo erläutert worden)
- für die Progressbar vielleicht besser JDialog (vielleicht modal ?) verwenden.
 
Das Problem ist, dass der Algorithmus keine feste Arbeitsmenge hat.
Man kann also frei wählen wie häufig er sich wiederholt.
Wie implementiere ich das in einem Thread?
 
Hier ein kleines Beispiel von mir:


Code:
import java.awt.event.*;
import javax.swing.*;

interface ProzessListener {
	public void step(int step);
	public void endProzess();
}

class Progress extends JDialog {
	private JProgressBar progressBar;
	Progress(JFrame frame,int anzahl) {
		super(frame);
		this.progressBar = new JProgressBar();
		this.progressBar.setValue(0);
		this.progressBar.setMaximum(anzahl-1);
		this.progressBar.setSize(380, 250);
		this.add(progressBar);
	
		this.setSize(200, 50);
		this.setLocationRelativeTo(frame);
		this.setVisible(true);
	}

	public void step(int i) {
		this.progressBar.setValue(i);
	}

	public void close() {
		this.dispose();
	}
}

class WorkerThread extends Thread {
	private ProzessListener prozessListener;
	private int anzahl;

	WorkerThread(int anzahl) {
		this.anzahl = anzahl;
	}

	public void addProzessListener(ProzessListener prozessListener) {
		this.prozessListener = prozessListener;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		for (int i = 0; i < anzahl; i++) {
			
			try {
				Thread.sleep(300); // simuliert eine längerdauernde Operation
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			prozessListener.step(i);
		}
		try {
			Thread.sleep(1000); // nach Ende noch 1s warten
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		prozessListener.endProzess();
	}
}

public class MainFrame extends JFrame implements ProzessListener,ActionListener {
	private JButton startbuttun;
	private Progress progress;
	private WorkerThread worker;
	private int anzahl = 10;
	
	MainFrame() {
		startbuttun = new JButton("start");
		startbuttun.addActionListener(this);
		startbuttun.setBounds(0,0,100,20);
	
		this.setLayout(null);
		this.add(startbuttun);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationByPlatform(true);
		this.setSize(300, 100);
		this.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent arg0) {
		// TODO Auto-generated method stub
		progress = new Progress(this,anzahl);
		worker = new WorkerThread(anzahl);
		worker.addProzessListener(this);
		worker.start();
		startbuttun.setEnabled(false);
	}
	
	public void endProzess() {
		// TODO Auto-generated method stub
		progress.close();
		startbuttun.setEnabled(true);
	}

	public void step(int step) {
		// TODO Auto-generated method stub
		progress.step(step);
	}


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new MainFrame();
	}

}


Eigentlich habe ich die Methoden endProzess() usw. im Controller
und die Möglichkeit den Prozess zu beenden (Stop-Button im Progressfenster) .
Habe ich hier aber mal weggelassen.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben