# JPanel zeichnet Inhalt erst nach Größenänderung des JFrames



## Nova (23. Jul 2005)

Hallo,

Kurze Erläuterung zum Programm:
Wenn man auf den Button "Blocking einfügen" drückt wird ein JPanel erstellt welches später verschiedene weitere Objekte haben Kann (Labels, Buttons,...).
Sobald man dann in die rechte Hälfte des SplitPanes kommt mit der Maus "klebt" das Panel am Mauszeiger, wenn man die linke Maustaste drückt wird das Panel an dieser Stelle "abgelegt".

Ich habe das ganze zuerst mit einem JTextField und einem JLabel probiert => funktioniert einwandfrei!
Jetzt möchte ich aber ein Panel haben, da es ja wie gesagt später weitere Objekte enthalten soll.
Das Panel klebt auch am Mauszeiger (sieht man weil die Background-Color des Panels grau ist, wenn ich die weiß mache sieht man nix), aber der Inhalt wird aber nicht "gemalt". 
Erst wenn ich die Größe des JFrames ändere taucht der Text auf, verschieben des JFrames hilft hingegen nicht.

Hier der Code:

```
package visualDBLPQ;

import javax.swing.*;

import java.awt.*;
import java.awt.event.*;

public class FilterPage extends JFrame{
	
	JPanel filterPanel = new JPanel();
	JPanel controlPanel = new JPanel();
	JSplitPane splitPane = new JSplitPane();
	JScrollPane scrollPane = new JScrollPane(filterPanel);
	JButton createBlockingButton = new JButton("Blocking einfügen");
	JButton createFilterButton = new JButton("Filter einfügen");
	JButton createConnectionButton = new JButton("Verbindung einfügen");
	//JPanel currentElement = null;
	JLabel currentElement = null;
	

	public static void main(String[] args) {
		new FilterPage();
	}
	
	public FilterPage(){
		super("Visual DBLPQ Filter Page");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(800,600);
		Container contentPane = getContentPane();
	
		createBlockingButton.setPreferredSize(new Dimension(160,30));
		createFilterButton.setPreferredSize(new Dimension(160,30));
		createConnectionButton.setPreferredSize(new Dimension(160,30));
	
		JPanel p1 = new JPanel();
		p1.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));
		p1.setBackground(Color.WHITE);
		p1.setPreferredSize(new Dimension(200,200));
		p1.add(createBlockingButton);
		p1.add(createFilterButton);
		p1.add(createConnectionButton);
		
		addActionListeners(); // ActionListener für Buttons hinzufügen
		
		createFilterButton.setEnabled(false);
		createConnectionButton.setEnabled(false);
		
		controlPanel.setBackground(Color.WHITE);
		controlPanel.setLayout(new BorderLayout());
		controlPanel.add(p1, BorderLayout.NORTH);
		
		filterPanel.setBackground(Color.WHITE);
		filterPanel.setLayout(null);
		
		splitPane.setDividerLocation(200);
		splitPane.setLeftComponent(controlPanel);
		splitPane.setRightComponent(scrollPane);
		contentPane.add(splitPane);
		
		this.setVisible(true);
	}
	
	private void addActionListeners(){
		createBlockingButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				JLabel t = new JLabel("test");
				//JPanel panel = new JPanel();
				//panel.add(t);
				//currentElement = panel;
				currentElement = t;
			}
		});
		
		filterPanel.addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent e){
				if (e.getButton() == MouseEvent.BUTTON1 && currentElement != null){
					currentElement.setBounds(e.getX(),e.getY(),140,60);
					filterPanel.add(currentElement);
					filterPanel.repaint();
					currentElement = null;
				}
			}
			public void mouseExited(MouseEvent e){
				if (currentElement != null){
				    filterPanel.remove(currentElement);
				    filterPanel.repaint();
				}
			}
		});
		
		filterPanel.addMouseMotionListener(new MouseMotionAdapter(){
			public void mouseMoved(MouseEvent e){
				if (currentElement != null){
					currentElement.setBounds(e.getX(),e.getY()+1,140,60);
					filterPanel.add(currentElement);
					filterPanel.repaint();
				}
			}
		});
	}

}
```

Das ist der Code mit einem JLabel, funktioniert wie gesagt auch.
Wenn ich jetzt jedoch Zeile 67-69 nehme und Zeile 70 auskommentiere (ausserdem noch Zeile 18 statt Zeile 17), dann habe ich ein JPanel welches ein JLabel enthält. Das JPanel "klebt" am Mauszeiger und kann ich auch ablegen, der Inhalt wird aber wie gesagt erst bei Größenänderung des Frames gezeichnet.


Hat jemand einen Tipp für mich wo das Problem liegen könnte?


mfg
Christian


EDIT:
Wie ich gerade bemerkt habe reicht es auch den Divider des JSplitPanes zu bewegen damit der Inhalt gezeichnet wird.


----------



## lin (23. Jul 2005)

ersetz mal die Zeile 79

```
filterPanel.repaint();
```
durch

```
filterPanel.validate();
```

PS: und natürlich dasselbe in den mouseMoved- und  mouse Exited- Methoden


----------



## Nova (23. Jul 2005)

Hallo,

Ich habs jetzt hinbekommen: Wenn ich

```
filterPanel.paintComponents(filterPanel.getGraphics());
```
im MouseMotionListener hinzufüge funktioniert es.
Kann mir jemand sagen wo der Unterschied zwischen repaint() und paintComponents() ist?


Gibt es eigentlich eine "schönere" Methode das Panel an der Maus kleben zu lassen? 
Momentan füge ich es ja im filterPanel hinzu und ändere ständig die Position, es wäre natürlich schöner wenn das Panel wirklich nur an der Maus hängen würde und erst beim Klick dem filterPanel hinzugefügt würde...


mfg
Christian


----------



## Nova (23. Jul 2005)

Hallo,

validate() funktioniert auch!

Ich fange gerade erst an mit GUI-Komponenten, irgendwie hab ich da noch nicht wirklich den Durchblick...
Überhaupt mal die passende Methode zu finden ist schon fast unmöglich (JPanel hat schon mehrere hundert Methoden wenn ich nach der JavaDoc gehe)...


mfg
Christian


----------

