Methoden JPanel nach clearAll() und add neu zeichnen

gamebreiti

Mitglied
Hallo,

vielleicht könnt ihr mir helfen. Bin am verzweifeln. Habe gegoogelt und im Forum rauf und runter gesucht. Aber ich komme einfach nicht auf die Lösung meines Problems.
Also... ich habe eine GUI geschrieben nun möchte ich ein JPanel mit 3 JLabels füllen. Die benötigten Daten für die JLabels kommen aus einer Liste (Bilder). Soweit so gut alles kein Problem.
An den einzelnen JLabels hängt nun ein MouseListener dran.
Nun möchte ich ein beliebiges der drei Labels anklicken.
daraufhin soll der Name des Labels aus der Liste entfernt werden und auch das entsprechende Label nicht mehr angezeigt werden.

Auf Baisis der neuen, kürzeren Liste soll das JPanel mit den nur noch zwei JLabels neu gezeichnet werden.

Soweit die Situation. Alles klappt ... AUßER!!!! Beim neuzeichnen des JPanels bleiben die JLabels im Hintergrund, da das JPanel auf einem JFrame liegt wird scheinbar der JFrame über das Panel gezeichnet.

Um zu überprüfen, ob der Rest auch sicher funktioniert habe ich die JLabels durch JButtons ersetzt. Nun werden die Buttons beim houvern sichtbar, aber eben erst dann.

Wie kann ich JPanel zwingen sich sofort neu zu zeichnen und nicht erst wenn ein Event wie Mouseover passiert.
Ich habe in der API gelesen, dass JPanel zuerst alles offscreen neuzeichnet.

Mit override hab ich es auch probiert, jedoch erben meine Klassen nur von Object.

Hier der Code: Die Probleme liegen vermutlich in Spiel 177ff und Handkarten 52ff sowie innere klasse Wahl

