Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Thread Problem bei Event

Empfohlene Antworten

Veröffentlicht

Hallo,

ich möchte nach einem Buttonklick eine (swing)Komponente für einen Moment gelb färben und anschließend blinkend grün oder rot (wie man es bei den Antworten aus Quizshows kennt).

Daraus:

Here's the rule:

Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.

Quelle: Threads and Swing

... entnehme ich, dass ich dem EDT bescheid sagen muss: "Hier, führ mal diesen Code aus".

Folgender Codeschnipsel soll genau das erstmal tun.


Runnable colorMyComponent = new Runnable() 

{

	public void run()

	{ handleButtonLogin(); }

};

SwingUtilities.invokeLater(colorMyComponent);
Implementierung:

public void handleButtonLogin()

{

	try	 

	{ 

		gui.buttonA.setBackground(Color.yellow);

		System.out.println("jetzt gelb bei A");

		gui.repaint();

		Thread.sleep(1500);

	}

	catch( InterruptedException e) {}

	gui.buttonA.setBackground(Color.green);

	gui.repaint();

	System.out.println("Weiter");

}

Was jetzt passiert: Der Try-Block wird ausgeführt, aber ich bekomme nur die Ausgabe und nachdem Thread.sleep() abgearbeitet ist, ist meine Komponente grün.

Weshalb wird gui.buttonA.setBackground(Color.yellow); nicht ausgeführt?

Du führst die Warteoperation innerhalb des Event Dispatcher Threads aus und hinderst dabei das System daran, überhaupt die Komponente neu zu zeichnen.

Der Ablauf muss wie folgt laufen:

- Komponente innerhalb des EDT einfärben

- Ausserhalb des EDT (in einem separaten Thread) warten

- Komponente innerhalb des EDT wieder zurückfärben.

Ungetestet also in etwa so:


public void doColorCycle() {

  new Thread() {

    public void run() {

      SwingUtilities.invokeLater(new Runnable() {

        public void run() {

          component.setBackgroundColor(Color.YELLOW);

        }

      });

      Thread.sleep(500);

      SwingUtilities.invokeLater(new Runnable() {

        public void run() {

          component.setBackgroundColor(Color.GREEN);

        }

      });

    }

  }.start();

}

  • Autor

Prima, so in etwa hab ich mir das vorgestellt. Danke. Mir fällt es allerdings nicht ganz leicht, den Handlungsstrang nachzuvollziehen, was in welcher Reihenfolge abgearbeitet wird.


if(gui.buttonA.getActionCommand().equals(radioListener.getAnswer()))

{				

	doColorCycle();

}


gui.update(getNewTask());

Durch die letzte Anweisung geht es praktisch weiter, d. h. die Oberfläche wird mit neuen Inhalten gefüllt. Dies passiert aber scheinbar bevor doColorCycle() ausgeführt wird (Implementierung von oben übernommen). Mit anderen Worten, die Ansicht wechselt und erst dann färbt sich die besagte Komponente. Lässt sich das nicht besser steuern?

Lässt sich das nicht besser steuern?
Mach dir klar, welche Operation von welchem Thread ausgeführt wird. Alles, was die GUI betrifft sollte im EDT ausgeführt werden - wenn du das konsequent so handhabst dürftest du auch keine Probleme bezüglich der Darstellung haben.

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.