Swing Zur Laufzeit hinzegfügte Komponenten nicht sofort sichtbar?!

ElJarno

Bekanntes Mitglied
Hi Leute,
diese Problem hatte ich schon öffters bei der Änderung von der TableModel oder der JTable an sich. Es geht halt darum, dass ich zur Laufzeit durch betätigen eines Buttons oder etwas anderem ich irgendwelche Komponten einem JPanel neu hinzufügen möchte. Diese sind dann ebr nicht sofort sichtbar und erscheinen erst wenn man die Fenstergröße ändert. Wie gesagt bei TableModle konnte ich das durch die FireStrcuturChanged-Methode umgehen. JPanel bietet aber nur FirePropertyChanged an. Diese meine ich würde mir nichts bringen bzw. weiß ich dann nicht welche Werte ich dort mitgeben muss. Kann mir vlt. Jemand mal erklären woran das leigt und wie man so was generell umgeht oder behandelt.
Hier mal ein Testcode wo dieses Problem genau auftritt. Mit pack() konnte ich dieses Problem auch nicht beheben.
Java:
package schrott;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JButton jButton = null;
	private JPanel jPanel = null;

	public Test() {
		super();
		initialize();
		this.setSize(300, 200);
		this.setContentPane(jContentPane);
		this.setTitle("JFrame");
	}

	private void initialize() {
		jPanel = new JPanel();
		jPanel.setLayout(new FlowLayout());
		jButton = new JButton();
		jButton.addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent e) {
				jPanel.add(new JButton("Test"));
			}
		});
		jContentPane = new JPanel();
		jContentPane.setLayout(new BorderLayout());
		jContentPane.add(jButton, BorderLayout.NORTH);
		jContentPane.add(jPanel, BorderLayout.CENTER);
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Test test = new Test();
				test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				test.setVisible(true);
			}
		});
	}
}

Gruß Jan🙂
 
je nach dem wo du etwas geändert hast, musst du auf dem Panel oder dem Frame ein repaint() oder revalidate aufrufen (könnte auch nur validate sein). Probiers mal aus. welches es genau ist, weiß ich jetzt nicht.

Zu deinem TableModel-Problem: einfach ein FireTableStructureChanged aufrufen ist mit Kanonen auf Spatzen geschossen. Je nach dem, Ob du Daten komplett änderst, hinzufügst, oder sonst was gibt es auch die Methoden fireTableDataChanged, fireTableDataInserted, usw., Nimm lieber die. Bei deiner Methode wird die komplette Tabelle neu gezeichnet und damit gehen dir evtl auch Formatierungen und Sortierungen verloren.

Nicht zu vergessen ist, dass du einen solchen Aufruf nicht direkt machen solltest, sondern alles was Änderungen der Oberfläche bewirkt sollte in die EventQueue eingereiht werden.
 
Also ein pack() hätte doch zumindest den Button sichtbar machen sollen oder? (auch wenn dadurch die Größe dann komplett angepasst wären würde).
Ansonsten hilft ein
Code:
revalidate();
nach
Code:
jPanel.add(...);
 
Jo mit validate hats geklappt. Danke an dieser Stelle.

Nicht zu vergessen ist, dass du einen solchen Aufruf nicht direkt machen solltest, sondern alles was Änderungen der Oberfläche bewirkt sollte in die EventQueue eingereiht werden.

Wie genau funktioniert denn sowas?bzw. wie wirds gemacht.

Gruß Jan
 
So wie du es auch schon in deiner main getan hast:
Java:
 SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // ...
            }
        });

oder
Code:
EventQueue.invokeXXX()

allerdings wird der Code der Listener eh auf dem EDT ausgeführt !
 

Zurück
Oben