JLabel, JTextArea, JScrollPane. repaint(); ?

cronkalonca

Mitglied
Mahlzeit.

Folgendes Problem 🙂

Ich zeichne in einem Applet eine Tile-Map. Das ganze mach ich mit einem einfach Array und entsprechenden JLabels, die die Bilder enthalten.

Am unteren linken Bildschirmrand habe ich ein JPanel, indem sich eine JTextArea mit einem JScrollPane befindet.

Wenn ich nun Text in die TextArea einfügen möchte, dann wird der Hintergrund der TextArea mit Teilen der TileMap gefüllt. Dadurch entstehen seltsame Bilder im Hintergrund des Chats.

Hier die wichtigen Codeschnipsel:

Java:
chat_panel = new JPanel();
chat = new JTextArea(6, 30);
scroll = new JScrollPane();
scroll.setViewportView(chat);

chat_panel.add(scroll);
content.add(chat_panel);

Bei Tastendruck(zu Testzwecken) wird folgendes gemacht:

Java:
chat.append("chat.append("Du hast den blauen Kristall gefunden! \nEr befindet sich nun in Deiner Tasche! \nDu kannst die Tasche mit 'b' öffnen \nbla")");
chat.setCaretPosition(chat.getText().length());
chat.repaint();

Die JPanel, JScrollPane und JTextArea werden noch optisch bearbeitet mit setBackground etc. Denke aber das tut nichts zur Sache.

hier noch einmal ein Bild wie der chat zu Beginn aussieht:
chat1.JPG


nach mehreren 'appends' siehts so aus:
chat2.JPG


Hoffe Ihr habt eine Idee wodran es liegen kann.

Danke schonmal.
 
Ok, dann hier mal ein Ausschnitt von der Schleife mit der ich das Level zeichne.

In der init() lade ich alle Panels etc. ganz zum Schluss führe ich die Funktion Lade-Level() aus.

Hier die Funktion Lade_Level();
Java:
for(int i=0; i<lvlbreite; i++)
{
	for(int j=0; j<lvlhoehe; j++)
	{
             labels[i][j].setBounds(i*feldbreite, j*feldhoehe, feldbreite, feldhoehe);
             labels[i][j].setIcon(stein);
	     content.add(labels[i][j]);
        }
}

Ich weiss nicht ob es da zu Problemen kommen kann, weil ich alles mit JLabels zeichne und nicht über die paint()-Methode, aber alles andere läuft einwandfrei.
 
ist denn die JTextArea mit ihrem JScrollPane über den JLabels?

und ich finde es immer ärgerlich, so kurze Postings schreiben zu müssen,
du hast stundenlang soviel Zeit, poste doch viele viele viele Infos 😉
ganzen Code usw.
 
Ok, mal etwas ausführlicher
Java:
public void init()
	{		
		content = getContentPane();
		content.setLayout(null);
			
		labels = new JLabel[lvlbreite][lvlhoehe]; //Label-Array das alle Labels enthält die gebraucht werden um das ganze level zu zeichnen

		kamera = new Rectangle(0, 0, 768, 512);
		
			
		chat_panel = new JPanel();
		chat_panel.setBounds(0, 412, 450, 200);
		chat_panel.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.0f));
		chat_panel.setForeground(new Color(1.0f, 1.0f, 1.0f, 0.0f));
		chat_panel.setOpaque(true);
		
		chat = new JTextArea(6, 40);
		chat.setEnabled(false);
		chat.setBounds(0, 412, 400, 100);
		chat.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.4f));
		chat.setForeground(new Color(1.0f, 1.0f, 1.0f, 1.0f));
		chat.setOpaque(true);

		scroll = new JScrollPane();
		scroll.setViewportView(chat);
		scroll.setBackground(new Color(0.0f, 0.0f, 0.0f, 0.4f));
		scroll.setForeground(new Color(1.0f, 1.0f, 1.0f, 1.0f));
		scroll.setOpaque(true);
		scroll.setVisible(true);
			
		chat_panel.add(scroll);
			
		content.add(chat_panel);

		Bilder_laden();
	        Lade_Level(level1);
	
		addKeyListener (this);
		addMouseListener(this);
		addMouseMotionListener(this);
		
		kamera(kamera_x, kamera_y);
	}

