Fibonacci-Folge status Leiste.

Status
Nicht offen für weitere Antworten.

Dagobert

Bekanntes Mitglied
Ich habe ein Programm geschrieben womit man die Fibonacci-Folge einer Zahl berechnen kann...

da dies durchaus länger dauer kann wollte ich ein Progressbar mit Statusanzeige einbauen... leider sind bis jetzt alle versuche fehlgeschlagen... kann mir wohl jemand einen ansazt geben wie ich eien korrekt laufende ProgressBar hinbekomme.

Also hier schonmal meine Idee...

ich habe eine Progreesbar die von 0 bis 100 geht
dann habe ich ein sleep drin... aber da weis ich nicht die passende zeit die ich einsetzen muss :( :?:
dann wird meine Bar um 1 geupdatet

ist das soweit inordnung? und was muss ich als Zeit für sleep reinpacken?

mfg
Dagobert
 

The_S

Top Contributor
Nein, garantiert nicht. Du musst an bestimmten Punkten der Berechnung die ProgressBar updaten, sonst ist die Fortschrittsanzeige ja vollkommen falsch ...
 

Dagobert

Bekanntes Mitglied
ok thx...

kannst du mir bittte sagen wo ich bei ner Fib-Folge diese Punkte sind, denn ich weis es echt nicht so ganz...

hier ist mein code zum berechnen der fib...
Code:
private int berechnenFib(int n) {
		if (n == 0 || n == 1) {
			return n;
		} else {
			return (berechnenFib(n - 1) + berechnenFib(n - 2));
		}
	}
 
S

SlaterB

Gast
wenn du nicht weißt, wie lange deine Berechnung dauert,
dann kannst du logischereise auch keine Forschrittsanzeige machen..

kannst nebenbei einen Thread laufen lassen, der Sekunden hochzählt

--------

bei so ner Rekursion ist es allgemein möglich:
berechne(n-1) von der Ausgangszahl,
dann hast du grob 50% der Arbeit, dann (n-2)

für feinere Unterteilung musst du eben in ein paar Ebenen tiefer den Zwischenstand anzeigen

-----
wie lange dauert überhaupt diese Berechnung? wie speicherst du eine so große Zahl,
die länger als ein Blinzeln in der Berechnug dauert?
doch wohl nicht in einem int?
 

Dagobert

Bekanntes Mitglied
speichern XD

gar nicht wird mit return in int format zurückgegeben

habs jetzt mal auf Long geändert...

ok soweit so gut... ich muss also in der Rekusion bei jeden neuaufruf meine bar updaten.... aber um was für ein Wert? ich kann den counter wohl schlecht um 1 eínfach hochzählen.... denn dann kommen ein par Prozdent mehr als möglich aus... XD
 

Dagobert

Bekanntes Mitglied
ich weis wie ich so eine bar bedienen, ich weis nur nicht an welcher stelle ich sie im rekusiven aufruf updaten soll -.-
bzw. mit welchen wert
 

The_S

Top Contributor
Da du nciht weißt, wie viele durchläufe du benötigst, kannst du auch keinen normalen Fortschrittsbalken einbauen. Als alternative wäre ein simpler WorkInProgress balken, der dem User anzeigt, dass zumindest noch was gemacht wird.

Ich war mal so frei:

Code:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class WorkInProgress extends JComponent{

	private static final long serialVersionUID = 1L;
	
	private int speed = 50;
	private int pos = 0;
	private int step = 4;
	private boolean workInProgress = false;
	
	private String progressText = null;
	private String noProgressText = null;
	private BufferedImage status = null;
	
	public WorkInProgress() {
		
		progressText = "Work in Progress";
		noProgressText = "Nothing in Progress";
		status = new BufferedImage(73, 20, BufferedImage.TYPE_INT_ARGB);
		setForeground(Color.red);
		setBackground(Color.WHITE);
		setFont(new Font("monospaced", Font.BOLD + Font.ITALIC, 11));
		Graphics2D g2d = status.createGraphics();
		g2d.setColor(Color.BLACK);
		for (int i = 0; i < 5; i++) {
			g2d.fillRect(15 * i, 3, 14, 14);
		}
		g2d.dispose();
	}
	
	private void checkProgress() {
		
		new Thread(new Runnable() {
			public void run() {
				boolean leftToRight = true;
				while (isWorkInProgress()) {
					repaint();
					if (leftToRight) {
						pos += step;
						if (getWidth() - status.getWidth() < pos) {
							leftToRight = false;
						}
					}
					else {
						pos -= step;
						if (pos <= 0) {
							leftToRight = true;
						}
					}
					try { 
						Thread.sleep(speed);
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				pos = 0;
				repaint();
			}
		}).start();
	}
	
	public void paintComponent(Graphics g) {
		
		String drawString = null;
		g.setColor(getBackground());
		g.fillRect(0, 0, getWidth(), getHeight());
		g.setColor(getForeground());
		g.setFont(getFont());
		if (isWorkInProgress()) {
			drawString = progressText;
			g.drawImage(status, pos, getHeight() / 2 - status.getHeight() / 2, this);
		}
		else {
			drawString = noProgressText;
		}
		int w = g.getFontMetrics(g.getFont()).stringWidth(drawString);
		int h = g.getFontMetrics(g.getFont()).getHeight();
		g.drawString(drawString, getWidth() / 2 - w / 2, getHeight() / 2 + h / 4);
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public boolean isWorkInProgress() {
		return workInProgress;
	}

	public void setWorkInProgress(boolean workInProgress) {
		this.workInProgress = workInProgress;
		if (isWorkInProgress()) {
			checkProgress();
		}
	}

	public String getNoProgressText() {
		return noProgressText;
	}

	public void setNoProgressText(String noProgressText) {
		this.noProgressText = noProgressText;
	}

	public String getProgressText() {
		return progressText;
	}

	public void setProgressText(String progressText) {
		this.progressText = progressText;
	}

	public BufferedImage getStatus() {
		return status;
	}

	public void setStatus(BufferedImage status) {
		this.status = status;
	}

	public int getStep() {
		return step;
	}

	public void setStep(int step) {
		this.step = step;
	}
	
	public static void main(String[] args) {
		
		JFrame frame = new JFrame();
		frame.setSize(200, 50);
		WorkInProgress wip = new WorkInProgress();
		frame.add(wip);
		frame.setVisible(true);
		wip.setWorkInProgress(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

Zum Testen direkt ausführbar ...
 

The_S

Top Contributor
Da gibts nix zu verstehen, du ersetzt deine ProgressBar einfach durch diese Componente und rufst anschließend setWorkInProgress(true) auf ;) .
 
R

Roar

Gast
erhöhe doch für jede berechnete zahl den wert deiner bar um 1, voraussetzung ist natürlich dass du den maximalwert der bar auf den wert der zu berechnenden werte gesetzt hast.
bei *deiner* fib implementierung hast du dann auch genug zu gucken für eine zahl im integer bereich ;)
 

Leroy42

Top Contributor
Vergiß es!

Mit den Informationen alleine, die deine rekursive Funktion hergibt,
wirst du nie die Gesamtzeit erkennen können, die du ja
für eine Fortschrittsanzeige benötigst, ohne den Fibonacci-Wert selbst
zuvor berechnet zu haben.

Was eventuell ginge, wäre eine Bezugnahme auf den Gesamtwert,
indem du ihn dir in situ berechnest.

5f914ec0170479d746bc035c9619e6f6.png


Aber auch das wäre unverhältnismäßig kompliziert,
und würde deiner Idee grundsätzlich widersprechen.
 
S

SlaterB

Gast
eine Progressbar muss doch nicht genau sein,
und auch nicht die Endzeit schon am Anfang anzeigen

was spricht dagegen, für die 8 höchsten Rekursionsschritte je eine Zeit von 1/8 anzunehmen?
wenns länger dauert, dann eben mehr Schritte,
kann man ja grob an der Ausgangszahl abschätzen
 

Leroy42

Top Contributor
SlaterB hat gesagt.:
was spricht dagegen, für die 8 höchsten Rekursionsschritte je eine Zeit von 1/8 anzunehmen?

Ach ja!?

Dann zeig' doch mal wie Dagobert das in seine Fibbonacci-Methode einbauen soll.
Code:
private int berechnenFib(int n) { 
      if (n == 0 || n == 1) { 
         return n; 
      } else { 
         return (berechnenFib(n - 1) + berechnenFib(n - 2)); 
      } 
   }

Viel Spaß! :cool:

Das Problem ist doch, daß diese Methode, je Aufruf, nur
die Information über das aktuelle n besitzt.
 
S

SlaterB

Gast
ja, 5 Min. programmieren muss man schon ;)
z.B. eine zweite 20-zeilige Operation, die einen Tiefen-Parameter mitbekommt + Grenze,
ab dieser Grenze wird die normale Operation aufgerufen,
so dass so gut wie kein Overhead entsteht

ist für einen Anfänger nicht leicht, aber 'vergiss es' klingt so fundamental,
als wenn das grundsätzlich dem Rekursionsprinzip widerspricht,
dabei ein Klacks

edit: baut natürlich immer noch auf der Grundannahme eines binären Baums mit gleicher Suchzeit für jeden Teilbaum auf,
sonst schwieriger, stimmt,
aber Exemplarvariablen gibts dann auch noch..
 
R

Roar

Gast
wieso soll die progressbar denn immer gleichschnell fortschreiten?
je lägner die operation, desto langsamer der balken: it's not a bug it's a feature :)
 

Leroy42

Top Contributor
SlaterB hat gesagt.:
ja, 5 Min. programmieren muss man schon ;)

Dann bitte ich dich hiermit ganz offiziell, diese 5++ Minuten doch
mal zu erübrigen, und einen Ansatz zu entwickeln.

Ich selbst sehe mich zwar nicht als Anfänger, mein
jahrelanges rekursives Gefühl sagt mir jedoch,
das es da grundsätzlich Schwierigkeiten gibt. ???:L

SlaterB hat gesagt.:
kann man ja grob an der Ausgangszahl abschätzen
Das halte ich für ein Gerücht.

Entweder geht es exakt oder eben gar nicht.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben