Farbänderung von Komponenten wird nicht wirksam

Rufus.Mueller

Bekanntes Mitglied
Guten Mittag,

ich habe eine Methode sequenzAnzeigen(), diese bekommt ein Window (ist Subklasse von Frame) und eine Sequenz übergeben. Nach Vorgaben der Sequenz sollen bestimmte Komponenten auf dem Bildschirm die Farbe wechseln. Tasächlich tut sich nichts, gar nichts. Die Methode gehört zu einer Klasse namens corsiPlatte und wird aufgerufen mit window.corsiPlatte.sequenzAnzeigen(aktuelleSequenz, window);. Eclipse zeigt vor dem Ausführen keinen Fehler an.

Java:
public void sequenzAnzeigen(Sequenz aktuelleSequenz, Window window) throws InterruptedException {
		
		this.window = window;
		this.aktuelleSequenz = aktuelleSequenz;

		for (int i=0; i<aktuelleSequenz.sequenzfolge.length; i++) {
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.YELLOW);
			
			Thread.sleep(1000);
			
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.BLACK);
			
			Thread.sleep(1000);	
		}	
	}

Dann bin ich auf die Idee gekommen, dass der Hund in der for-Schleife begraben liegt und habe mal eine Codezeile block1.setBackground(Color.YELLOW); vor die for-Schleife in der Methode sequenzAnzeigen() gesetzt. Das Resultat ist, dass ich von ebendieser neuen Codezeile eine NPE an den Kopf geworfen bekomme. Das könnte ich mir eigentlich nur dann erklären, wenn es block1 gar nicht gibt. Zweifellos wird er mir aber auf dem Bildschirm angezeigt. Kommentiere ich die Anweisung aus, verschwindet die Fehlermeldung, umfärbung findet aber keine statt.

Die Klasse CorsiPlatte sieht aus wie folgt.

Java:
import java.awt.*;

import javax.swing.*;

import javax.swing.JFrame;


public class CorsiPlatte extends Panel {
	
	CorsiQuadrat block1, block2, block3, block4, block5, block6, block7, block8, block9;
	Sequenz aktuelleSequenz;
	Window window;
	
	//Konstruktor
	public CorsiPlatte(){
		

		//Panel erzeugen
		
		
		this.setLayout(null);
		this.setBackground(Color.BLACK);
		this.setVisible(true);
	
	
		
		//Corsi-Bklöcke erzeugen
		
		CorsiQuadrat block1 = new CorsiQuadrat("1");
		CorsiQuadrat block2 = new CorsiQuadrat("2");
		CorsiQuadrat block3 = new CorsiQuadrat("3");
		CorsiQuadrat block4 = new CorsiQuadrat("4");
		CorsiQuadrat block5 = new CorsiQuadrat("5");
		CorsiQuadrat block6 = new CorsiQuadrat("6");
		CorsiQuadrat block7 = new CorsiQuadrat("7");
		CorsiQuadrat block8 = new CorsiQuadrat("8");
		CorsiQuadrat block9 = new CorsiQuadrat("9");  
		
		
		//Corsi-Blöcke auf dem Panel platzieren
		
	
		this.add(block1);
		this.add(block2);
		this.add(block3);
		this.add(block4);
		this.add(block5);
		this.add(block6);
		this.add(block7);
		this.add(block8);
		this.add(block9);   
		
		block1.setBounds(105,135,90,90);
		block2.setBounds(265,80,90,90);
		block3.setBounds(450,80,90,90);
		block4.setBounds(630,170,90,90);
		block5.setBounds(120,390,90,90);
		block6.setBounds(240,285,90,90);
		block7.setBounds(440,420,90,90);
		block8.setBounds(440,245,90,90);
		block9.setBounds(615,300,90,90);  
	}
		
	
	
	

	public void sequenzAnzeigen(Sequenz aktuelleSequenz, Window window) throws InterruptedException {
		
		this.window = window;
		this.aktuelleSequenz = aktuelleSequenz;
		
		
		
		//dieser Codeblock ist nur zum ausprobieren
		System.out.println("test");
	//	block1.setBounds(100,100,100,100);
		block1.setBackground(Color.YELLOW);
	//	block1.validate();
	//	window.validate();
		
		
	
		//die folgenden Code-Blöcke sind die "echten"
		for (int i=0; i<aktuelleSequenz.sequenzfolge.length; i++) {
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.YELLOW);
			
			Thread.sleep(1000);
			
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.BLACK);
			
