Thread.sleep in while

Sorry wenn ich so direkt frage, aber was ist an folgender Aussage nicht zu verstehen : “ALLE Änderungen an der GUI haben grundsätzlich nur durch den EDT zu erfolgen !”. Denn genau das machst du nicht weshalb das verhalten unspezifiziert ist und entsprechend nicht deinem gewünschten Ergebnis entspricht. Außerdem : wenn du vorher und hinterher zwei log-Ausgaben hast dann ist sowas wie “nur die Zeile dazwischen wird nicht ausgeführt” kompletter Blödsinn.
Hier wie es richtig geht :

{
	new Thread(new Runnable()
	{
		public void run()
		{
			SwingUtilities.invokeAndWait(new Runnable()
			{
				public void run()
				{
					// Rand = rot
				}
			});
			try { Thread.sleep(5000); } catch(Exception e) { e.printStackTrace(); }
			SwingUtilities.invokeAndWait(new Runnable()
			{
				public void run()
				{
					// Rand = schwarz
				}
			});
		}
	}).start();
}```
Klar, strukturiert, sauber und einfach.

Weiter : gewöhne dir an NIE leer catch-Blöcke zu nutzen. In ein catch gehört IMMER mindestens eine Log-Message oder ein printStackTrace().

btw : du machst eben nicht genau das gleiche, denn ein mal machst du es mit Stühlen, und ein mal mit Tischen. Möglich das dieser Unterschied schon reicht.

Und bevor der nächste kommt von wegen "kein AndWait()" : wie oben erwähnt kann somit sichergestellt werden das die gewünschte Aktion erst vollständig abgearbeitet wird bevor es weiter geht. Begründung : race-condition das halt so wenig zeit zwischen rot und schwarz vergeht das man es nicht mal mehr sieht weil das sleep() des äußeren Threads schon durch ist.

Das ist der Punkt, auf den ich dich hinweisen wollte, bevor ich das nach dem Codeblock gelesen habe:
An der Stelle macht es keinen Sinn, die Stacktrace auszugeben. Der Catch-Block bleibt also leer. Und du solltest dir angewöhnen NIEMALS [japi]Exception[/japi] zu fangen, sondern immer den spezifischstmöglichen Exception-Typ (in diesem Fall [japi]InterruptedException[/japi]). (Ja, manchmal geht es nicht anders als [japi]Exception[/japi] zu fangen, das ist aber die absolute Ausnahme.)
Prinzipiell ist es richtig, den Catch-Block nicht leer zu lassen. Bei der InterruptedException ist es aber etwas anders. Entweder packt man dort gar nichts hinein, damit die übergeordnete Routine einfach beendet wird, oder man ruft Thread.currentThread().interrupt(); auf, damit der Interrupt propagiert wird. Das braucht man in der Regel aber nicht, wenn man sich in einem Kontext befindet, in dem man die Threadverwaltung selber macht.

Hallöle,

vielen Dank für eure Hilfe. Ja, okay, ich werde die catchblöcke füllen, habe verstanden.

Aber das Problem von eben hat sich noch nicht aufgelöst.
Es passiert weiterhin rein gar nichts. Auch wenn ich das mit dem Roten Rahmen auch dort integriere, wie im Beispiel oben. Es wird nur der Schwarze Rahmen verändert.

Mal unabhängig davon, ob das jetzt geht oder nicht:

„ALLE Änderungen an der GUI haben grundsätzlich nur durch den EDT zu erfolgen !“

Wieso? Die Codezeile mit dem Rot hat doch nichts mit dem Thread zu tun? Das ist einfach nur ein Färben eines Rahmens, was sonst an jeder Stelle in jedem Javaprogramm, immer genau so funktioniert hat. Verstehe ehrlich gesagt nicht, was das an der Codestelle in dem invokeAndWait zu suchen hat.

Aber ich lasse es mir gerne erklären :slight_smile:
Gruß
Lukas

@cmrudolph
Das man nicht direkt Exception fangen soll weis ich auch, war nur auf die schnelle. Außer schrieb ich “mindestens” was mit der Besonderheit bei sleep() ja nich kollidiert.

@TO
Ich gebs auf … lies dir einfach mal die SwingThreadingPolicy durch … vielleicht verstehst du dann meinen Code (der im Gegensatz zu deinem auch das tut was er soll).

„Mindestens“ schließt einen leeren Catch-Block aber aus. Ebenso wie deiner Aussage „NIE leere Catch-Blöcke zu nutzen“.

[ot]Mich stört deine herablassende Art und Weise tierisch:

Deshalb reagiere ich vielleicht etwas über und schreibe ebenfalls etwas verschärft…
Meine Auffassung des zitierten Textes: „Du bist einfach zu blöd das zu verstehen. Ich hab es total drauf und da du ja eh nichts zustande bringst, kannst du dir mal meinen Code ansehen und davon lernen.“[/ot]

Hallihallöle,

ich habe das Problem lösen können.
Ich habe hierfür den “heiligen und einzig wahren korrekten Code” von @Sen-Mithrarin benützen können. Bzw. in einer Abwandlung.
Die Funktion SwingUtilities.invokeAndWait erfordert nämlich das Abfangen zweier Exceptions InvocationTargetException & InterruptedException, ohne die das Programm nicht funktioniert.
Selbstverfreilich habe ich den catch-Block auch nicht leer gelassen.

Im Gesamten sieht es nun so aus:

					        public void run() {
					            try {
									SwingUtilities.invokeAndWait(new Runnable() {
									    public void run() {
									    	stuhl.getSpielzelle().setBorder(BorderFactory.createLineBorder(Color.red, 3));
									    }
									});
								} catch (InvocationTargetException | InterruptedException e) {
									e.printStackTrace();
								}
					            try { Thread.sleep(5000); } catch(Exception e) { e.printStackTrace(); }
					            try {
									SwingUtilities.invokeAndWait(new Runnable() {
									    public void run() {
									    	stuhl.getSpielzelle().setBorder(BorderFactory.createLineBorder(Color.red, 3));
									    }
									});
								} catch (InvocationTargetException | InterruptedException e) {
									e.printStackTrace();
								}
					        }
					    }).start();```