Java:
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Spiel extends Iskaar_Start implements Bilder{
	
	static JFrame plan;
	static String name;
	
	// Dienstvariabeln
	
	static int aktuelleHandkartenZahl = 1;
		
	//Variabeln Aktionen
	
	public static int zug = 1;
	public static int geld = 0;
	public static int kauf = 1;
	public static int muenzen = 0;
	public static int bankbetrag = 0;
	
	//Variabeln Nachziehstapel
	
	public static ArrayList<String> listnz;
	public static JButton nz;
	
	// Variabeln Handkarten
	
	public static JPanel handkarten = new JPanel(); //
	public static List<String> handk = new ArrayList<String>();
	public static JPanel block = new JPanel(new GridLayout((handk.size()+1),0));
	
	
	//Variabeln Ablagestapel
	
	public static ArrayList<String> listabl = new ArrayList<String>();
	public static JLabel abl = new JLabel();

	// AktionPanelVariabeln
	
	public static JLabel geldzuege;
	public static JLabel zuege; 
	public static JLabel gespGeld;
	public static JLabel kaeufe;
	
	
	// Variabeln für Tischmitte
	
	public static List<Icon> bildtemp = new ArrayList<Icon>();
	public static JPanel mitteBlock;
	public static List<String> listGespielteKarte = new ArrayList<String>();
	public static List<JButton> gespielteKarte = new ArrayList<JButton>();
	public static JButton karte[];
	private static JPanel mitteTisch ;
	
	//Variable KaufenButtons
	
	public static JButton abheben;
	public static JButton einzahlen;
	public static JButton kaufen;
	
	//Variable Bank
	
	public static JLabel bank = new JLabel();
	
	//Variabeln Scoretablaeu
	
	public static JLabel tpmarker = new JLabel();
	public static JLabel abtmarker = new JLabel();
	public static int schritte = 0;
	
	//Konstruktor
	public Spiel(){
		
	}
	//Spielerkarten geben
    public static void startmischen(){
	//1) Startkarten
    listnz = new ArrayList<String>();
    listnz.add("g1");
    listnz.add("g1");
    listnz.add("g1");
    listnz.add("g1");
    listnz.add("t");

	//2) Startkarten mischen
	Collections.shuffle(listnz);
	
	//3) Handkarten austeilen
	{int handkartenAnzahl = 3;
	if (listnz.size()< handkartenAnzahl)
		handkartenAnzahl = listnz.size();
	handk.addAll(listnz.subList(0,handkartenAnzahl));}
	}
    //4) Nachziehstapel erzeugen
	public static void nachziehstapelErzeugen(){
		    
			if (listnz.size() < 3){
				listnz.addAll(listabl); 
			}
			int y = 0;
			int handkartenAnzahl = 3;
			if (listnz.size()< handkartenAnzahl)
				handkartenAnzahl = listnz.size();
			while(y<handkartenAnzahl){
				if(listnz.size()>1)
				listnz.remove(y);
	    	y++;
			}	    	
			nz =(new JButton(ausruest[33]));
		    nz.setLayout(null);
		    nz.setBounds(264,620,66,100);
		    nz.setToolTipText(""+ listnz.size());
		    plan.add(nz);
	}    	
	
	public static void ablagestapelbearbeiten(){
		abl.setVisible(true);
	}
public static void gamerun()	{
	
	zug = 1;
	plan = new JFrame(spieleranzahl + " Spielerspiel");
	plan.setBounds(0,0,1024,768);
	plan.setUndecorated(true);
	plan.setLayout(null);
	
	// Panel fuer Hintergrundfarbe
	
	JPanel back = new JPanel();
	back.setSize(1024,768);
	back.setBackground(Color.BLACK);
	
	JLabel bild = new JLabel(bilder[6]);
	bild.setBounds(0,0,1000,750);
	
	// Erzeugen aller Komponenten und hinzufügen
	
	AufbauVorratsstapel.mischen();
	AufbauVorratsstapel.neuesBrett();
	startmischen();
	nachziehstapelErzeugen();
	buildTischMitte();
	AufbauVorratsstapel.bankAnzeigen();
	kartenhandGeben();
	aktionPanelerstellen();
	
	plan.add(bild);
	plan.add(back);
	plan.setVisible(true);
}
// Panel in Tischmitte erzeugen

public static void buildTischMitte(){

GridLayout mitte = new GridLayout();
mitteTisch = new JPanel(mitte);
mitteTisch.setBounds(272,336,453,166);
mitteTisch.setBackground(null);
mitteTisch.setLayout(new GridLayout(1,0));
mitteTisch.setBackground(new Color(0,0,0,0));
mitteTisch.setVisible(false);
plan.add(mitteTisch);
}

// Buttons für Kartenhand im Panel erzeugen !!!!!UND HIER !!!!!!

public static void  kartenhandGeben(){

 System.out.println("Karten gegeben");
 System.out.println("Ausgespieltes Geld: " + muenzen);
 int x = handk.size();
 block = Handkarten.erstellen(x);
 plan.add(block);

}
// Kartentyp und verfügbare Zuege prüfen
public JFrame getPlan(){
		return plan;
	}
public JPanel getBlock(){
	return Spiel.block;
}

//Panel für Aktionen erstellen
public static void aktionPanelerstellen(){
	
geldzuege = new JLabel();
geldzuege.setText(" Geldzüge: "+ geld);
geldzuege.setFont(new Font("Papyrus", Font.BOLD,16));
geldzuege.setForeground(Color.WHITE);
geldzuege.setBackground(Color.GRAY);
geldzuege.setOpaque(true);
zuege = new JLabel ();
zuege.setText(" Züge:          "+ zug);
zuege.setFont(new Font("Papyrus", Font.BOLD,16));
zuege.setForeground(Color.WHITE);
zuege.setBackground(Color.GRAY);
zuege.setOpaque(true);
gespGeld = new JLabel ();
gespGeld.setText(" Münzen:    "+ muenzen);
gespGeld.setFont(new Font("Papyrus", Font.BOLD,16));
gespGeld.setForeground(Color.WHITE);
gespGeld.setBackground(Color.GRAY);
gespGeld.setOpaque(true);
kaeufe = new JLabel();
kaeufe.setText(" Käufe:       "+ kauf);
kaeufe.setFont(new Font("Papyrus", Font.BOLD,16));
kaeufe.setForeground(Color.WHITE);
kaeufe.setBackground(Color.GRAY);
kaeufe.setOpaque(true);

GridLayout akt = new GridLayout();
final JPanel aktionPanel = new JPanel(akt);
aktionPanel.setBounds(35,325,100,120);
aktionPanel.setBackground(null);
aktionPanel.setLayout(new GridLayout(4,0));
aktionPanel.setBackground(new Color(0,0,0,0));
aktionPanel.add(geldzuege);
aktionPanel.add(zuege); 
aktionPanel.add(gespGeld);
aktionPanel.add(kaeufe);
plan.add(aktionPanel);
aktionPanel.repaint();
plan.repaint();

//ScoreTableau

tpmarker = new JLabel();
tpmarker.setIcon(bilder[18]);
tpmarker.setBounds(68,615,25,25);
plan.add(tpmarker);

abtmarker = new JLabel();
abtmarker.setIcon(bilder[18]);
if(schritte == 0){
abtmarker.setBounds(104,695,25,25);
plan.add(abtmarker);
}
}
public static void laufen(){
	if(schritte == 1)
		abtmarker.setBounds(107,670,25,25);
		if(schritte == 2)
			abtmarker.setBounds(111,641,25,25);
			if(schritte == 3)
				abtmarker.setBounds(116,614,25,25);
				if(schritte == 4)
					abtmarker.setBounds(121,587,25,25);
					if(schritte == 5)
						abtmarker.setBounds(93,578,25,25);
						if(schritte == 6)
							abtmarker.setBounds(65,568,25,25);
						
}


// Panel für Gespielte Karten
// Gespielte Karten aus Hand entfernen und in Tischmitte legen
public static void karteGespielt(Icon b,int k){

	mitteTisch.setVisible(true);
	gespielteKarte.add(karte[k]);
	karte[k]= new JButton(bildtemp.get(k));
	karte[k].setLayout(new GridLayout());
	karte[k].setBackground(null);

	if (handk.get(k).startsWith("g")){
		einzahlen.setVisible(true);
		abheben.setVisible(true);
		}
	if (handk.get(k).startsWith("g")&& geld > 0){geld--;}
	else{zug--;}
	mitteTisch.add(karte[k]);
}
}