			Thread.sleep(1000);	
		}	
	}
}
 
Warum benutzt du AWT und kein Swing?

EDIT: Dein UI Thread hat gar keine Zeit sich neu zu zeichnen?! Was willst du den erreichen? Ein flackern zwischen gelb und schwarz?
 
Zuletzt bearbeitet von einem Moderator:
SirWayne hat gesagt.:
Warum benutzt du AWT und kein Swing?

EDIT: Dein UI Thread hat gar keine Zeit sich neu zu zeichnen?! Was willst du den erreichen? Ein flackern zwischen gelb und schwarz?

Ich lerne noch. Im Grunde will ich Swing benutzen, manchmal rutscht im Eifer des Gefechts dann auch mal was aus AWT dazwischen. Durch Thread.sleep(1000); sollte für eine Sekunde die Farbe gelb erscheinen, dann wieder schwarz. Zusätzlich window.validate(); nach dem sleep() Aufruf einzufügen hatte keinen Erfolg. Ich habe neun Buttons auf dem Bildschirm, alle schwarz. Nach einer vorgegebenen Sequenz soll sich immer ein Button gelb färben (für eine Sekunde), dann wieder schwarz und dann kommt ein anderer Button dran.


Von wo wird sequenzAnzeigen() aufgerufen? Aus dem EDT?

Die Methode wird von der Klasse TestungEinerVP aufgerufen und diese wiederum von der main-Methode der Klasse WordCorsi.

Java:
import java.util.ArrayList;


public class TestungEinerVP{
	ArrayList<Sequenzbehaelter> sequenzVorratDieserVP = new ArrayList<Sequenzbehaelter>();
	
	
	Sequenz aktuelleSequenz;
	int aktuelleLaenge;
	Sequenzbehaelter aktuellerSequenzbehaelter;
	// ArrayList<Sequenzbehaelter> sequenzbehaelterCollection;
	ArrayList<Sequenzbehaelter> sequenzbehaelterCollection;
	Window window;
	
	
	//Konstruktor
	public TestungEinerVP(ArrayList<Sequenzbehaelter> sequenzbehaelterCollection, Window window) {
		this.sequenzbehaelterCollection=sequenzbehaelterCollection;
		
	this.window =window;
	//	sequenzbehaelterCollectionDieserVP = sequenzbehaelterCollection;
	//	seq = sequenzVorrat;
	
	}
	
	//Durchführung der Corsi-Aufgabe
	public void corsiSpanneErmitteln() throws InterruptedException{
		
		
		//System.out.println(aktuellerSequenzbehaelter=sequenzbehaelterCollectionDieserVP.getSize();)
		
        System.out.print(sequenzbehaelterCollection.get(2).get(0).sequenzfolge[0] );
        System.out.println(sequenzbehaelterCollection.get(2).get(0).sequenzfolge[1] );
		
		aktuellerSequenzbehaelter=sequenzbehaelterCollection.get(2);
		aktuelleSequenz=aktuellerSequenzbehaelter.get(0);
		
	//	aktuelleSequenz=sequenzbehaelterCollection.get(2);
		
		
		window.corsiPlatte.sequenzAnzeigen(aktuelleSequenz, window);
		
		
	}
	
}


Java:
import java.awt.Frame;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.*;


public class WortCorsi {
	
	public static void main(String[] args) throws IOException, InterruptedException{
		
		Window window = new Window();


		window.setVisible(true);
		ArrayList<Sequenzbehaelter> sequenzbehaelterCollection= new ArrayList<Sequenzbehaelter>();
		TestungEinerVP durchlauf;

		Sequenzeinleser sequenzeinleser = new Sequenzeinleser();
		sequenzbehaelterCollection = sequenzeinleser.leseSequenzen();
		
		
       System.out.print(sequenzbehaelterCollection.get(2).get(0).sequenzfolge[0] );
       System.out.println(sequenzbehaelterCollection.get(2).get(0).sequenzfolge[1] );
       
       durchlauf = new TestungEinerVP(sequenzbehaelterCollection, window);
       durchlauf.corsiSpanneErmitteln();
       
       
        
 //      System.out.print(sequenzVorrat.get(9).get(1).sequenzfolge[0] );
 //       System.out.println(sequenzVorrat.get(12).get(1).sequenzfolge[0] ;  */
        
        
        
		
		
		//System.out.println(sequenzeinleser.sequenzbehaelterCollection.get(0).get(0).sequenzfolge);
		
		
		

	}

}
 
