# [Swing] GUI zur Laufzeit ändern



## multiholle (25. Mrz 2009)

Ich möchte meine Oberfläche zu Laufzeit anpassen. Dazu wird beim Klick mit der rechten Maustaste ein Kontextmenü geöffnet, in dem man eine Komponente auswählen kann, die dann in die Oberfläche eingefügt wird. Das funktioniert bis auf zwei Probleme ganz gut:

I: Warum funktionieren die beiden auskommentierten Zeilen (58/59) nicht? Es soll jedem Panel wieder der gleiche MouseListener hinzugefügt werden.
II: Warum ist das erzeugte SplitPane, sowie die enthaltenen Buttons winzig klein? Sie sollten das aktuelle Fenster genau teilen.

[highlight="java"]
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;

public class CustomWindowNG extends JFrame implements MouseListener {
	public CustomWindowNG() {
		JPanel panel = new JPanel();
		panel.addMouseListener(this);
		getContentPane().add(panel);

		setTitle("CustomWindowNG");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setMinimumSize(new Dimension(200,200));
		pack();
		setVisible(true);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		if (!e.isPopupTrigger()) return;
		final JPanel src = (JPanel) e.getSource();

		JPopupMenu menu = new JPopupMenu();
		final String[] items = {"SplitPane top/bottom", "SplitPane left/right", "Player", "Library"};

		for (String s : items) {
			menu.add(new AbstractAction(s) {
				@Override
				public void actionPerformed(ActionEvent e) {
					String action = e.getActionCommand();
					// SplitPane Horizontal
					if (action.equals(items[0])) {
						JPanel panel1 = new JPanel();
						JPanel panel2 = new JPanel();
						//panel1.addMouseListener(this);
						//panel2.addMouseListener(this);
						JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel1, panel2);
						src.add(splitPane);
						src.validate();
					}
				}
			});
		}

		menu.show(src, e.getX(), e.getY());
	}

	public static void main(String[] args) {
		new CustomWindowNG();
	}
}
[/highlight]


----------



## Hadernlump (25. Mrz 2009)

multiholle hat gesagt.:


> II: Warum ist das erzeugte SplitPane, sowie die enthaltenen Buttons winzig klein? Sie sollten das aktuelle Fenster genau teilen.



Weil sie nach den FlowLayout angeordnet werden würd ich auf den ersten Blick sagen.

Gruß Hadernlump


----------



## max40 (25. Mrz 2009)

multiholle hat gesagt.:


> Ich möchte meine Oberfläche zu Laufzeit anpassen. Dazu wird beim Klick mit der rechten Maustaste ein Kontextmenü geöffnet, in dem man eine Komponente auswählen kann, die dann in die Oberfläche eingefügt wird. Das funktioniert bis auf zwei Probleme ganz gut:
> 
> I: Warum funktionieren die beiden auskommentierten Zeilen (58/59) nicht? Es soll jedem Panel wieder der gleiche MouseListener hinzugefügt werden.




Weil das this auf den Action verweist da du dich in einer InnerKlass befindest


----------



## multiholle (25. Mrz 2009)

max40 hat gesagt.:


> Weil das this auf den Action verweist da du dich in einer InnerKlass befindest


Was schreibe ich denn stattdessen darein? Bei "addMouseListener(CostumWindowNG)" sagt er mir "... can not be resolved".


----------



## Bartleby (25. Mrz 2009)

multiholle hat gesagt.:


> Was schreibe ich denn stattdessen darein? Bei "addMouseListener(CostumWindowNG)" sagt er mir "... can not be resolved".



CustomWindowNG.this


----------



## Hadernlump (25. Mrz 2009)

CustomWindowNG.this statt this


----------



## max40 (25. Mrz 2009)

[HIGHLIGHT="Java"]import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSplitPane;

public class CustomWindowNG extends JFrame implements MouseListener {
	public CustomWindowNG() {
		final JPanel panel = new JPanel(new BorderLayout());
		panel.addMouseListener(this);
		getContentPane().add(panel);

		setTitle("CustomWindowNG");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setMinimumSize(new Dimension(200, 200));
		pack();
		setVisible(true);
	}

	@Override
	public void mouseClicked(final MouseEvent e) {
	}

	@Override
	public void mouseEntered(final MouseEvent e) {
	}

	@Override
	public void mouseExited(final MouseEvent e) {
	}

	@Override
	public void mousePressed(final MouseEvent e) {
	}

	@Override
	public void mouseReleased(final MouseEvent e) {
		if (!e.isPopupTrigger()) {
			return;
		}
		final JPanel src = (JPanel) e.getSource();

		final JPopupMenu menu = new JPopupMenu();
		final String[] items = { "SplitPane top/bottom",
				"SplitPane left/right", "Player", "Library" };

		for (final String s : items) {
			menu.add(new AbstractAction(s) {
				@Override
				public void actionPerformed(final ActionEvent e) {
					final String action = e.getActionCommand();
					// SplitPane Horizontal
					if (action.equals(items[0])) {
						final JPanel panel1 = new JPanel(new BorderLayout());
						final JPanel panel2 = new JPanel(new BorderLayout());
						 panel1.addMouseListener(CustomWindowNG.this);
						panel2.addMouseListener(CustomWindowNG.this);
						final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panel1, panel2);
						src.add(splitPane, BorderLayout.CENTER);
						src.revalidate();
					}
				}
			});
		}

		menu.show(src, e.getX(), e.getY());
	}

	public static void main(final String[] args) {
		new CustomWindowNG();
	}
}[/HIGHLIGHT]


----------



## multiholle (25. Mrz 2009)

Funktioniert wunderbar, danke! Noch eine weitere Frage:

Ich möchte ein erzeugtes Splitpane per Rechtsklick auf den Balken des Splitpanes wieder löschen. Ich habe einen Mouslistener hinzugefügt und die Methode mouseReleased implementiert. Leider wird diese Funktion nie aufgerufen. Muss ich einen anderen Listener verwenden?

[highlight="java"]
// SPLITPANE LÖSCHEN
@Override
public void mouseReleased(MouseEvent e) {
	System.out.println("mouseReleased");
	if (!e.isPopupTrigger()) return;
	final JSplitPane src = (JSplitPane) e.getSource();

	JPopupMenu menu = new JPopupMenu();
	menu.add(new AbstractAction("Clear") {
		@Override
		public void actionPerformed(ActionEvent e) {
			src.getParent().remove(src);
		}
	});
	menu.show(src, e.getX(), e.getY());
}
[/highlight]

EDIT: Habe einen neuen Thread dazu eröffnent: http://www.java-forum.org/awt-swing-swt/80952-jsplitpane-und-mouslistener.html


----------