und die zweite Klasse
Java:
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JPanel;

public class Handkarten extends Spiel implements Bilder{
	
	//Variabeln aktueller Karte
	private static List<String> houver = new ArrayList<String>();
	private static List<String> aktuellerKartenName = new ArrayList<String>();
	
	// Objekt für MouseListener
	static Wahl waehlen = new Wahl();
	
	//Hilfsvariabeln
	public static String name;
	
    //Handkarten Panel(Karten geben)
public static JPanel erstellen(int anzahl){
		
	int k = anzahl;
	int i = 0;
	
	 handkarten = new JPanel();
	 handkarten.setBounds(335,585,320,150);
	 handkarten.setLayout(new GridLayout());
	 handkarten.setBackground(new Color(0,0,0,0));
	 plan.add(handkarten);
	 
	karte = new JButton[k]; 

    while(i < k){  
    	
    	getKarteInfo(i);
    	karte[i]  = new JButton(bildtemp.get(i)); 
     	karte[i].setSize(200,330);
    	karte[i].setBackground(null);
        karte[i].addMouseListener(waehlen);
        handkarten.add(karte[i]);
        i++;    
    } 
    plan.add(handkarten);
    return handkarten;
}
// Handkarten aktualisieren           !!!!!     HIER LIEGT WAHRSCHEINLICH DAS PROBLEM !!!!!!
public static void handkartenRefresh(){
	
	handkarten.removeAll();
	bildtemp.clear();
	houver.clear();
	aktuellerKartenName.clear();
	Spiel.kartenhandGeben();
	plan.add(handkarten);

}