also evtl hilft dir auch ein einfaches
Code:
repaint()
nach dem
Code:
validate()
auf dein window...ohne wirklich deine code groß gelesen, geschweige denn verstanden zu haben 😉
 
Du benutzt nur AWT

siehe Frame,Panel usw.

du musst immer JFrame und JPanel usw. verwenden. Bei Swing beginnt alles mit "J".

Zu deinem Problem du legst deinen UI-Thread eine sekunde schlafen solange kanner nichts neues zeichnen. Du musst das in einen Hintergrund Thread auslagern, dieser darf allerdings wieder nur im UI-Thread zeichnen. Siehe SwingUtilities#invokeLater oder SwingWorker.
 
In der Klasse benutz' ich tatsächlich nur AWT. Ich werde künftig besser aufpassen.

Die Erklärung mit dem schlafenden Thread ist sehr plausibel. Ich wollte versuchen eine einfachere Lösung als verschiedene Threads (habe noch nie mit mehreren Threads gearbeitet) zu finden, weil es leider Zeitdruck gibt. Daher habe ich mal versucht das Fenster vor dem einschläfern des Threads zu repainten, seltsamerweise bringt das auch nichts. Wenn das Window gerepaintet wird bevor der Thread einschläft, müsste die Sache doch klar gehen? Ich frage mich daher ob es noch ein anderes Problem gibt, möchte in dem Zusammenhang auch noch mal auf die im ersten Posting erwähnte NPE hinweisen.

Java:
	public void sequenzAnzeigen(Sequenz aktuelleSequenz, Window window) throws InterruptedException {
		
		this.window = window;
		this.aktuelleSequenz = aktuelleSequenz;
		
		
		
		//dieser Codeblock ist nur zum ausprobieren
		System.out.println("test");
	//	block1.setBounds(100,100,100,100);
	//	block1.setBackground(Color.YELLOW);
	//	block1.validate();
	//	window.validate();
		
		
	
		//die folgenden Code-Blöcke sind die "echten"
		for (int i=0; i<aktuelleSequenz.sequenzfolge.length; i++) {
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.YELLOW);
			
			
			window.validate();
			window.repaint();
			block1.validate();
			block1.repaint();
			Thread.sleep(1000);
			
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.BLACK);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.BLACK);
			
			window.validate();
			window.repaint();
			block1.validate();
			block1.repaint();
			Thread.sleep(1000);
 
Falls es jmd. interessiert: Ich konnte das Problem lösen!!! :toll:

Ursache war, dass ich mal wieder einen Anfängerbock geschossen habe. Hatte die Variablen button1...9 nämlich nicht nur als Instantvariablen sondern zusätzlich versehentlich als lokale Variablen erzeugt. Offenbar haben die lokalen Variablen so die Instanzvariablen verdeckt. Der unten stehende Code arbeitet wie intendiert.

Java:
	public void sequenzAnzeigen(Sequenz aktuelleSequenz, Window window) throws InterruptedException {
		
		this.window = window;
		this.aktuelleSequenz = aktuelleSequenz;

	for (int i=0; i<aktuelleSequenz.sequenzfolge.length; i++) {
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.YELLOW);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.YELLOW);
			
			Thread.sleep(1000);
			
			if (this.aktuelleSequenz.sequenzfolge[i]==1) block1.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==2) block2.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==3) block3.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==4) block4.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==5) block5.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==6) block6.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==7) block7.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==8) block8.setBackground(Color.BLUE);
			if (this.aktuelleSequenz.sequenzfolge[i]==9) block9.setBackground(Color.BLUE);
			
			Thread.sleep(1000); 
		}
	}
 

Zurück
Oben