Problem beim Einbau von einem Thread in eine Gui

Status
Nicht offen für weitere Antworten.

Kaleidoskop

Mitglied
Also ich habe ein Programm geschrieben das abhängig von den Eingaben an der Gui Grafiken malt. Die Berechnung der Daten dazu findet in der Gui statt. Diese ruft das die Klasse des Zeichenbrettes auf damit die eigentliche Zeichnung hergestellt wird.

So nun kriege ich es nicht hin, das die Gui nach jedem Zeichnen eine Pause macht und nur das Zeichnen abbricht wenn der Benutzer z.B. eine Taste drückt. Habe bisher auch noch nie was mit Threads zu tun gehabt und somit keine Erfahrung damit.

Habe das Programm radiakel gekürzt und nur die relevanten Dinge dargestellt.

Wüde wenn gerne die Gui komplett als Thread haben. Habe aber keine Ahnung wie ich es umsetzten soll das der Thread nach wie vor auf die Eingaben des Benutztrs reagiert, vor allem da ich diese ja nicht vorhersehen kann.

Worum es hier geht ist folgendes. Der Benutzer drückt einen BUtton und läd eine Grafik bestehend aus einen von ihm gewählten file. In diesem File stehen spezielle Daten drin die nun geladen werden. Diese sollen nun auotamisch komplett bearbeitet werden. Dabei soll das Bild langsam nämlich Strich für Strich entstehen. Zudem soll das Zeichnen auch komplett abgebrochen werden können, ohne das das Programm beendet wird.

Habe verschiedenste Dinge ausprobiert und nichts hat mich weitergebracht. Wenn dann wartete das Programm zwar, malte aber nichts und malte dann am ende alles auf einmal.

Bin für jede Hilfe, Idee oder Anregung dankbar.

Code:
public class Gui extends JFrame implements Runnable{
	Zeichenbrett z;
	
	public Gui(){
		super("Titel");
		z = new Zeichenbrett();
		Thread th = new Thread (this);
		th.start();
	}
	
	public void run(){
		while (true){
		}
	}
	
	public void laden(){
		//Daten werden geladen und stehen als Liste in eingabe
		while(eingabe.hasNext()){
			//Werte abhängig von eingabe berechnet,setzt Daten in Gui um
				zeichnen();
				//soll dann hier eigentlich kurz warten damit der Benutzer das Bild langsam entstehen sieht
und das zeichnen abbrechen kann
		}
	}
	
	public void zeichnen(){
		//Wandelt Koordinaten um etc.
		z.linieMalen(x,y,next.x,next.y);
		z.repaint();
	}
}

Klasse des Zeichenbrettes


Code:
public class Zeichenbrett extends JPanel {
	
	private Graphics2D offlineG;
	private BufferedImage offlineImg; 
	
	public Zeichenbrett(){
		this.setBackground(Color.white);
		this.setPreferredSize(new Dimension(2000,1500));
		this.offlineImg = new BufferedImage(2000,1500,BufferedImage.TYPE_INT_RGB);
		this.offlineG = this.offlineImg.createGraphics();
        }
	
	public void linieMalen(int x,int y,int nextx, int nexty){
		offlineG.drawLine(x,y,nextx,nexty);
	}
	
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(this.offlineImg, null, 0, 0);
	}
}
 
B

Beni

Gast
Einen Thread pausieren kannst du mit "Thread.sleep( Millisekunden )".

Am Zeichenbrett musst du eigenlich nichts mehr verändern, allenfalls ein paar "synchronized" bei den Methoden hinzufügen (das verhindert Fehler, wenn mehrere Threads gleichzeitig auf das Zeichbrett zugreiffen).

Zum Abbrechen: Mach irgendeine Variable, am einfachsten ein boolean. Diese Variable wird vom ladenden Thread alle paar Millisekunden abgefragt, wenn sie verändert wurde, bricht der Thread ab. Die Variable kann dann aus einem anderen Thread gesetzt werden.

Wieso du bei der Gui schon einen Thread im Konstruktur anlegst, weiss ich nicht. Eine einfache Variante: leg den Thread dann an, wenn der Benutzer auf ein Knöpflein gedrückt hat. Dann kannst du den Inhalt der Methode "laden" direkt in die "run" schreiben.
 

Kaleidoskop

Mitglied
Das ich den Thread da anlege war eine meiner Versuche. Also ich dachte ich brauche nur einen Thread. Oder muß ich bei jeder Methode einen extra Thread erzeugen ? Methoden ala sleep, interrupd, is Interrupted etc kenne ich wohl. Hatte hier und da nur immer wieder Probleme mit static Problemen.

