Repaint problem

socke999

Erfahrenes Mitglied
Hallo, ich habe ein problem beim Repaint.

und zwar habe ich ein JFrame, diese enthält meine eigene Klasse View
Code:
public class View extends JPanel {
	
	public static String ICONPATH = "graphics/icons/";
	private JScrollPane scrollPane;
	protected JTable table;
	
	private JPanel loadingPanel, contentPanel;
	
	protected String sql;
	
	
	private static long VIEW_ID_COUNTER = 0;
	
	public View()
	{
		super();
		this.setLayout(new BorderLayout());
		scrollPane = null;
		generateViewID();
		
		this.scrollPane = new JScrollPane();
		
		
		table = new JTable();
		this.table.setVisible(true);
		table.setAutoCreateRowSorter(true);
		this.setContent(table);
		
		
		
		
		// Loading
		GridBagLayout gbl = new GridBagLayout();
		GridBagConstraints gbc = new GridBagConstraints();

		this.loadingPanel = new JPanel(gbl);
		this.loadingPanel.setBackground(Color.white);
		
		JLabel label = new JLabel(new ImageIcon(View.ICONPATH+"loading.gif"));
		gbc.anchor = GridBagConstraints.CENTER;
		gbl.setConstraints(label,gbc);
		this.loadingPanel.add(label);
		
	}

        public void showLoading()
	{
		this.remove(scrollPane);
		this.add(loadingPanel, BorderLayout.CENTER);
		this.repaint();
	}
	
	public void showContent()
	{
		this.remove(loadingPanel);
		this.add(scrollPane, BorderLayout.CENTER);
		this.repaint();
	}
	
	public void setContent(Component component)
	{
		scrollPane.setViewportView(component);	
	}

	public void setToolBar(JToolBar tb)
	{
		this.add(tb, BorderLayout.NORTH);
	}

}

Also View ist meine Klasse, die von JPanel ableitet. Sie verwendet das BorderLayout. In Border.North kommt eine ToolBar (Methode setToolBar) und in die Mitte (BorderLayout.CENTER) soll entweder mein "loadingPanel" oder mein ScrollBar mit meinen JTable angezeigt werden. Das soll durch die Funktionene showLoading() --> loadingPanel und showContent() -->ScrollPane festgesetzt werden.

Das funktioniert aber nur Teilweise. Also wenn ich nun zum Beispiel so etwas mache:
Code:
public static void main(String[] args) {

		final JFrame frame = new JFrame("Test");
		
		View v = new View();
		

		// tabelle mit werten füllen die ich der Einfachheitshalber hier weck lasse
		
		frame.add(v);
		frame.setSize(800,600);
		frame.setVisible(true);
		
		frame.repaint();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		cv.showContent();
		
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("Fertig mit sleep ...");
		cv.showLoading();
		frame.repaint();
		
	}

Dann basiert folgendes...
Zu Begin sehe ich mein JFrame mit der ScrollPane, die dazugehörige Tabelle usw.
Bislang passt alles.

Dann mach ich mit Thread.sleep() eine verzögerung, und nach 2 Sekunden sollte nun anstelle der ScrollPane samt tabelle, mein "loadingPanel" angezeigt werden.

Dies funktioniert jetzt allerdings nun mehr nicht so ganz wie gewünscht.
Also, mit dem aufruf von cv.showLoading() nach dem sleep() wird die ScrollPane mit Tabelle entfernt, und ich sehe diese auch nicht mehr. Also der mittlere Abschnitt des Frames, dort wo die scrollPane war, wird zum Standard grau. Soweit noch ok.

Dann sollte aber allerdings gleich das "loadingPanel" angezeigt werden, dass klappt allerdings nicht. Es wird zwar im Hintergrund das "loadingPanel" richtig gesetzt, allerdings noch nicht gezeichnet. D.h. der Mittlere Abschnitt (BorderLayout.Center) ist immer noch Grau. Ändere ich jetzt ein bisschen die größe des Frames, dann sehe ich nun auch das "loadingPanel".
Also irgendwas scheint da beim Paint() bzw. repaint() nich zu klappen.

Ich glaube das liegt daran das, der Thread der zeichnet und daten setzt in Swing der gleiche ist und dort etwas schief läuft. Muss man da vielleicht mit Swing.invokeLater() was machen? Oder ist das prinzipiell ein Fehler von mir?
 
doch würd ich eigentlich schon machen, mit
frame.repaint();
am ende in der Main-funktion

ich habe nun frame.getContentPane().validate() anstelle des repaints() eingefügt und soweit klappts.

was genau ist eigentlich der unterschied zwischen frame.add() und frame.getContentPane().add() ?
 
was genau ist eigentlich der unterschied zwischen frame.add() und frame.getContentPane().add() ?

Hi,

mit frame.getContentPane() holst du dir das Panel mit dem Inhalt. So musste man es vor java 1.5 machen, erst mit 1.5 kann man das direkt über frame.add() machen. In deinem Code bedeutet das
also, dass er abwärtskompatibel zu 1.4 oder älter ist.

Gruß
BK
 
Zurück