[QUOTE=cmrudolph]
[ot]Mich stört deine herablassende Art und Weise tierisch:

Deshalb reagiere ich vielleicht etwas über und schreibe ebenfalls etwas verschärft...
Meine Auffassung des zitierten Textes: "Du bist einfach zu blöd das zu verstehen. Ich hab es total drauf und da du ja eh nichts zustande bringst, kannst du dir mal meinen Code ansehen und davon lernen."[/ot][/QUOTE]

Vielen Lieben Dank. Du hast alles gesagt, was ich sagen wollte. :) Diese Arroganz in Deinem Ton @Sen-Mithrarin  ist schon partiell unverschämt.
Aber ich werde das jetzt nicht weiter ausmalen.
Ich bin froh über jeden, der mir bei dem einen oder anderen Problem hilft und über jedes Zusatzwissen, was ich für mich persönlich erreichen kann.
Und das habe ich durch Dich nun auch erhalten können.

Ohne ekelhafte Antipathieträger wäre das Leben ja auch langweilig.

Schöne Grüße und Vielen Dank allen, die mir geholfen haben!
 @Marco13  @cmrudolph  @Sen-Mithrarin  @CyborgGamma  @SlaterB  @Bene  @FSM

Schönes Restwochenende!
Lukas

Ungefähr so hätte ich das geschrieben:

 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dasisttest;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

/**
 * @author CB at http://forum.byte-welt.net/
 */
public class Button {

    private static volatile boolean runs = true; // "May be changed by other threads without warning."
    private static final JLabel JL = new JLabel("text label");

    public static void main(String[] args) {
        final JFrame jf = new JFrame("Frame title");
        jf.add(JL);
        //jf.pack();
        jf.setSize(400, 300);
        jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // runs etwa 11 Sek.
        jf.setVisible(true);

        new Thread(new Runnable() { // besser: lokale Var.
            @Override
            public void run() {
                try {
                    while (runs) {
                        SwingUtilities.invokeLater(new Runnable() { // hier die jeweilige, lange Änderung
                            @Override
                            public void run() {
                                JL.setText(Long.toString(System.currentTimeMillis() / 1000));
                                //jf.pack();
                            }
                        });
                        Thread.sleep(1500);
                    }
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }

            }
        }).start();

        try {
            Thread.sleep(9999);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
        runs = false;
    }
}```

.printStackTrace() unterstrichelt mir NetNeans (schon seit Längerem).

Das mit den anonymen inneren Klassen ist nicht so ganz einfach.

Es sollten mehrere Threads und lokale Variablen sein. final sollte alles sein, was (in Methoden) in anonymen inneren Klassen verwendet wird.

grüße

Ist ja auch richtig und war die Kernaussage. Exceptions (gleich wie „hoch“ oder „tief“ im Klassenbaum) stillschweigend zu ignorieren, auch wenn sie noch so offensichtlich sind oder „Sonderbehandelungen“ erfordern, ist einfach FALSCH!

Das ist auch richtig, und genau SO war es auch gemeint. Ich weis zwar nicht in welchem Thread die Methode letztendlich ausgeführt wird, und wenns im EDT passiert wäre es so ja auch ok, aber wenn man mehrfach sagt das es in Swing einfach so gemacht wird und man es dann, und ja, jetzt sag ichs mal grade raus : nicht rallt und dann noch drüber heult : „Was das soll versteh ich nicht?“, dann hab ich auch einfach kein bock mehr mich 100 mal zu wiederholen. Entweder man lernt es und nutzt die zur Verfügung gestellten Resourcen oder Verweise, oder halt nicht und muss halt copy’n’paste machen.

~ zum Rest : TLDR