Also Laden kann ich nicht in die run schreiben, da ich noch andere Methoden habe die ähnlich aufgerufen werden können. Genau da liegt ja mein Problem. Habe sie nur zur besseren Übersicht weggelassen.

Habe noch andere Methoden die an Hand von benutzer definierten Werten spezielle Grafiken berechnen.
 
B

Beni

Gast
Ach so.

Also, für jede Arbeit einen Thread ist möglich. Ich habe das geschrieben, weil das für kleine Programme einfach zu implementieren ist.

Eine weitere Variante ist das Command-Pattern: Du definierst ein Interface mit einer einzigen Methode, das "Command" (man kann auch gleich Runnable nehmen...).
Instanzen dieser Commands gibst du nun in eine Queue (LinkedList), und ein "Worker-Thread" ruft ein Command nach dem anderen ab (und führt es aus).
Mit Hilfe der Methoden "wait" und "notify" kann man den Worker-Thread schlafen lassen, solange die Queue leer ist.

Codemässig sieht die Queue etwa so aus:
Code:
public class Worker{
  private Queue<Runnable> queue = new LinkedList<Runnable>();

  public static final Worker WORKER = new Worker();
  
  private Worker(){
    Thread thread = new Thread(){
         public void run(){
            Runnable next;
            synchronized( queue ){
               while( queue.isEmpty() )
                  queue.wait() // und die ganzen Exceptions abfangen...
                next = queue.poll();
            } 
            next.run();
         }
     };
     thread.start();
  }

   // Das Runnable run wird ausgeführt, sobald der Thread Zeit dazu hat
   public void run( Runnable run ){
      synchronized( queue ){
          // Das Runnable speichern
          queue.push( run );

          // Versichern, dass der Thread nicht schläft
          queue.notify();
      }
  }
}

Jetzt müsste das "laden" nurnoch in ein Runnable, anonyme Klassen bieten sich da an (so wie der "Thread" im Code oben) :wink:

Wegen dem Vorhersehen der GUI, was der Benutzer wird tun können... wenn es nicht möglich ist, einfach mal die Kontrollen sperren, welche möglicherweise Probleme verursachen könnten. Oder die "Commands" prüfen bei ihrem Start nochmal, ob wirklich alles stimmt (und sie ausgeführt werden können). Die letzte Methode bringt aber das Problem mit sich, dass der Benutzer auf irgendwelche Kontrollen klicken kann, die (scheinbar) gar nichts bewirken.
 

Kaleidoskop

Mitglied
Erstmal danke für die Mühe.

Diese Lösung scheint schon recht kompliziert. Steige da zwar vom Prinzip hinter, aber das zu implementieren ist mir noch nicht so ganz klar.

Frage ist ob dies nicht zu aufwendig wäre, denn in meinem Falle hätte die Queue ja immer nur einen Thread zu bearbeiten.

Normalzustand
|
User klickt Fraktal(oder Laden,Kreis,Spirale etc.)
|
Daten dazu eingeben
|
Linie berechnen<------------
| |
Linie zeichnen |
| |
kurze Pause----->(user tut nichts)
|
User tut irgendwas(bricht das zeichnen ab)
|
Normalzustand

Mal eine vereinfachte Darstellung des ganzen.

Daher hätte ich eigentlich immer nur einen Thread der bearbeitet wird. Der Benutzer soll eigentlich nicht mehrmals irgendwo klicken können und so mehrere Grafikoperationen auslösen können.
 
B

Beni

Gast
Ehrlich gesagt, jetzt verstehe ich langsam dein Problem nicht mehr. Wenn es nur etwas zu bearbeiten gibt -> einen Thread machen wenn der Benutzer auf das Knöpflein drückt. ???:L
 

Kaleidoskop

Mitglied
War etwas fleißig und auch ein wenig was gefunden. hatte mich übrigens getäuscht, brauche wohl doch mehrere Threads, dank Rekursion.


Kann sein das am Ende eine Klammer fehlt was aber nicht so wichtig ist. Habe mir nun damit beholfen es so wie unten zu machen. Funktioniert bisher auch einwandfrei, das mit dem Abbrechen kriege ich auch alleine hin.
Code:
public void laden(){
		
new Thread(){
                                Iterator iterator = befehlsSpeicher.iterator();
				public void run(){
					try{
						while(iterator.hasNext()){
							String eingabe = (String)iterator.next();
							StringTokenizer stringToken = new StringTokenizer(eingabe);
							String aktuell = stringToken.nextToken();
							zeichnen(true);
								Thread.currentThread().sleep(500);
							
						}
						
					}
					catch(Exception ex){
						ex.printStackTrace();
					}
				}
			}.start();
				
}

