Eingefärbtes Panel wird in Frame nicht angezeigt

Rufus.Mueller

Bekanntes Mitglied
Ich habe hier den Auszug aus einer main-Methode die die Methode praesentiere() einer Klasse aufruft. Ich erwarte, dass ein Frame mit einem schwarzen Panel angezeigt wird. Tatsächlich wird nur der Frame ohne Panel angezeigt. Die Funktion praesentiere soll eigentlich was anderes bzw. noch mehr machen, ich habe sie nur mal auf das nötigste reduziert um den Fehler einzugrenzen.

Java:
public static void main(String[] args) throws InterruptedException{
		
		JFrame frame = new JFrame();
		//frame.setLayout(new FlowLayout());
		frame.setExtendedState(Frame.MAXIMIZED_BOTH);	
		frame.setVisible(true);
		
		
		QuadrSequenz sequenz1 = new QuadrSequenz(4);
		sequenz1.praesentieren(frame);
		frame.setVisible(true);
		
		
	}


Java:
public void praesentieren(JFrame window) throws InterruptedException {
		
		JFrame w = window;	
		JPanel panel = new JPanel();
		panel.setBackground(Color.BLACK);
		panel.setVisible(true);
		w.add(panel);

Ich habe zum ausprobieren mal eine Testklasse entworfen, die einwandfei funktioniert:

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.*;


public class Test { 

	
		public static void main(String[] args){
			
			JFrame frame = new JFrame();
			frame.setVisible(true);
			//frame.setLayout(new FlowLayout());
			JPanel panel = new JPanel();
			panel.setVisible(true);
			panel.setBackground(Color.BLACK);
			//panel.setPreferredSize(new Dimension(100, 100));
			frame.add(panel);
			
		}
}

Meinem Verständnis nach, enthält die Testklasse nichts was im eigentlichen Programm nicht enthalten wäre. Ich erzeuge ein neues Panel (new) , färbe es schwarz (setBackground), mache es sichtbar (SetVisible) und füge es dem Frame hinzu (add). Auch wenn man den Frame nach dem hinzufügen des Panels noch mal "zum aktualisieren" neu aus visible setzt ändert sich nichts.
 
Ein setVisible(true) auf Komponenten ist überflüssig (ausser auf Fenster oder falls die Komponente vorher setVisible(false) gesetzt wurde).

Ein nachträgliches Hinzufügen oder Entfernen vom Komponenten ist eine schwerwiegende Änderung am Layout. Hier hift ein validate() oder revalidate() an der geänderten Komponente.

Alternativ bietet das CardLayout die Möglichkeit Komponenten zur Laufzeit dynamisch auszutauschen.
 
Hallo,


ganz ehrlich ich sehe da keinen Fehler:
Habe das zwar so umgeschrieben, aber es funktioniert ohne Probleme:


Java:
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class JFrameExtend {

	
	public static void main(String[] args){
        
        JFrame frame = new JFrame();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        
        
        JFrameExtend.praesentieren(frame);
        
           
        frame.setVisible(true);
    }
	
	public static void praesentieren(JFrame window) {
        
        JFrame w = window;  
        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);
        w.add(panel);
        
	}
}


Ich meine du kannst locker das panel wechseln. Aber schöner ist da wirklich ein CardLayout(). Sonst mit setVisible() oder auch gerne remove(Object) und add() + revalidate() , bzw. bei Frame auch repaint().

grüße Spin
 
Hallo,


ganz ehrlich ich sehe da keinen Fehler:
Habe das zwar so umgeschrieben, aber es funktioniert ohne Probleme:


Java:
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class JFrameExtend {

	
	public static void main(String[] args){
        
        JFrame frame = new JFrame();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        
        
        JFrameExtend.praesentieren(frame);
        
           
        frame.setVisible(true);
    }
	
	public static void praesentieren(JFrame window) {
        
        JFrame w = window;  
        JPanel panel = new JPanel();
        panel.setBackground(Color.BLACK);
        w.add(panel);
        
	}
}


Ich meine du kannst locker das panel wechseln. Aber schöner ist da wirklich ein CardLayout(). Sonst mit setVisible() oder auch gerne remove(Object) und add() + revalidate() , bzw. bei Frame auch repaint().

grüße Spin
Weil hier setVisible(true) auf den Frame erst nachdem das Panel hinzugefügt wurde aufgerufen wird.
 
CardLayout wäre wahrscheinlich wirklich am besten gewesen, ich habe aber so viel Zeit in diese Lösung investiert, dass ich Sie nach Möglichkeit zum laufen bringen möchte. Nach längerem rumprobieren habe ich die unten stehende Klasse meine main-Methode die das ganze aufruft ist immer noch unverändert wie im ersten Post.

Java:
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;