	//Karten Infos, Bilder und Houvertexte holen
public static void getKarteInfo(int i){
	setName(i);
	if ( getName().equals(Karte.holeName())){
		aktuellerKartenName.add(Karte.holeName());
		bildtemp.add(Karte.holeBild(Karte.holeName())); 
		houver.add(Karte.holeInfo(Karte.holeName()));
		}
}
// Kartenname auf Handkarten positionieren
public static void setName(int i){
	name = Spiel.handk.get(i);;
} 
// positionierten Kartenname zurück geben
public static String getName(){
	return name;

}
// MouseListener der Handkarten
private static class Wahl implements MouseListener{

	@Override
	public void mouseClicked(MouseEvent event) {
		if(geld > 0 || zug > 0){
			int position = 0;
			while(position < handk.size()){
			
				if ( (event.getSource().equals(karte[position]))){
					
		 				if ((geld > 0||zug > 0)&& aktuellerKartenName.get(position)!= "t")	
		 				{
		 					if ((aktuellerKartenName.get(position)).startsWith("g")||zug > 0  ){
		 					Spiel.karteGespielt(bildtemp.get(position), position); 
		 					Karte.holeAktion(position, aktuellerKartenName.get(position));
		 					listGespielteKarte.add(handk.remove(position));
		 					System.out.println("Listenname wurde in Tischmitte geschrieben");
		 					}
		 					for(int zaehler = 0;zaehler < handk.size(); zaehler ++)
		 						System.out.println("In Hand: " + handk.get(zaehler)); 
		 					handkartenRefresh(); 
		 					}
		 				else{}
		 			position = handk.size();
				}
				else
				position++;
			} 
		}
		plan.repaint();
	}
	@Override
	public void mouseEntered(MouseEvent event) {
		

		int position = 0;
		while(position < handk.size()){
			
			if ( (event.getSource().equals(karte[position])))
				karte[position].setToolTipText(houver.get(position));		 
			position++;
		}		 
	} 
	@Override
	public void mouseExited(MouseEvent event) {
		
	}
	
	@Override
	public void mousePressed(MouseEvent event) {
	
	}

	@Override
	public void mouseReleased(MouseEvent event) {
			
	}
	
}

}

Ich hab mal beide Quelltexte komplett gelassen, da das Problem eventuell auch irgendwo anders steckt.

Falls est doch nur mit override von paint geht .. wäre eine genaue Beschreibung wichtig ... BITTE !!!

Vielen Dank im Vorraus

Breiti
 
Hallo liebe Community,

auch wenn ich hier keine Antwort auf meine Frage erhalten habe, möchte ich dennoch Anderen Usern mit ähnlichen Problemen helfen.
Nach meiner verzweifelten Suche zur Lösung meines Problems, bin ich endlich selbst auf die Lösung gestossen.

Es war ein Semmantischer Fehler. Die Codezeilen Spiel 34 und Spiel 59 fügen das JPanel handkarten dem JFrame plan
hinzu. Das ist falsch, da bei jedem Aufruf der Methode handkartenRefresh() das JPanel unter das alte leere Panel gezeichnet wird.

Die Lösung war nun diese beiden Zeilen zu entfernen und stattdessen die Anweisung
Code:
plan.add(handkarten);
an die Stelle
Zeile 155 in der Klasse Spiel einzufügen.
Java:
AufbauVorratsstapel.mischen();
	AufbauVorratsstapel.neuesBrett();
	startmischen();
	nachziehstapelErzeugen();
	buildTischMitte();
	AufbauVorratsstapel.bankAnzeigen();
	kartenhandGeben();
	aktionPanelerstellen();
	
	plan.add(handkarten);
	plan.add(bild);
	plan.add(back);
	plan.setVisible(true);
}

Jetzt wird das JPanel nur einmal zum Zeitpunkt seiner Erzeugung dem JFrame hinzugefügt.

...TaTa.... und nun funktioniert es so wie es soll

Möge der Bug nie mit euch sein :idea:


Breiti
 
Zuletzt bearbeitet:

Zurück
Oben