Nun habe ich aber noch ein kleines Problem mit einer rekursiven Methode. Nehme als Beispiel mal die Kochkurve.

Code:
public void kochkurveZeichnen(double strecke, int ebene){
		new Thread(){
			public void run(){
				try{
					if (ebene > 0) {
						kochkurveZeichnen(strecke/3, ebene - 1);
						drehen(60);
			                        kochkurveZeichnen(strecke/3, ebene -1);
			                        drehen(-120);
			                        kochkurveZeichnen(strecke/3, ebene -1);
			                        drehen(60);
			                        kochkurveZeichnen(strecke/3, ebene -1);
			                 } else{
			        	       zeichnen(strecke);
			        	       Thread.currentThread().sleep(500);
			                 }
				}
				catch(Exception ex){
					ex.printStackTrace();
				}
			}
		}.start();
	}
Erstmal sind "strecke" und "ebene" nicht im run block bekannt. Zudem müßte ich ja mit jeden neuen aufruf einen neuen Thread erzeugen. Diese müßten ja allerdings warten bis der jeweils vor ihm existierende Thread beendet ist. Ansonsten geraten ja meine Koordinaten durcheinander.

Muß ich nun die von dir vorgeschlagende Queue verwenden oder gibt es eine andere Möglichkeit das zu lösen ? Oder ist der obige Ansatz völliger Quatsch.

Für jede Idee dankbar ist.
 
B

Beni

Gast
Zur Strecke, Ebene: mach jeweils ein "final" davor, dann sind sie auch im Thread bekannt (aber können nicht mehr verändert werden).

Ich würde die Methoden in zwei Methoden aufteilen: eine die den Thread startet, eine andere welche die Rekursion abarbeitet (und vom Thread aufgerufen wird).
Bei jedem Durchgang einen neuen Thread machen, und dann doch nur einen anderen schlafen lassen, das ist reine Ressourcenverschwendung :wink:
 

Kaleidoskop

Mitglied
Code:
new Thread(group,"Kochkurve"){
			public void run(){
				kochkurveZeichnen(strecke,ebenen);
			}
			public void kochkurveZeichnen(double strecke, int ebene){
				if(!isInterrupted()){
					try{
						sleep(7);
						if (ebene > 0) {
							kochkurveZeichnen(strecke/3, ebene - 1);
							drehen(60);
				                        kochkurveZeichnen(strecke/3, ebene - 1);
				                        drehen(-120);
				                        kochkurveZeichnen(strecke/3, ebene - 1);
				                        drehen(60);
				                        kochkurveZeichnen(strecke/3, ebene - 1);
				                } else zeichnen(strecke);
					}catch (InterruptedException e){
						System.out.println("Kochkurve zeichnen ist interrupted!");
						interrupt();
					}
				}else {
					System.out.println("Kochkurve ist interrupted!");
					interrupt();
				}
			}
		}.start();

So sieht die Methode aktuell aus nach deinem Vorschlag und funktioniert von den Funktionen einwandfrei. Nur hat sie noch einen Performancekiller. Da man stop() ja nicht verwenden soll, brauche ich aktuell 2 interrupt Bereiche. Das Zeichnen wid auch schön abgebrochen, nur geht er die restlichen Rekursiven Aufrufe noch durch und bricht sie einzeln ab. Das sind je nach Abbruchzeit bis zu 20 Aufrufe nur um sie abzubrechen.