bilder_Laden() lädt einfach nur ein paar Bilder, damit ich die zur Verfügung habe. level1 ist ein 2-dimensionales int-Array, in dem durch Zahlen bestimmt wird, was für ein Tile gezeichnet wird. Lade-Level schleift nun level1 durch und setzt für jede Zahl ein entsprechendes Label mit dem passenden Bild, um so die TileMap zusammenzubauen. ( siehe vorheriger Post )

Im Prinzip ganz simpel.
Das chat_panel sollte nun auf dem ganzen draufliegen und halb transparent sein um nicht zuviel Fläche zu verdecken.

Ich denke soweit ist das alles, hoffentlich hilft das weiter 🙂
 
durchsichtig heißt setOpaque(false); nicht setOpaque(true);

ansonsten denke ich nicht dass ich bei mehreren Komponenten übereinander groß etwas beitragen kann, denen habe ich noch nie getraut,
wenn überhaupt, dann mit paint() malen, was sich bei Bildern eh anbietet

du kannst noch mit 'hintergrundbild + jscrollpane' hier im Forum suchen, dürften aber nur paint()-Varianten kommen
 
Ich habe jetzt mal die ganze Sache umgebaut, jetzt zeichne ich mit der paint()-Methode meine TileMap und meine Spielfigur. Das ganze lässt sich nun gut scrollen und animieren. Ich kann jetzt aber nicht zusätzlich Komponenten wie JLabels "drüberzeichnen". paint() wird mit Hilfe eines Threads regelmäßig neugeladen um die Position des Spielers und die Spielfeldausrichtung zu ändern. Bei jedem Aufruf wird dann die Map über die Komponenten gezeichnet.
Ich öffnen zum Beispiel auf Knopfdruck ein JLabel, das als Inventar dient. Das wird nur solange angezeigt, bis paint() erneut aufgerufen wird. Gibt es da ne elegante Lösung?

Hier noch etwas Code zur Veranschaulichung:

paint():
Java:
public void paint(Graphics g)
    {

		for(int i=0; i<lvlbreite; i++)
		{
			for(int j=0; j<lvlhoehe; j++)
			{
				
				if(level1[i][j]==1)
				{
					bild2.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level1[i][j]==2)
				{
					bild3.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level1[i][j]==3)
				{
					bild4.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level1[i][j]==4)
				{
					bild5.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
			}
		}
		for(int i=0; i<lvlbreite; i++)
		{
			for(int j=0; j<lvlhoehe; j++)
			{
				
				if(level2[i][j]==1)
				{
					bild2.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level2[i][j]==2)
				{
					bild3.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level2[i][j]==3)
				{
					bild4.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
				if(level2[i][j]==4)
				{
					bild5.paintIcon(this, g, i*feldbreite+kamera_x, j*feldhoehe+kamera_y);
					recs[i][j] = new Rectangle(i*feldbreite+kamera_x, j*feldhoehe+kamera_y, feldbreite, feldhoehe);
				}
			}
		}

		if(steht)
		{
			spieler_steht.paintIcon(this, g, spielerposi_x, spielerposi_y);
		}
		if(rechts)
		{
			spieler_bilder_rechts[cnt].paintIcon(this, g, spielerposi_x, spielerposi_y);
		}
		if(links)
		{
			spieler_bilder_links[cnt].paintIcon(this, g, spielerposi_x, spielerposi_y);
		}
		if(runter)
		{
			spieler_bilder_runter[cnt].paintIcon(this, g, spielerposi_x, spielerposi_y);
		}
		if(hoch)
		{
			spieler_bilder_hoch[cnt].paintIcon(this, g, spielerposi_x, spielerposi_y);
		}

    }
run() um paint() regelmäßig aufzurufen
Java:
public void run()
	   {
	      cnt = 0;

	      while (true) {
	    	  repaint();
	         if(cnt ==7)
     		{
     			cnt=0;
     		}
     		else
     		{
     			cnt++;
     		}
	         try {
	            Thread.sleep(150);
	         } catch (InterruptedException e) {
	            //nichts
	         }
	      }
	   }

Wäre super wenn es da eine Lösung gibt. Danke schon mal.
 

Zurück
Oben