// bekommt einen Parameter x übergeben. Erstellt daraus eine Sequenz bestehend aus x 
// unterschiedlich gefärbten Quadraten. Hat eine Methode starten() die die Präsentation
// der Sequenz startet. Parameter steht nicth in der Klassensignatur sondern im Konstruktor
// Der Parameter kann dabei nur Werte zwischen vier und 8 annehmen


//AChtung: Die Seuqnzen sind bisher noch nicht zufällig, die Farben müssen noch durchgemischt w
// werden!!!!

//zusätzlich noch urne mit Arraylist und RG wo nach jeder ziehung gezogenes gelöscht wird??



public class QuadrSequenz {

	//Deklarationsteil
	public int a;
	int i;
	ArrayList<JPanel> sequenz = new ArrayList<JPanel>();
	
	
	//Konstruktor der Klasse Sequenz
	
	public QuadrSequenz(int a) {
		int anzQuadrate=a;
		
		
		if (anzQuadrate==4) {
			for (int i =0; i<=3; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.GREEN);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
		}
		
		if (anzQuadrate==5) {
			for (int i =1; i<=5; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.BLUE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
		}
			
		
		if (anzQuadrate==6) {
			for (int i =1; i<=6; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.YELLOW);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
		}
			
		
		if (anzQuadrate==7) {
			for (int i =1; i<=7; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.WHITE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
			sequenz.get(6).setBackground(Color.WHITE);
		}
			
		
		if (anzQuadrate==8) {
			for (int i =1; i<=4; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.MAGENTA);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.GRAY);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.WHITE);
			sequenz.get(5).setBackground(Color.BLACK);
			sequenz.get(6).setBackground(Color.BLUE);
			sequenz.get(7).setBackground(Color.ORANGE);
		}		
	}
	

	//Methoden der Klasse Sequenz
	
	//prasentieren bekommt ein window übergeben und muss auf diesem die Sequenz anzeigen
	
	public void praesentieren(JFrame window) throws InterruptedException {
		
		JFrame w = window;
		
		this.sequenz.get(0).setVisible(true);
		this.sequenz.get(0).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(0));
		w.validate(); 
		Thread.sleep(5000);
		this.sequenz.get(1).setVisible(true);
		this.sequenz.get(1).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(1)); 
		w.validate();
		Thread.sleep(5000);
		this.sequenz.get(2).setVisible(true);
		this.sequenz.get(2).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(1)); 
		w.validate();
		Thread.sleep(5000);
		this.sequenz.get(3).setVisible(true);
		this.sequenz.get(3).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(1)); 
		w.validate();

		
		}
	}



Meine Erwartung war, dass in genau fünfsekündigem Abstand ein grünes, rotes, blaues und gelbes Panel angezeigt wird. Tatsächlich arbeitet das Programm völlig bizzar. Es wird ein grünes Panel angezeigt und weiter passiert nichts. Wenn ich den unten angegebenen Bereich auskommentiere, wird ein graues Panel angezeigt und es passiert weiter nichts.


Java:
if (anzQuadrate==5) {
			for (int i =1; i<=5; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.BLUE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
		}
			
		
		if (anzQuadrate==6) {
			for (int i =1; i<=6; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.YELLOW);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
		}
			
		
		if (anzQuadrate==7) {
			for (int i =1; i<=7; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.WHITE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
			sequenz.get(6).setBackground(Color.WHITE);
		}
			
		
		if (anzQuadrate==8) {
			for (int i =1; i<=4; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.MAGENTA);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.GRAY);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.WHITE);
			sequenz.get(5).setBackground(Color.BLACK);
			sequenz.get(6).setBackground(Color.BLUE);
			sequenz.get(7).setBackground(Color.ORANGE);
 
Den zweiten Fehler (graues Panel beim ausparaphrasieren) habe ich gefunden, ich habe eine geschweifte Klammer zuviel ausparaphrasiert und Eclipse hat das Programm trotzdem gestartet. Das andere Problem besteht noch.
 
Um einen solchen Farbwechsel hinzubekommen, muss man mit Threads, Timern, SwingWorker o.ä. arbeiten. Das geht aber schon ein bisschen über das Anfängerniveau hinaus.
 
Ich muss und will versuchen es mit einfachen Mitteln hinzubekommen, was bleibt mir anderes übrig? Eine Sequenz farbiger Rechtecke kann ich mittlerweile erfolgreich anzeigen, siehe unten stehend meine Klassen.

Java:
public class Farbquadrate2 {
	
	public static void main(String[] args) throws InterruptedException{
		
		Window window= new Window();
		window.setExtendedState(Frame.MAXIMIZED_BOTH);
		
		window.fensterEinrichten();
		window.setVisible(true);
		Thread.sleep(2000);
		
		QuadrSequenz sequenz1 = new QuadrSequenz(4);
		sequenz1.praesentieren(window);
		
		Thread.sleep(2000);
		window.fensterEinrichten();

Java:
import java.awt.*;
import java.util.ArrayList;
import javax.swing.*;


// bekommt einen Parameter x übergeben. Erstellt daraus eine Sequenz bestehend aus x 
// unterschiedlich gefärbten Quadraten. Hat eine Methode starten() die die Präsentation
// der Sequenz startet. Parameter steht nicth in der Klassensignatur sondern im Konstruktor
// Der Parameter kann dabei nur Werte zwischen vier und 8 annehmen


//AChtung: Die Seuqnzen sind bisher noch nicht zufällig, die Farben müssen noch durchgemischt w
// werden!!!!

//zusätzlich noch urne mit Arraylist und RG wo nach jeder ziehung gezogenes gelöscht wird??



public class QuadrSequenz {

	//Deklarationsteil
	public int a;
	int i;
	ArrayList<JPanel> sequenz = new ArrayList<JPanel>();
	
	
	//Konstruktor der Klasse Sequenz
	
	public QuadrSequenz(int a) {
		int anzQuadrate=a;
		
		
		if (anzQuadrate==4) {
			for (int i =0; i<=3; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.GREEN);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
		}
	}
		
	/*	if (anzQuadrate==5) {
			for (int i =1; i<=5; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.BLUE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
		}
			
		
		if (anzQuadrate==6) {
			for (int i =1; i<=6; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.YELLOW);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
		}
			
		
		if (anzQuadrate==7) {
			for (int i =1; i<=7; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.WHITE);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.BLUE);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.GRAY);
			sequenz.get(5).setBackground(Color.ORANGE);
			sequenz.get(6).setBackground(Color.WHITE);
		}
			
		
		if (anzQuadrate==8) {
			for (int i =1; i<=4; i++) {
			sequenz.add(new JPanel());
			}
			sequenz.get(0).setBackground(Color.MAGENTA);
			sequenz.get(1).setBackground(Color.RED);
			sequenz.get(2).setBackground(Color.GRAY);
			sequenz.get(3).setBackground(Color.YELLOW);
			sequenz.get(4).setBackground(Color.WHITE);
			sequenz.get(5).setBackground(Color.BLACK);
			sequenz.get(6).setBackground(Color.BLUE);
			sequenz.get(7).setBackground(Color.ORANGE);
		}		
	}
	*/

	//Methoden der Klasse Sequenz
	
	//prasentieren bekommt ein window übergeben und muss auf diesem die Sequenz anzeigen
	
	public void praesentieren(Window window) throws InterruptedException {
		
		Window w = window;
		
		this.sequenz.get(0).setVisible(true);
	//	this.sequenz.get(0).setPreferredSize(new Dimension(10, 10));
	//	this.sequenz.get(0).setMaximumSize(new Dimension(10, 10));
		w.add(this.sequenz.get(0), BorderLayout.CENTER);
		w.validate(); 
		Thread.sleep(1000);
		this.sequenz.get(0).setVisible(false);
		Thread.sleep(1000);
		w.remove(this.sequenz.get(0));
		
		this.sequenz.get(1).setVisible(true);
	//	this.sequenz.get(1).setPreferredSize(new Dimension(10, 10));
		
		w.add(this.sequenz.get(1),BorderLayout.CENTER); 
		w.validate();
		Thread.sleep(1000);
		this.sequenz.get(1).setVisible(false);
		Thread.sleep(1000);
		w.remove(this.sequenz.get(1));
		
		this.sequenz.get(2).setVisible(true);
	//	this.sequenz.get(2).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(2),BorderLayout.CENTER); 
		w.validate();
		Thread.sleep(1000);
		this.sequenz.get(2).setVisible(false);
		Thread.sleep(1000);
		w.remove(this.sequenz.get(2));
		
		this.sequenz.get(3).setVisible(true);
	//	this.sequenz.get(3).setPreferredSize(new Dimension(10, 10));
		w.add(this.sequenz.get(3),BorderLayout.CENTER); 
		w.validate();
		Thread.sleep(1000);
		this.sequenz.get(3).setVisible(false);
		Thread.sleep(1000);
		w.remove(this.sequenz.get(3));

		
		}
	}
 
Ich habe versucht meine Methode prasentieren() radikal zu vereinfachen indem ich eine for-Schleife verwende. Leider gibt es nur einen Schleifendurchlauf. Die Abbruchbedingung habe ich, denke ich, richtig verwendet.

Java:
	public void praesentieren(Window window) throws InterruptedException {
		
		Window w = window;
		
		for (j=0; j<=a; j++){
		
		this.sequenz.get(j).setVisible(true);
	//	this.sequenz.get(j).setPreferredSize(new Dimension(10, 10));
	//	this.sequenz.get(j).setMaximumSize(new Dimension(10, 10));
		w.add(this.sequenz.get(j), BorderLayout.CENTER);
		w.validate(); 
		Thread.sleep(1000);
		this.sequenz.get(j).setVisible(false);
		Thread.sleep(1000);
		w.remove(this.sequenz.get(j));
 

Neue Themen


Zurück
Oben