Unabhängig davon schon mal super vielen Dank für die tolle Hilfe.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
C GLOOP Problem beim Erstellen der Kamera Java Basics - Anfänger-Themen 9
sserio Problem beim Anzeigen Java Basics - Anfänger-Themen 5
I Output BigDecimal anstatt double / Problem beim Rechnen Java Basics - Anfänger-Themen 16
P Problem beim Überschreiben einer vererbten Methode Java Basics - Anfänger-Themen 4
J Problem beim vergleich von zwei Integer Java Basics - Anfänger-Themen 3
G Problem beim Speichern von Objekten in einer Datei Java Basics - Anfänger-Themen 7
S Collections funktionale Listen (ListNode<E>) review und problem beim clone Java Basics - Anfänger-Themen 0
C Methoden Problem beim Speichern von Variablen Java Basics - Anfänger-Themen 1
F Problem beim entfernen von mehreren Listenelementen auf einmal (Programmierung des Spiels Arschloch) Java Basics - Anfänger-Themen 1
B Problem beim grundsätzlichen Verständnis bei Rekursion mit 2-dimensionalen Array Java Basics - Anfänger-Themen 6
E Datentypen Problem beim Speichern von enum. Java Basics - Anfänger-Themen 10
A Problem beim Deklarieren von einem BOOLEAN Java Basics - Anfänger-Themen 4
B Gleicher Prozess starten und stoppen (Problem beim Stoppen) Java Basics - Anfänger-Themen 5
DestinatioN Problem beim splitten eines Satzes in Wörter und die Wörter in Buchstaben Java Basics - Anfänger-Themen 2
B Problem beim Angeben einer Eingabe Java Basics - Anfänger-Themen 12
J Encoding Problem beim Einlesen einer txt Datei mit Umlauten Java Basics - Anfänger-Themen 3
R Problem beim Wochenplan (Datum,Wochentag) Java Basics - Anfänger-Themen 30
D Problem beim umwandeln eines Strings in eine Dzezimalzahl Java Basics - Anfänger-Themen 6
A Compiler-Fehler Problem beim einbinden der applet Klasse Java Basics - Anfänger-Themen 2
L Compiler-Fehler Problem beim Programmieren eines Kalenders (java.lang.ArrayIndexOutOfBoundsException) Java Basics - Anfänger-Themen 2
C Problem beim laden eines BufferedImage Java Basics - Anfänger-Themen 2
D Problem beim Lesen einer txt-Datei Java Basics - Anfänger-Themen 8
fLooojava Bluetooth Projekt - Problem beim mehrmaligen Senden Java Basics - Anfänger-Themen 5
E Problem beim Übergeben von Parameter an Methode Java Basics - Anfänger-Themen 2
Z Problem beim Lesen und Schreiben einer Datei Java Basics - Anfänger-Themen 10
R Problem beim erstellen eines neuen Klassenobjekts Java Basics - Anfänger-Themen 2
F Input/Output Problem beim einlesen eines Strings Java Basics - Anfänger-Themen 3
J Problem beim auslesen von Int Wert aus YML-Datei Java Basics - Anfänger-Themen 6
P Problem beim Abschluss im Kompositum Java Basics - Anfänger-Themen 3
M Problem mit null pinterexception beim laden von Bildern Java Basics - Anfänger-Themen 20
K Problem beim Array aufruf Java Basics - Anfänger-Themen 4
J Problem beim ausführen in cmd.exe Java Basics - Anfänger-Themen 4
J Variablen Problem beim einlesen einer Zahl Java Basics - Anfänger-Themen 7
A Problem beim Compilieren Java Basics - Anfänger-Themen 11
J Problem beim Fenster Java Basics - Anfänger-Themen 4
tux20 Problem beim Schreiben von List to File Java Basics - Anfänger-Themen 2
M Problem beim Compilieren Java Basics - Anfänger-Themen 14
Maxim6394 Problem beim Abspielen von Sounds Java Basics - Anfänger-Themen 8
S Problem beim ersten compilieren überhaubt Java Basics - Anfänger-Themen 43
H Problem beim lesen des InputStreams von einem Subprozess Java Basics - Anfänger-Themen 4
Luk10 Problem beim .jar Datei erstellen Java Basics - Anfänger-Themen 19
L Problem beim Ausführen Java Basics - Anfänger-Themen 40
A Problem beim einfügen in eine Datenbank Java Basics - Anfänger-Themen 2
E Problem beim Programmieren eines Kartenspiels Java Basics - Anfänger-Themen 3
A Problem beim Ausführen einer .jar datei auf externen System Java Basics - Anfänger-Themen 5
M Problem beim compilieren Java Basics - Anfänger-Themen 6
JAVAnnik problem beim lvl laden Java Basics - Anfänger-Themen 15
L Problem beim Einlesen einer Datei in einen String Java Basics - Anfänger-Themen 12
W Problem beim erstellen eines Tests Java Basics - Anfänger-Themen 16
JAVAnnik Problem beim Objekt bewegen Java Basics - Anfänger-Themen 20
A Erstes Programm - Problem beim Ausführen als jar Java Basics - Anfänger-Themen 3
S Problem beim Speichern und Laden von Daten Java Basics - Anfänger-Themen 13
B Problem beim Abspielen einer Videodatei Java Basics - Anfänger-Themen 4
S Problem beim Erstellen eines Scanner-Objekts Java Basics - Anfänger-Themen 7
W Problem beim CSV-Import Java Basics - Anfänger-Themen 5
M Datentypen Problem beim zusammenstellen eines Abfrage-Strings Java Basics - Anfänger-Themen 3
K Collections Problem beim import von Packages Java Basics - Anfänger-Themen 10
S Problem beim Kompilieren - cannot find symbol - constructor() Java Basics - Anfänger-Themen 12
B Problem beim Email versenden mit Javamail Java Basics - Anfänger-Themen 5
H Problem beim Anfang von Java (Java Editor) Java Basics - Anfänger-Themen 2
I Problem beim Schreiben eines ersten Programms Java Basics - Anfänger-Themen 3
D Problem beim Zeichnen von "Das Haus vom Nikolaus" Java Basics - Anfänger-Themen 10
D Problem beim Auslesen aus File Java Basics - Anfänger-Themen 3
A Problem beim Splitten eines Strings Java Basics - Anfänger-Themen 10
S Problem mit ObjectInputStream beim Einlesen von LinkedList Java Basics - Anfänger-Themen 3
J Problem beim Löschen von elementen aus einer ArrayList Java Basics - Anfänger-Themen 5
V Problem beim Programm laden Java Basics - Anfänger-Themen 5
H Problem beim kompilieren Java Basics - Anfänger-Themen 3
C ActionListener problem beim starten von programmen Java Basics - Anfänger-Themen 3
4 OOP Problem beim Speichern verschiedener Klassen in verschiedenen Dateien Java Basics - Anfänger-Themen 25
T Problem beim Returnwert einer Methode Java Basics - Anfänger-Themen 12
M line.separator: Problem beim Lesen einer Datei Java Basics - Anfänger-Themen 11
Miladriel Problem beim Neuzeichnen nach deiconify Java Basics - Anfänger-Themen 9
R Problem beim Ausführen von Java-PGM aus der shel Java Basics - Anfänger-Themen 3
G Problem beim Sortieren einer Liste Java Basics - Anfänger-Themen 20
M Problem beim Ereignishandling mit Menü Java Basics - Anfänger-Themen 2
H problem beim zeichen im JFrame Java Basics - Anfänger-Themen 6
F Problem beim Objekteaufruf... Java Basics - Anfänger-Themen 4
E BlockChallenge: Problem beim löschen der Blöcke Java Basics - Anfänger-Themen 3
H Problem beim Verkürzen von Programm Java Basics - Anfänger-Themen 3
T Problem beim Werfen und Fangen von Exceptions Java Basics - Anfänger-Themen 2
M Problem beim Zugriff auf Daten GUI + Startklasse Java Basics - Anfänger-Themen 4
P Problem beim Thread Java Basics - Anfänger-Themen 20
0 problem beim Polygon zeichnen Java Basics - Anfänger-Themen 3
V Problem beim erstellen eines ausführbaren Programs Java Basics - Anfänger-Themen 5
0 Problem beim Starten des Applets Java Basics - Anfänger-Themen 2
N Problem beim Durchsuchen einer LinkedList Java Basics - Anfänger-Themen 5
G Problem beim Programmieren von Blackjack Java Basics - Anfänger-Themen 15
R Problem beim Laden eines Images Java Basics - Anfänger-Themen 7
K Problem beim installieren des JDK 1.6+ version Java Basics - Anfänger-Themen 3
T Problem beim Konsolenstart Java Basics - Anfänger-Themen 5
C Problem beim Berechnen der Quadratwurzel Java Basics - Anfänger-Themen 3
C Problem beim nutzen von Teilprogrammen in main Java Basics - Anfänger-Themen 2
M Problem beim Zeichnen Java Basics - Anfänger-Themen 5
D Problem beim Kompilieren Java Basics - Anfänger-Themen 4
D Problem beim auslesen von TextArea Java Basics - Anfänger-Themen 3
G Problem beim Schreiben in Textdatei Java Basics - Anfänger-Themen 9
F ggT finden - problem beim qc Java Basics - Anfänger-Themen 4
S Problem mit url, inputStream und bytes beim Quellcode laden. Java Basics - Anfänger-Themen 6
G Habe ein Problem mit syn-Editor ( beim compilieren) Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben