# Jtree CheckNode mit JPanel



## Systalisma (17. Nov 2010)

Hallo,

ich habe einen JTree mit CheckBoxen von der Klasse CheckNode und CheckNodeRenderer.
Nun habe ich neben den CheckBoxen ein JPanel hinzugefügt.
Wenn ich nun einen neuen Knoten hinzufüge, was auch funktioniert, dann hat dieser Knoten auch das JPanel.
Es haben alle Wurzeln und Knoten dieses JPanel.
Gibt es eine Möglichkeit das Panel nur einer CheckBox, bzw. ausgewählten CheckBoxen zuzuweisen?

Zur Veranschaulichung (Den JTree grafisch vorstellen):


```
+[JCheckBox] [JPanel]
     +[JCheckBox] [JPanel]
     -[JCheckBox] [JPanel]
          [JCheckBox] [JPanel]
          [JCheckBox] [JPanel]
     +[JCheckBox] [JPanel]
```


Danke im Voraus


Mit freundlichen Grüßen

Systalisma


----------



## Systalisma (22. Nov 2010)

Kann mir keiner weiterhelfen? 
Auch keinen Hinweis, Tipp oder sonst etwas, dass mir weiterhelfen könnte?


Mit freundlichen Grüßen

Systalisma


----------



## Michael... (22. Nov 2010)

Gibt's Code dazu?

Ansonsten kann man nur sagen, wenn Du für alle Knoten den selben Renderer verwendest, schauen die halt alle ähnlich aus.


----------



## Systalisma (22. Nov 2010)

Ja ich verwende den selben TreeCellRenderer.
Kann man dann auch mehrere TreeCellRender schreiben und verwenden?
Oder wie realisiere ich das sonst?

Ja Code gibt es, ich poste mal die relevantesten Codeausschnitte:

Zunächst mal den TreeModelListener mit der Methode "treeNodesChanged".
Hier werden meine Wurzel und Unterknoten hinzugefügt.


```
public void treeNodesChanged(TreeModelEvent e) {
		DefaultMutableTreeNode node;
		node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent());

		try {
			int index = e.getChildIndices()[0];
			node = (CheckNode) (node.getChildAt(index));

			CheckNode newNode = new CheckNode("New Node");
			CheckNode selNode = (CheckNode) tree.getLastSelectedPathComponent();

			if (node.toString().equals("Main") && bool1 == true) {
				model.insertNodeInto(new CheckNode("Namensraum"), selNode,
						selNode.getChildCount());
				ja.append("<Main");
				model.insertNodeInto(new CheckNode("Element"), selNode, selNode
						.getChildCount());
				model.insertNodeInto(new CheckNode("Array"), selNode, selNode
						.getChildCount());
				bool1 = false;
			} else if (node.toString().equals("Verfahren1") && bool2 == true) {
				model.insertNodeInto(new CheckNode("Array"), selNode, selNode
						.getChildCount());
				model.insertNodeInto(new CheckNode("AnyXML"), selNode, selNode
						.getChildCount());
				model.insertNodeInto(new CheckNode("Attribut"), selNode,
						selNode.getChildCount());
				bool2 = false;
			} else if (node.toString().equals("Verfahren2") && bool3 == true) {
				model.insertNodeInto(new CheckNode("Element"), selNode, selNode
						.getChildCount());
				model.insertNodeInto(new CheckNode("Array"), selNode, selNode
						.getChildCount());
				model.insertNodeInto(new CheckNode("Attribut"), selNode,
						selNode.getChildCount());
				bool3 = false;
			} else
				;

			TreeNode[] nodes = model.getPathToRoot(newNode);
			TreePath path = new TreePath(nodes);
			tree.expandPath(path);
			tree.scrollPathToVisible(path);
			tree.setSelectionPath(path);
			tree.startEditingAtPath(path);
			tree.revalidate();
			tree.repaint();

		} catch (NullPointerException exc) {
			exc.printStackTrace();
		}

	}
```

Die Klasse CheckRenderer mit dem TreeCellRenderer:


```
class CheckRenderer extends JPanel implements TreeCellRenderer {
	protected JCheckBox check;
	protected JPanel panel;
	protected JLabel label;
	protected JTextField t;

	protected JPanel getLeafRenderer() {
		// leafRendere bearbeiten
		return panel;
	}

	public CheckRenderer() {

		setLayout(null);
		setUI(null);
		add(check = new JCheckBox());

// Hier füge ich das Panel hinzu, jedoch für alle CheckNodes, was ich aber nur für bestimmte Nodes hinzufügen möchte
		add(panel = new JPanel());

		label = new JLabel("Einstellung");
		label.setSize(120, 25);

		t = new JTextField("");
		t.setSize(100, 25);
		// label.setEditable(true);
		panel.add(t, BorderLayout.SOUTH);
		panel.add(label, BorderLayout.EAST);
		panel.setEnabled(true);

		panel.setPreferredSize(new Dimension(280, 60));
		panel.setBorder(BorderFactory.createEtchedBorder());
		panel.setBackground(new Color(245, 255, 245));
		panel.setLayout(null);
		check.setBackground(Color.WHITE);
	}

	public Component getTreeCellRendererComponent(JTree tree, Object value,
			boolean isSelected, boolean expanded, boolean leaf, int row,
			boolean hasFocus) {
		String stringValue = tree.convertValueToText(value, isSelected,
				expanded, leaf, row, hasFocus);
		setEnabled(tree.isEnabled());

		if (isSelected) {
			check.setForeground(new Color(255, 155, 55));
			check.setBackground(new Color(55, 155, 255));
			tree.revalidate();
			tree.repaint();
		}

		check.setSelected(((CheckNode) value).isSelected());
		check.setBackground(new Color(245, 245, 245));
		panel.setFont(tree.getFont());

		tree.setEditable(true);

		label.setText(stringValue);
		label.setBounds(5, 0, 110, 25);

		t.setBounds(5, 30, 100, 25);
		t.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (t.getText() != null)
					t.setText(t.getText());
				check.revalidate();
				check.repaint();
			}
		});

		MyTreeModelListener m = new MyTreeModelListener(tree, panel);

		return this;
	}
}
```


----------



## Michael... (22. Nov 2010)

Systalisma hat gesagt.:


> Ja ich verwende den selben TreeCellRenderer.
> Kann man dann auch mehrere TreeCellRender schreiben und verwenden?


Du kannst ja im Renderer das Objekt überprüfen. Hier mal was aus meinem Fundus, ich habe damals ein eigenes Objekt definiert, auf das ich den Knoteninhalt geprüft habe:

```
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
public class TreeCheckBoxDemo extends JFrame{
 
    public static void main(String[] args) {        
        TreeCheckBoxDemo treeFrame = new TreeCheckBoxDemo();
        treeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        treeFrame.setBounds(0, 0, 300, 300);
        treeFrame.setLocationRelativeTo(null);
        treeFrame.setVisible(true);
    }
    
    private JTree tree;
    
    public TreeCheckBoxDemo() {
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Root");
        DefaultMutableTreeNode node = new DefaultMutableTreeNode("Kategorie 1");
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 1", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 2", true)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 3", false)));
        rootNode.add(node);
        
        node = new DefaultMutableTreeNode("Kategorie 2");
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 4", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 5", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 6", true)));
        rootNode.add(node);
        
        tree = new JTree(rootNode) {
        	public void startEditingAtPath(TreePath path) {
        		DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
        		if (!treeNode.isLeaf()) {
        			super.startEditingAtPath(path);
        		}
        	}
        };
        tree.setCellRenderer(new MyCellRenderer());
        tree.setEditable(false);
        tree.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent evt) {
				if (evt.getClickCount()>1) {
					TreePath path = tree.getPathForLocation(evt.getX(), evt.getY());
					if (path==null)
						return;
					DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
					if (treeNode.getUserObject() instanceof CheckObject) {
						CheckObject co = (CheckObject)treeNode.getUserObject();
						co.setSelected(!co.isSelected());
						tree.repaint();
					}
				}
			}
        });
        this.add(tree);
    }
    
    class CheckObject {
    	private String text;
    	private boolean selected;
    	
    	public CheckObject(String text, boolean isSelected) {
    		this.text = text;
    		this.selected = isSelected;
    	}
    	
    	public boolean isSelected() {
    		return selected;
    	}
    	
    	public void setSelected(boolean b) {
    		selected = b;
    	}
    	
    	public String getText() {
    		return text;
    	}
    }
    
    class MyCellRenderer extends DefaultTreeCellRenderer {
    	private DefaultMutableTreeNode treeNode;
    	private CheckObject chObj;
    	private JCheckBox chBox = new JCheckBox();
    	
    	
    	public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    		super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
    		treeNode = (DefaultMutableTreeNode) value;
    		
    		if (treeNode.getUserObject() instanceof CheckObject) {
    			chObj = (CheckObject) treeNode.getUserObject();
    			chBox.setText(chObj.getText());
    			chBox.setSelected(chObj.isSelected());
    			chBox.setBackground(this.getBackground());
    			return chBox;
    		}
    		this.setIcon(null);
    		return this;
    	}
    }
}
```


----------



## Systalisma (22. Nov 2010)

Ja also dein Beispielcode hat mir schon sehr weitergeholfen.

Jedoch kann ich in diesem Beispiel nur eine CheckBox ODER ein JPanel hinzufügen.
Ich möchte aber CheckBoxen, teilweise ohne Panel, aber auch mit JPanel, je nachdem welche Componente ausgewählt wird.

Hier noch mein geänderter Code: (Zur Veranschaulichung einfach ausführen)


```
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
 
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
 
public class TreeCellEditor_1 extends JFrame{
 
    public static void main(String[] args) {        
        TreeCellEditor_1 treeFrame = new TreeCellEditor_1();
        treeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        treeFrame.setBounds(0, 0, 300, 300);
        treeFrame.setLocationRelativeTo(null);
        treeFrame.setVisible(true);
    }
    
    private JTree tree;
    
    public TreeCellEditor_1() {
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Root");
        DefaultMutableTreeNode node = new DefaultMutableTreeNode("Kategorie 1");
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 1", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 2", true)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 3", false)));
        rootNode.add(node);
        
        node = new DefaultMutableTreeNode("Kategorie 2");
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 4", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 5", false)));
        node.add(new DefaultMutableTreeNode(new CheckObject("Unterkategorie 6", true)));
        rootNode.add(node);
        
        tree = new JTree(rootNode) {
            public void startEditingAtPath(TreePath path) {
                DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                if (!treeNode.isLeaf()) {
                    super.startEditingAtPath(path);
                }
            }
        };
        tree.setCellRenderer(new MyCellRenderer());
        tree.setEditable(false);
        tree.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount()>1) {
                    TreePath path = tree.getPathForLocation(evt.getX(), evt.getY());
                    if (path==null)
                        return;
                    DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                    if (treeNode.getUserObject() instanceof CheckObject) {
                        CheckObject co = (CheckObject)treeNode.getUserObject();
                        co.setSelected(!co.isSelected());
                        tree.repaint();
                    }
                }
            }
        });
        this.add(tree);
    }
    
    class CheckObject {
        private String text;
        private boolean selected;
        
        public CheckObject(String text, boolean isSelected) {
            this.text = text;
            this.selected = isSelected;
        }
        
        public boolean isSelected() {
            return selected;
        }
        
        public void setSelected(boolean b) {
            selected = b;
        }
        
        public String getText() {
            return text;
        }
    }
    
    class MyCellRenderer extends DefaultTreeCellRenderer {
        private DefaultMutableTreeNode treeNode;
        private CheckObject chObj;
        private JCheckBox chBox = new JCheckBox();
        
        
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            treeNode = (DefaultMutableTreeNode) value;
                       
            if (treeNode.getUserObject() instanceof CheckObject) {
                chObj = (CheckObject) treeNode.getUserObject();
                if(chObj.getText().equals("Unterkategorie 1")){
                	JPanel p = new JPanel();
                	p.setPreferredSize(new Dimension(100, 50));
                	p.setBackground(new Color(100, 100, 200));
                	p.add(new JTextField("Test"));
                	
                	return p;
                }
                chBox.setText(chObj.getText());
                chBox.setSelected(chObj.isSelected());
                chBox.setBackground(this.getBackground());
                return chBox;
            }
            this.setIcon(null);
            return this;
        }
    }
}
```


----------



## Michael... (22. Nov 2010)

Nehme mal an das Neuerstellen des JPanels JTextFields innerhalb der getTreeCellR... ist nur zu Testzwecken.
Aber grundsätzlich funktioniert der Code ja - es wird ein JTextField innerhalb eines JPanels für den einen Knoten als Renderer zurückgeben. Wenn das nicht passt musst eine andere Komponentenzusammenstellung als Renderer zurückgeben.

Prinzipiell würde ich Objekte die anders dargestellt werden sollen als unterschiedliche Objekte in die Knoten stecken bzw. über sowas wie getType() unterscheidbar machen.


----------



## Systalisma (23. Nov 2010)

Michael... hat gesagt.:


> Wenn das nicht passt musst eine andere Komponentenzusammenstellung als Renderer zurückgeben.



Also das einzigste Problem sind jetzt noch diese Rückgabewerte vom Renderer.
Ich arbeite jetzt mit einer Label-Object-class und einer JPanel-Object-class.
Das sind die beiden verschiedenen Typen, die vorkommen können.

Jedoch weis ich nicht wie ich mehrere Komponenten zurückgeben soll, da ich ja wie gesagt, eine Checkbox brauche und dahinter ein Label oder ein Panel, je nachdem.


Mit freundlichen Grüßen

Systalisma


----------



## Michael... (23. Nov 2010)

Verstehe nicht, wo Du genau noch Probleme hast.
Eine JCheckBox besitzt ja standardmäßig ein Label und in ein JPanel kann man reinstecken was man will. Kannst Deiner  Kreativität also freien Lauf lassen.


----------



## Systalisma (23. Nov 2010)

Nun ja,

ich möchte eine JCheckBox, die nicht in einem Panel ist.
Je nachdem ob der Knoten von der Klasse JPanelObject erstellt wurde, soll dann ein JPanel hinzugefügt werden.
Wenn ich nicht die Klase JPanelObject verwende, dann soll einfach nur die CheckBox mit dem standardmäßig integrierten Label erscheinen.

Wenn ich ein Panel zurückgebe, dann verschwindet die CheckBox, was nicht sein sollte, und es wird nur noch das JPanel angzeigt bei dem jeweiligen Knoten.

In dem letzten Code kann man gut sehen, dass beim einen Knoten eine CheckBox ist, bei den anderen beiden ein JPanel.
Ich möchte aber, dass eine CheckBox immer vorhanden und ein JPanel nur hinzugefügt wird, wenn der Knoten mit der Klase JPanelObject erstellt wurde.
Systalisma


----------



## Michael... (23. Nov 2010)

Systalisma hat gesagt.:


> Wenn ich ein Panel zurückgebe, dann verschwindet die CheckBox, was nicht sein sollte, und es wird nur noch das JPanel angzeigt bei dem jeweiligen Knoten.


Ist ja auch logisch. Wenn Du der Tabelle sagst, der Renderer für diese Zelle ist ein Panel, dann zeichnet die Tabelle da keine CheckBox hin - ausser das  Panel beinhaltet eine CheckBox.

Wie soll denn das Panel aussehen?


----------



## Systalisma (23. Nov 2010)

Also das Panel beinhaltet eine Checkbox, dahinter eine ComboBox, dahiner dann noch ein Textfeld.
Das sind ca. 5 Zeilen mit diesem Inhalt.
Wenn ich die CheckBox von einer Zeile markiere, dann sollen wieder neue Checkbox, Combobox und Textfeld zwischen der derzeitigen Zeile generiert werden.
Dieser Vorgang kann beliebig tief gehen.
Dabei soll das JPanel dann auch vergrößert werden.

Systalisma


----------



## Michael... (23. Nov 2010)

Da bist Du ja noch garnicht bei der Problematik des CellEditor angelangt ;-)

Das ganze ist grundsätzlich machbar. Bin mir aber nicht sicher, ob JTree die geeignete Komponente dafür ist.


----------



## Michael... (23. Nov 2010)

Hier mal kurzes Bsp für die unterschiedlichen Renderer. Muss zu meiner Schande gestehen, dass ich das mit Renderingkonzept nicht ganz sauber durch gezogen habe - aber dazu hatte ich jetzt keine Lust.
Aber wie man sieht kann das schon recht ausarten - und dabei kann man das Ganze noch nicht einmal editieren. Keine Ahnung was Du genau vorhast, aber vielleicht wärst Du mit einer JList besser bedient.

```
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

public class TreeRendererDemo2 extends JFrame {
	private JTree tree;
	private DefaultTreeModel model;
	
	public  TreeRendererDemo2() {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Wurzelknoten");
		DefaultMutableTreeNode node;
		root.add(new DefaultMutableTreeNode(Boolean.TRUE));
		root.add(new DefaultMutableTreeNode(Boolean.FALSE));
		root.add(new DefaultMutableTreeNode(new SomeFunnyObject()));
		root.add(new DefaultMutableTreeNode(Boolean.FALSE));
		root.add(new DefaultMutableTreeNode(new SomeFunnyObject()));
		root.add(new DefaultMutableTreeNode(new SomeFunnyObject()));
		root.add(new DefaultMutableTreeNode("Simple Node"));
		root.add(new DefaultMutableTreeNode(Boolean.TRUE));
		model = new DefaultTreeModel(root);
		
		tree = new JTree(model);
		tree.setCellRenderer(new DualRenderer());
		this.getContentPane().add(new JScrollPane(tree));
	}
	
	class RendererPanel extends JPanel {
		
		public RendererPanel() {
			this.setLayout(new GridLayout(0, 1));
			this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
			this.setOpaque(false);
		}
		
		public void preparePanel(SomeFunnyObject sfo) {
			removeAll();
			for (int i=0; i<sfo.getSize(); i++) {
				SomeFunnyItem item = sfo.getItem(i);
				add(new RendererItem(item.isSelected(), item.getSelectedIndex(), item.getText()));
			}
		}
	
		class RendererItem extends JPanel {
			private JCheckBox check;
			private JComboBox combo;
			private JTextField field;
			private String[] values = new String[] {"A", "B", "C", "D", "E", "F"}; 
			
			public RendererItem(boolean b, int index, String text) {
				this.setOpaque(false);
				check = new JCheckBox("", b);
				combo = new JComboBox(values);
				combo.setSelectedIndex(index);
				field = new JTextField(text);
				add(check);
				add(combo);
				add(field);
			}
		}
	}
	
	class SomeFunnyObject {
		private ArrayList<SomeFunnyItem> list;
		
		public SomeFunnyObject() {
			list = new ArrayList<SomeFunnyItem>();
			this.randomInitialize();
		}
		
		private void randomInitialize() {
			int n = (int)(Math.random()*5) +1;
			for (int i=0; i<n; i++)
				list.add(new SomeFunnyItem());
		}
		
		public int getSize() {
			return list.size();
		}
		
		public SomeFunnyItem getItem(int index) {
			return list.get(index);
		}
	}
	
	class SomeFunnyItem {
		private boolean b;
		private int index;
		private String text;
		
		private String[] values =  {"TextA", "TextB", "TextC", "TextD", "TextE"};
		
		public SomeFunnyItem() {
			this.b = (Math.random()*2)>1;
			this.index = (int)(Math.random()*6);
			this.text = values[(int)(Math.random()*values.length)];
		}
		
		public SomeFunnyItem(boolean b, int index, String text) {
			this.b = b;
			this.index = index;
			this.text = text;
		}
		
		public boolean isSelected() {
			return b;
		}
		
		public int getSelectedIndex() {
			return index;
		}
		
		public String getText() {
			return text;
		}
	}
	
	
	class DualRenderer extends DefaultTreeCellRenderer {
		public RendererPanel panel = new RendererPanel();
		public JCheckBox check = new JCheckBox("DefaultCheckBox");
		
		public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    		super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
    		Object obj = ((DefaultMutableTreeNode)value).getUserObject();
    		if (obj instanceof SomeFunnyObject) {
    			panel.preparePanel((SomeFunnyObject)obj);
    			return panel;
    		}
    		if (obj instanceof Boolean) {
    			check.setSelected((Boolean)obj);
    			return check;
    		}
    		return this;
    	}
	}
	
	public static void main(String[] args) {
		JFrame frame = new TreeRendererDemo2();
		frame.setBounds(0, 0, 500, 500);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------



## Systalisma (23. Nov 2010)

Danke erstmal für das Beispiel.

So in etwa soll das aussehen.
Das mit dem "editierbar" habe ich noch nicht so ganz verstanden, habe es zwar schon bei diversen Beispielen gesehen und auch selbst hinbekommen, aber wie genau das jetzt funktioniert ist mit letztenendes unklar.

Mein CellEditor sieht so aus: (Wurde auch etwas kopiert, habe ich nicht alles allein geschrieben)


```
static class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

		CheckRenderer renderer = new CheckRenderer();

		ChangeEvent changeEvent = null;

		public Object getCellEditorValue() {
			JPanel panel = renderer.getLeafRenderer();
			return panel;
		}

		public boolean isCellEditable(EventObject event) {
			boolean returnValue = false;
			if (event instanceof MouseEvent) {
				MouseEvent mouseEvent = (MouseEvent) event;
				TreePath path = tree.getPathForLocation(mouseEvent.getX(),
						mouseEvent.getY());
				if (path != null) {
					Object node = path.getLastPathComponent();
					if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
						DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
						@SuppressWarnings("unused")
						Object userObject = treeNode.getUserObject();
						returnValue = ((treeNode.isLeaf()));
					}
				}
			}
			return returnValue;
		}

		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean selected, boolean expanded, boolean leaf, int row) {

			Component editor = renderer.getTreeCellRendererComponent(tree, value,
					true, expanded, leaf, row, true);

			// editor always selected / focused
			ItemListener itemListener = new ItemListener() {
				public void itemStateChanged(ItemEvent itemEvent) {
					if (stopCellEditing()) {
						fireEditingStopped();
					}
				}
			};
			if (editor instanceof JCheckBox) {
				((JCheckBox) editor).addItemListener(itemListener);
			}

			return editor;
		}

	}
```

Zum Thema JList:
Also was sehr wichtig ist, dass ich auf -und zuklappen kann, wie bei einem JTree, falls eine Umsetzung damit wirklich sinnvoll wäre.

Des Weiteren soll man diese Elemente direkt auf der Gui auswählen können, welche dann analysiert werden und in eine Datei geschrieben werden.

Systalisma


----------



## Systalisma (23. Nov 2010)

Ich hab jetzt mal ein kleines Szenario gemacht.
So kann es auch aussehen.


```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

@SuppressWarnings("serial")
public class TreeCellEditor_1 extends JFrame{

    public static void main(String[] args) {
        TreeCellEditor_1 treeFrame = new TreeCellEditor_1();
        treeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        treeFrame.setBounds(0, 0, 300, 300);
        treeFrame.setLocationRelativeTo(null);
        treeFrame.setVisible(true);
    }

    private JTree tree;
    private JPanel plPanel = new JPanel();

    public TreeCellEditor_1() {
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("");
        DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);

        node = new DefaultMutableTreeNode("Verfahren1");
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);

        node = new DefaultMutableTreeNode("Verfahren2");
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);


        rootNode.add(node);

        tree = new JTree(rootNode) {
            public void startEditingAtPath(TreePath path) {
                DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                if (!treeNode.isLeaf()) {
                    super.startEditingAtPath(path);
                }
            }
        };
        tree.setCellRenderer(new MyCellRenderer());
        tree.setEditable(true);
        tree.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent evt) {
                if (evt.getClickCount()>1) {
                    TreePath path = tree.getPathForLocation(evt.getX(), evt.getY());
                    if (path==null)
                        return;
                    DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                    if (treeNode.getUserObject() instanceof CheckObject) {
                        CheckObject co = (CheckObject)treeNode.getUserObject();
                        co.setSelected(!co.isSelected());
                        tree.repaint();
                    }
                }
            }
        });
        this.add(tree);
    }

    class TreeEditable implements TreeCellEditor{

		@Override
		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean isSelected, boolean expanded, boolean leaf, int row) {
			return null;
		}

		@Override
		public void addCellEditorListener(CellEditorListener l) {

		}

		@Override
		public void cancelCellEditing() {

		}

		@Override
		public Object getCellEditorValue() {
			return null;
		}

		@Override
		public boolean isCellEditable(EventObject event) {
			boolean returnValue = false;
			if (event instanceof MouseEvent) {
				MouseEvent mouseEvent = (MouseEvent) event;
				TreePath path = tree.getPathForLocation(mouseEvent.getX(),
						mouseEvent.getY());
				if (path != null) {
					Object node = path.getLastPathComponent();
					if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
						DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
						Object userObject = treeNode.getUserObject();
						returnValue = ((treeNode.isLeaf()));
					}
				}
			}
			return true;
		}

		@Override
		public void removeCellEditorListener(CellEditorListener l) {

		}

		@Override
		public boolean shouldSelectCell(EventObject anEvent) {
			return false;
		}

		@Override
		public boolean stopCellEditing() {
			return false;
		}

    }

    class CheckObject {
        private String text;
        private String name;
        private boolean selected;

        public CheckObject(String text, boolean isSelected, String name) {
            this.text = text;
            this.selected = isSelected;
            this.name = name;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean b) {
            selected = b;
        }

        public String getText() {
            return text;
        }

        public String getName(){
        	return name;
        }
    }

    class PanelObject {
    	private boolean enabled;
    	private Dimension size;
    	private String name;

    	public PanelObject(boolean enabled, String name){
    		this.enabled = enabled;
    		this.name = name;
    	}

    	public boolean isEnabled(){
    		return enabled;
    	}

    	public void setEnabled(boolean b){
    		enabled = b;
    	}

    	public void setPreferredSize(Dimension size){
    		size = new Dimension();
    	}

    	public void getPreferredSize(){
    		size.getSize();
    	}

    	public String getName(){
    		return name;
    	}

    }

    class MyCellRenderer extends DefaultTreeCellRenderer {
        private DefaultMutableTreeNode treeNode;
        private CheckObject chObj;
        private PanelObject plObj;
        private JCheckBox chBox = new JCheckBox();

        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            treeNode = (DefaultMutableTreeNode) value;

            if (treeNode.getUserObject() instanceof CheckObject) {

                chObj = (CheckObject) treeNode.getUserObject();

                System.out.println("ChObjekt " + chObj.getName());
                if(chObj.getName().equals("Main")){
                	chBox.setText("EXTraEdiDefinition");
                	chBox.setSelected(chObj.isSelected());
                    chBox.setEnabled(true);
                    chBox.setBackground(Color.cyan);
                }

                return chBox;
            }
            else if(treeNode.getUserObject() instanceof PanelObject){
            	plObj = (PanelObject) treeNode.getUserObject();

                if(plObj.getName().equals("Namensraum")){
                	plPanel.removeAll();
                	plPanel.setEnabled(plObj.isEnabled());
                	plPanel.setLayout(null);
                	plPanel.setPreferredSize(new Dimension(200, 60));
                	plPanel.setBorder(BorderFactory.createEtchedBorder());
                	plPanel.setBackground(this.getBackground());

                	JLabel lb1 = new JLabel("Namensräume");
                	lb1.setBounds(10, 5, 150, 25);
                	lb1.setEnabled(true);
                	plPanel.add(lb1);
                	
                	JCheckBox ch1 = new JCheckBox("Namensraum1");
                	ch1.setBounds(10, 30, 150, 25);
                	ch1.setBackground(null);
                	ch1.setEnabled(true);
                	plPanel.add(ch1);

                }
                else if(plObj.getName().equals("Attribut")){
                	plPanel.removeAll();
                	plPanel.setEnabled(plObj.isEnabled());
                	plPanel.setLayout(null);
                	plPanel.setPreferredSize(new Dimension(200, 60));
                	plPanel.setBorder(BorderFactory.createEtchedBorder());
                	plPanel.setBackground(this.getBackground());

                	JLabel lb1 = new JLabel("Attribute");
                	lb1.setBounds(10, 5, 150, 25);
                	lb1.setEnabled(true);
                	plPanel.add(lb1);
                	
                	JCheckBox ch1 = new JCheckBox("Atrribut1");
                	ch1.setBounds(10, 30, 150, 25);
                	ch1.setBackground(null);
                	ch1.setEnabled(true);
                	plPanel.add(ch1);
                }
                else if(plObj.getName().equals("Element")){
                	plPanel.removeAll();
                	plPanel.setEnabled(plObj.isEnabled());
                	plPanel.setLayout(null);
                	plPanel.setPreferredSize(new Dimension(200, 60));
                	plPanel.setBorder(BorderFactory.createEtchedBorder());
                	plPanel.setBackground(this.getBackground());

                	JLabel lb1 = new JLabel("Elemente");
                	lb1.setBounds(10, 5, 150, 25);
                	lb1.setEnabled(true);
                	plPanel.add(lb1);
                	
                	JCheckBox ch1 = new JCheckBox("Element1");
                	ch1.setBounds(10, 30, 150, 25);
                	ch1.setBackground(null);
                	ch1.setEnabled(true);
                	plPanel.add(ch1);
                }
                else 
                	;

            	//plPanel.setEnabled(true);



            	return plPanel;
            }

            this.setIcon(null);
            return this;
        }
    }
}
```

Dabei soll, wenn man jetzt auf die CheckBox im Panel klickt:
- eine neue CheckBox angeboten werden mit z.B. "Namensraum2", dann "Namensraum3" usw.

Jetzt muss ich "nur" noch wissen wie ich die Componenten im JPanel auch noch bearbeiten kann. 

Dann wäre mir schon gut weitergeholfen.

Systalisma


----------



## Michael... (23. Nov 2010)

Systalisma hat gesagt.:


> Zum Thema JList:
> Also was sehr wichtig ist, dass ich auf -und zuklappen kann, wie bei einem JTree, falls eine Umsetzung damit wirklich sinnvoll wäre.
> 
> Des Weiteren soll man diese Elemente direkt auf der Gui auswählen können, welche dann analysiert werden und in eine Datei geschrieben werden.


Ein JTree ist ja im Prinzip nichts anderes als eine auf-und zuklappbare Liste und "Elemente" auswählen kann man in einem JTree genauso wie in einer JList.

Was mir noch nicht klar ist, was ist graphisch/layouttechnisch gesehen der Unterschied zwischen Namensraum, Attribut und Element. Ist doch bei allen ein "Titel" mit einer Liste von JCheckBoxes - warum drei mal der selbe Code?
Ansonsten hat eine JCheckBox bereits ein Label, man muss das nicht mittels JCheckBox + JLabel nachbauen.

Damit die Knoten editierbar werden, musst Du ersten den Editor dem JTree zuweisen und zweitens in der getTreeCellEditorComp... eine Komponente zurückgeben und drittens...


----------



## Systalisma (23. Nov 2010)

Michael... hat gesagt.:


> Was mir noch nicht klar ist, was ist graphisch/layouttechnisch gesehen der Unterschied zwischen Namensraum, Attribut und Element. Ist doch bei allen ein "Titel" mit einer Liste von JCheckBoxes - warum drei mal der selbe Code?


Das war nur testweise, wollte eigentlich die Panel unterschiedlich machen.
Habe es jetzt auch so geändert, dass nur der Text individuell festgelegt wird.



Michael... hat gesagt.:


> Damit die Knoten editierbar werden, musst Du ersten den Editor dem JTree zuweisen und zweitens in der getTreeCellEditorComp... eine Komponente zurückgeben und drittens...



Ok ich habe jetzt mal den Editor zugewiesen, eine Komponente zurückgeben und noch ein paar weitere Eigenschaften.

Hier noch der Code:

```
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import javax.swing.JTree;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;


@SuppressWarnings("serial")
public class TreeCellEditor_1 extends JFrame{

    public static void main(String[] args) {
        TreeCellEditor_1 treeFrame = new TreeCellEditor_1();
        treeFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        treeFrame.setBounds(0, 0, 300, 500);
        treeFrame.setPreferredSize(new Dimension(300, 500));
        treeFrame.setLocationRelativeTo(null);
        treeFrame.setVisible(true);
    }

    private JTree tree;
    private JPanel plPanel = new JPanel();
    private static ArrayList<DefaultMutableTreeNode> al = new ArrayList<DefaultMutableTreeNode>();

    public TreeCellEditor_1() {
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("");
        DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");

        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);

        node = new DefaultMutableTreeNode("Verfahren1");
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);

        node = new DefaultMutableTreeNode("Verfahren2");
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Namensraum")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Attribut")));
        node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element")));
        rootNode.add(node);


        rootNode.add(node);

        tree = new JTree(rootNode) {
            public void startEditingAtPath(TreePath path) {
                DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                if (!treeNode.isLeaf()) {
                    super.startEditingAtPath(path);
                }
            }
        };
        tree.setCellRenderer(new MyCellRenderer());
        tree.setEditable(true);
        tree.setCellEditor(new CheckBoxNodeEditor());
//        tree.addMouseListener(new MouseAdapter() {
//            public void mouseClicked(MouseEvent evt) {
//                if (evt.getClickCount()>1) {
//                    TreePath path = tree.getPathForLocation(evt.getX(), evt.getY());
//                    if (path==null)
//                        return;
//                    DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
//                    if (treeNode.getUserObject() instanceof CheckObject) {
//                        CheckObject co = (CheckObject)treeNode.getUserObject();
//                        co.setSelected(!co.isSelected());
//                        tree.repaint();
//                    }
//                }
//            }
//        });
        this.add(tree);
    }

    class CheckObject {
        private String text;
        private String name;
        private boolean selected;

        public CheckObject(String text, boolean isSelected, String name) {
            this.text = text;
            this.selected = isSelected;
            this.name = name;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean b) {
            selected = b;
        }

        public String getText() {
            return text;
        }

        public String getName(){
        	return name;
        }
    }

    class PanelObject {
    	private boolean enabled;
    	private Dimension size;
    	private String name;

    	public PanelObject(boolean enabled, String name){
    		this.enabled = enabled;
    		this.name = name;
    	}

    	public boolean isEnabled(){
    		return enabled;
    	}

    	public void setEnabled(boolean b){
    		enabled = b;
    	}

    	public void setPreferredSize(Dimension size){
    		size = new Dimension();
    	}

    	public void getPreferredSize(){
    		size.getSize();
    	}

    	public String getName(){
    		return name;
    	}

    }

    class MyCellRenderer extends DefaultTreeCellRenderer {
        private DefaultMutableTreeNode treeNode;
        private PanelObject plObj;

        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
            treeNode = (DefaultMutableTreeNode) value;

            tree.revalidate();
            tree.repaint();

            if(treeNode.getUserObject() instanceof PanelObject){
            	plObj = (PanelObject) treeNode.getUserObject();

            	plPanel.removeAll();
            	plPanel.setEnabled(plObj.isEnabled());
            	plPanel.setLayout(null);
            	plPanel.setPreferredSize(new Dimension(200, 60));
            	plPanel.setBorder(BorderFactory.createEtchedBorder());
            	plPanel.setBackground(this.getBackground());

            	JLabel lb1 = new JLabel();
            	lb1.setBounds(10, 5, 150, 25);
            	lb1.setEnabled(true);

            	JCheckBox ch1 = new JCheckBox("Namensraum1");
            	ch1.setBounds(10, 30, 150, 25);
            	ch1.setBackground(null);
            	ch1.setEnabled(true);

                if(plObj.getName().equals("Namensraum")){
                	lb1.setText("Namensräume");
                	ch1.setText("Namensraum1");
                }
                else if(plObj.getName().equals("Attribut")){
                	lb1.setText("Attribute");
                	ch1.setText("Attribut1");
                }
                else if(plObj.getName().equals("Element")){
                 	lb1.setText("Elemente");
                	ch1.setText("Element1");
                }
                else
                	;

                tree.repaint();
                plPanel.add(lb1);
                plPanel.add(ch1);

                System.out.println(al);
            	//plPanel.setEnabled(true);


            	return plPanel;
            }

            this.setIcon(null);
            return this;
        }
    }
    class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {

		MyCellRenderer renderer = new MyCellRenderer();

		ChangeEvent changeEvent = null;

		public Object getCellEditorValue() {
			JPanel panel = null; //renderer.getLeafRenderer();
			return panel;
		}

		public boolean isCellEditable(EventObject event) {
			boolean returnValue = false;
			if (event instanceof MouseEvent) {
				MouseEvent mouseEvent = (MouseEvent) event;
				TreePath path = tree.getPathForLocation(mouseEvent.getX(),
						mouseEvent.getY());
				if (path != null) {
					Object node = path.getLastPathComponent();
					if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
						DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
						@SuppressWarnings("unused")
						Object userObject = treeNode.getUserObject();
						returnValue = ((treeNode.isLeaf()));
					}
				}
			}
			return returnValue;
		}

		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean selected, boolean expanded, boolean leaf, int row) {

			Component editor = renderer.getTreeCellRendererComponent(tree, value,
					true, expanded, leaf, row, true);

			// editor always selected / focused
			ItemListener itemListener = new ItemListener() {
				public void itemStateChanged(ItemEvent itemEvent) {
					if (stopCellEditing()) {
						fireEditingStopped();
					}
				}
			};
			if (editor instanceof JCheckBox) {
				((JCheckBox) editor).addItemListener(itemListener);
			}

			return editor;
		}

	}


}
```

Das Phänomen, das bei diesem Code autritt, hatte ich jetzt auch schon öfters.
Die Panels verschwinden und kommen wieder beim Klicken.


Systalisma


----------



## Michael... (23. Nov 2010)

Grundsätzlich ist es eine schlechte Idee die Renderer Komponente für den Editor herzunehmen. Das kann abgesehen von nicht sichtbaren Komponenten ganz unangenehme Nebeneffekte haben.

Deswegen habe ich u.a. das RendererPanel in einer eigenen Klasse definiert. So kann man für den Editor eine eigenständige Instanz erzeugen.


----------



## Systalisma (24. Nov 2010)

Michael... hat gesagt.:


> Deswegen habe ich u.a. das RendererPanel in einer eigenen Klasse definiert. So kann man für den Editor eine eigenständige Instanz erzeugen.



Ich verstehe noch nicht ganz wie das mit der eigenständigen Instanz funktionierten soll.
Wo muss ich diese implementieren.
Bin gerade etwas durcheinander.

Was genau bring mir diese eigenständige Instanz?

Systalisma


----------



## Michael... (24. Nov 2010)

Das Renderer und Editor Konzept von Swing funktioniert prinzipiell so:
Es wird eine Komponente als Renderer zum Zeichnen der Zellen bei einer Tabelle, der Knoten bei einem Baum... verwendet (bei verschiedenen Zell/Knoten-Darstellungen gibt es selbstverständlich verschiedene Rendererkomponenten)
Eine zweite Komponente wird als Editor verwendet (bei verschiedenen Editoren... s. Renderer)

Die Rendererkomponent wird entsprechend der sichtbaren Zellen, Knoten... mehrfach abgemalt, die Editorkomponente wird im Bedarfsfall tatsächlich auf der GUI platziert.

Wenn sich aber Editor und Renderer eine gemeinsame Komponente teilen müssen, kommt es vor, dass beim Editieren die Komponente aber "gleichzeitig" auch zum Renderern der Knoten benötigt wird ==> fehlerhafte bzw. falsche Darstellung von Editor und/oder Renderer


----------



## Systalisma (24. Nov 2010)

Erstmal danke für die Erläuterung, gerade der letzte Satz war aufschlussreich 

Habe jetzt den Tree grundsätzlich so wie ich ihn haben will.
Auch das mit den editierbaren Zellen scheint zu funktionieren (ohne Konflikte)

Jetzt bin ich gerade dabei einen ItemListener zu implementieren.
Dabei möchte ich eine neue CheckBox hinzufügen und das Panel vergrößen.

Das klappt auch beides.
Aber die Panel überlappen im Jtree, das sollte natürlich nicht sein.

Hier noch der Java-Code zur Veranschaulichung:

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

class TreeNodeVector<E> extends Vector<E> {
	String name;

	TreeNodeVector(String name) {
		this.name = name;
	}

	TreeNodeVector(String name, E elements[]) {
		this.name = name;
		for (int i = 0, n = elements.length; i < n; i++) {
			add(elements[i]);
		}
	}

	public String toString() {
		return "[" + name + "]";
	}
}

class LeafCellEditor extends DefaultTreeCellEditor {

	public LeafCellEditor(JTree tree, DefaultTreeCellRenderer renderer,
			TreeCellEditor editor) {
		super(tree, renderer, editor);
	}

	public boolean isCellEditable(EventObject event) {
		boolean returnValue = super.isCellEditable(event);
		if (returnValue) {
			Object node = tree.getLastSelectedPathComponent();
			if ((node != null) && (node instanceof TreeNode)) {
				TreeNode treeNode = (TreeNode) node;
				returnValue = treeNode.isLeaf();
			}
		}
		return returnValue;
	}
}

class PanelObject {
	private boolean enabled;
	private Dimension size;
	private String name;

	public PanelObject(boolean enabled, String name) {
		this.enabled = enabled;
		this.name = name;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean b) {
		enabled = b;
	}

	public void setPreferredSize(Dimension size) {
		size = new Dimension();
	}

	public void getPreferredSize() {
		size.getSize();
	}

	public String getName() {
		return name;
	}

}

class CheckBoxNodeRenderer extends JPanel implements TreeCellRenderer,
		ItemListener {
	private JCheckBox leafRenderer = new JCheckBox();
	private JLabel label = new JLabel();

	private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();

	protected JCheckBox getLeafRenderer() {
		return leafRenderer;
	}

	public CheckBoxNodeRenderer() {
		Font fontValue;
		fontValue = UIManager.getFont("Tree.font");
		if (fontValue != null) {
			leafRenderer.setFont(fontValue);
		}
		Boolean booleanValue = (Boolean) UIManager
				.get("Tree.drawsFocusBorderAroundIcon");
		leafRenderer.setFocusPainted((booleanValue != null)
				&& (booleanValue.booleanValue()));
	}

	public Component getTreeCellRendererComponent(final JTree tree,
			Object value, boolean selected, boolean expanded, boolean leaf,
			int row, boolean hasFocus) {

		Component returnValue;
		if (leaf) {
			String stringValue = tree.convertValueToText(value, selected,
					expanded, leaf, row, false);
			leafRenderer.setText(stringValue);
			leafRenderer.setSelected(false);
			leafRenderer.setBackground(new Color(255, 255, 255));
			leafRenderer.setBounds(10, 35, 120, 25);
			leafRenderer.setEnabled(tree.isEnabled());

			label.setBounds(10, 10, 120, 25);

			if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
				Object userObject = ((DefaultMutableTreeNode) value)
						.getUserObject();
				if (userObject instanceof PanelObject) {
					PanelObject node = (PanelObject) userObject;
					leafRenderer.setText(node.getName());
					leafRenderer.setSelected(false);
					leafRenderer.addItemListener(this);

					if (((PanelObject) userObject).getName().equals(
							"Namensraum1")) {
						label.setText("Namensräume");
					} else if (((PanelObject) userObject).getName().equals(
							"Attribut1")) {
						label.setText("Attribute");
					} else if (((PanelObject) userObject).getName().equals(
							"Element1")) {
						label.setText("Elemente");
					}
				}
			}
			this.add(leafRenderer);
			this.add(label);
			this.setLayout(null);
			this.setBackground(new Color(246, 246, 246));
			this.setPreferredSize(new Dimension(300, 70));
			this.setBorder(BorderFactory.createEtchedBorder());
			returnValue = this;
		} else {
			returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree,
					value, selected, expanded, leaf, row, hasFocus);
		}
		return returnValue;
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		if (leafRenderer.isSelected()) {
			JCheckBox box1 = new JCheckBox("Namensraum2");
			box1.setBounds(10, 65, 120, 25);
			box1.setBackground(new Color(246, 246, 246));
			add(box1);
			setPreferredSize(new Dimension(300, 100));
			setSize(new Dimension(300, 100)); 
			// tree.revalidate();
			// tree.repaint();
		}
	}
}

class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
	CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();

	ChangeEvent changeEvent = null;

	JTree tree;

	public CheckBoxNodeEditor(JTree tree) {
		this.tree = tree;
	}

	public Object getCellEditorValue() {
		JCheckBox checkbox = renderer.getLeafRenderer();
		PanelObject checkBoxNode = new PanelObject(checkbox.isSelected(), "");
		return checkBoxNode;
	}

	public boolean isCellEditable(EventObject event) {
		boolean returnValue = false;
		if (event instanceof MouseEvent) {
			MouseEvent mouseEvent = (MouseEvent) event;
			TreePath path = tree.getPathForLocation(mouseEvent.getX(),
					mouseEvent.getY());
			if (path != null) {
				Object node = path.getLastPathComponent();
				if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
					DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
					Object userObject = treeNode.getUserObject();
					returnValue = ((treeNode.isLeaf()) && (userObject instanceof PanelObject));
				}
			}
		}
		return returnValue;
	}

	public Component getTreeCellEditorComponent(JTree tree, Object value,
			boolean selected, boolean expanded, boolean leaf, int row) {

		Component editor = renderer.getTreeCellRendererComponent(tree, value,
				true, expanded, leaf, row, true);

		ItemListener itemListener = new ItemListener() {
			public void itemStateChanged(ItemEvent itemEvent) {
				if (stopCellEditing()) {
					fireEditingStopped();
				}
			}
		};
		if (editor instanceof JCheckBox) {
			((JCheckBox) editor).addItemListener(itemListener);
		}
		return editor;
	}
}

public class teste {
	public static void main(String args[]) {
		JFrame frame = new JFrame("CheckBox Tree");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("");
		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");

		node.add(new DefaultMutableTreeNode(
				new PanelObject(true, "Namensraum1")));
		node
				.add(new DefaultMutableTreeNode(new PanelObject(true,
						"Attribut1")));
		node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element1")));
		rootNode.add(node);

		node = new DefaultMutableTreeNode("Verfahren1");
		node.add(new DefaultMutableTreeNode(
				new PanelObject(true, "Namensraum1")));
		node
				.add(new DefaultMutableTreeNode(new PanelObject(true,
						"Attribut1")));
		node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element1")));
		rootNode.add(node);

		node = new DefaultMutableTreeNode("Verfahren2");
		node.add(new DefaultMutableTreeNode(
				new PanelObject(true, "Namensraum1")));
		node
				.add(new DefaultMutableTreeNode(new PanelObject(true,
						"Attribut1")));
		node.add(new DefaultMutableTreeNode(new PanelObject(true, "Element1")));
		rootNode.add(node);

		rootNode.add(node);
		JTree tree = new JTree(rootNode);

		CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
		tree.setCellRenderer(renderer);
		tree.setRootVisible(false);
		tree.setCellEditor(new CheckBoxNodeEditor(tree));
		tree.setEditable(true);
		JScrollPane scrollPane = new JScrollPane(tree);
		frame.add(scrollPane, BorderLayout.CENTER);
		//frame.setSize(400, 600);
		Dimension frameSize = new Dimension(800, 625);

		// Größe des Bildschirms ermitteln
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

		// Position des JFrames errechnen
		int top = (screenSize.height - frameSize.height) / 2;
		int left = (screenSize.width - frameSize.width) / 2;

		frame.setSize(frameSize);
		frame.setResizable(false);

		// Position zuordnen
		frame.setLocation(left, top);
		// frame.setResizable(false);
		frame.setVisible(true);
	}
}
```


----------



## Michael... (24. Nov 2010)

Systalisma hat gesagt.:


> Das klappt auch beides.
> Aber die Panel überlappen im Jtree, das sollte natürlich nicht sein.


Das liegt daran, dass der Editor einfach an der Position des Knotens oben drauf gesetzt wird.

Du hast aber noch ganz anderere (schwerwiegendere) Probleme:
Dein Datenmodell ist garnicht für solche Objekte ausgelegt. Änderungen an den Knoten werden nicht "zurückgespeichert".

Vielleicht solltest Du mal ein paar Schritte zurück und Dich erst einmal mit JTree und dessen Model auseinandersetzen. Du musst ersteinmal ein geeignetes Objekt definieren, dass alle notwendigen Informationen aufnehmen kann.
Immer daran Denken Renderer und Editor sind Repräsentationen eines (von Dir definierten) Objekts.
Solche "aktiven" Änderungen des Editors wie in der itemStateChanged sind der völlig falsche Weg. Die Reihefolge muss sein:
1. das Objekt ändert sich
2. der Renderer/Editor passt sich dem Objekt an


----------



## Systalisma (24. Nov 2010)

Michael... hat gesagt.:


> Du hast aber noch ganz anderere (schwerwiegendere) Probleme:
> Dein Datenmodell ist garnicht für solche Objekte ausgelegt. Änderungen an den Knoten werden nicht "zurückgespeichert".



Nun ja, das ist mir schon klar.
Das hätte ich gemacht, nachdem ich weis wie das mit dem Panel vergrößern funktioniert 

Da hast du natürlich recht, das es so herum wenig Sinn macht.

Dann implementiere ich erstmal die Objekte und die nötigen Events. 
Wenn es dann immernoch nicht klappt mit dem Panel, dann melde ich mich nochmal. 

Systalisma


----------



## Systalisma (25. Nov 2010)

Mh,

Also ich habe mich für einen Hashtable entschieden.
Der Key soll einen qualifizierten Namen repräsentieren (String) und der Wert ist dann ein Object.

Beispiel:

```
h.put("MainNamensraum1", (PanelObject) plobj)
```

Was mir auch unklar ist, wie greife ich dann wieder auf die gespeicherten Objekte zu, so dass ich z.B. die Hintergrundfarbe individuell ändern könnte.

Bei meinem Zugriff wird trotzdem immer bei jedem Panel die Veränderung durchgeführt und ich möchte die Panel ja einzeln ansprechen.

Allgemein:
1. Ist ein Hashtable sinnvoll?
2. Wenn nicht, was würdest du empfehlen?

Systalisma


----------



## Michael... (25. Nov 2010)

Systalisma hat gesagt.:


> Mh,
> 
> Also ich habe mich für einen Hashtable entschieden.
> Der Key soll einen qualifizierten Namen repräsentieren (String) und der Wert ist dann ein Object.
> ...


mit 
	
	
	
	





```
h.get(Object key)
```
 Allerdings richt die Anmerkung mit der Hintergrundfarbe, danach dass Du Datenmodell und Repräsentation vermischt?


Systalisma hat gesagt.:


> Allgemein:
> 1. Ist ein Hashtable sinnvoll?
> 2. Wenn nicht, was würdest du empfehlen?


Ich sehe nirgends die Notwendigkeit einer Hashtable. Ich würde die Objekte einfach in DefaultMutableTreeNodes stecken und ein DefaultTreeModel ohne customizing.
Was hast Du mit der Hashtable vor bzw. was versprichst Du Dir davon?


----------



## Systalisma (25. Nov 2010)

Michael... hat gesagt.:


> Allerdings richt die Anmerkung mit der Hintergrundfarbe, danach dass Du Datenmodell und Repräsentation vermischt?



Nun ja, es sollen Dinge wie: Neue Label, neue TextFelder, das Bearbeiten von Felder usw. möglich sein.
Das mit der Hintergrundfarbe war nur eins von vielen.



Michael... hat gesagt.:


> Ich sehe nirgends die Notwendigkeit einer Hashtable. Ich würde die Objekte einfach in DefaultMutableTreeNodes stecken und ein DefaultTreeModel ohne customizing.



Also ein DefaultMutabletreemodel erzeugt man ja so:


```
...
			rootNode.add(node);

			DefaultTreeModel model = new DefaultTreeModel(rootNode);
			model.addTreeModelListener(new TreeModelListener(){

				@Override
				public void treeNodesChanged(TreeModelEvent e) {
				}

				@Override
				public void treeNodesInserted(TreeModelEvent e) {
				}

				@Override
				public void treeNodesRemoved(TreeModelEvent e) {
				}

				@Override
				public void treeStructureChanged(TreeModelEvent e) {
				}

			});

			JTree tree = new JTree(model);
...
```

Ich hatte das DefaultTreeModel schon einmal verwendet, allerdings hat das nicht gerade gut geklappt.
In welcher Methode/Funktion muss ich denn die Objekte, sprich die verschiedenen Panels, CheckBoxen usw., speichern?



Michael... hat gesagt.:


> Was hast Du mit der Hashtable vor bzw. was versprichst Du Dir davon?



Nun ja, wie schon gesagt, darin wollte ich die Objekte speichern, ich wusste nicht welche Art von Speicherung ich nehmen soll, daher hab ich einfach mal nen Hashtable genommen, da er nen Key und nen Wert hat. Erschien mir zu dem Zeitpunkt am einfachsten.


----------



## Michael... (25. Nov 2010)

Systalisma hat gesagt.:


> Nun ja, es sollen Dinge wie: Neue Label, neue TextFelder, das Bearbeiten von Felder usw. möglich sein.
> Das mit der Hintergrundfarbe war nur eins von vielen.


Aber das sind ja Dinge die dem Datenobjekt zunächst mal egal sein sollten. Wie ein Objekt dargestellt wird definiert/verantwortet die Viewingkomponente (z.B. der Renderer) das Objekt bzw. das Model muss nur die dazu notwendigen Informationen liefern.
Wenn ein Objekt unbedingt mit einer bestimmten Farbe dargestellt werden will, dann muss es das dem Renderer sagen. I.d.R. bestimmt aber der Renderer (anhand eines Kriteriums) welche Farbe zur Darstellung verwendet wird.

Vielleicht ein Bsp.: In einer Kontoübersicht, kannst Du zur besseren Übersicht negative Beträge in Rot darstellen. D.h. Du (als Renderer) definierst, dass negative Zahlen rot sind. Habe noch von keiner negativen Zahl gehört: Ich muss in Rot dargestellt werden.



Systalisma hat gesagt.:


> Ich hatte das DefaultTreeModel schon einmal verwendet, allerdings hat das nicht gerade gut geklappt.
> In welcher Methode/Funktion muss ich denn die Objekte, sprich die verschiedenen Panels, CheckBoxen usw., speichern?


Du übergibst diese Objekte einfach eine DefaultMutableTreeNode, diese Klasse kann ja Objekte aller Art entgegennehmen.

```
DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(einBeliebigesObjekt);
```
Am DefaultTreeModel musst Du gar nichts machen. Die für Deinen Zweck notwendigen Funktionaliäten sind da bereits alle implementiert.


----------



## Systalisma (29. Nov 2010)

Michael... hat gesagt.:


> Du übergibst diese Objekte einfach eine DefaultMutableTreeNode, diese Klasse kann ja Objekte aller Art entgegennehmen.
> 
> ```
> DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(einBeliebigesObjekt);
> ```



Hallo,

Also das verstehe ich noch nicht ganz.
Wenn ich jedes Mal ein neue neue "rootNode" erzeuge, dann enthält doch die "rootNode" nicht alle Objekte oder?



Michael... hat gesagt.:


> Am DefaultTreeModel musst Du gar nichts machen. Die für Deinen Zweck notwendigen Funktionaliäten sind da bereits alle implementiert.



Also was ich grundsätzlich nicht verstehe:
Wenn schon alles notwendige implementiert ist, wie verwende ich diese Dinge dann?


Vielleicht könntest du mir ein kleines Beispiel geben, welches ein paar Objekte in einem "DefaultMutableTreeNode" speichert.
Und wie man dann auf die Objekte zugreift.

Ich lerne immer am Besten an Beispielen


Systalisma


----------



## Michael... (29. Nov 2010)

Hier mal nur ein kurzes Bsp. um zu zeigen, dass für Dein Vorhaben das TreeModel oder die TreeNodes uninteressant sind und Du die Defaultkomponenten verwenden kannst.
Entscheidend ist wie Du die Objekte in den Blattkomponenten definierst und wie Renderer und Editor damit umgehen.
In dem Code ist nur das Datenobjekt und der Editor rudimentär implementiert und wie man sieht oder erahnen kann, wird Dein Vorhaben extrem kompliziert umzusetzen zu sein.

An Deiner Stelle würde ich mir aber Überlegen:
- ob man die Einträge tatsächlich im Tree editieren muss oder nicht in einem seperaten Bereich/Dialog
- ob man diese Einträge (entsprechend Ihrer Struktur) nicht weiter zerlegt: Namensräume, Attribute, Elemente als jeweils eigenständige Knoten mit den Kind/Blatt-Knoten Namensraum1, Namesraum2... bzw. Attribut1, Attribut2... usw. (so wie es jetzt ausschaut, versuchst Du eine Teilstruktur des Baumes in einem Knoten zusammenzufassen)



```
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

public class DemoTree extends JFrame {

	public DemoTree() {
		List<String> list = new ArrayList<String>();
		list.add("Namensraum1 [Main]");
		list.add("Namensraum2 [Main]");
		LeafDataObject leafObject = new LeafDataObject(list);
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");
		node.add(new DefaultMutableTreeNode(leafObject));
		root.add(node);
		node = new DefaultMutableTreeNode("Verfahren 1");
		list = new ArrayList<String>();
		list.add("Namensraum1 [Verf1]");
		leafObject = new LeafDataObject(list);
		node.add(new DefaultMutableTreeNode(leafObject));
		root.add(node);
		JTree tree = new JTree(root);
		tree.setEditable(true);
		tree.setCellEditor(new LeafDataEditor(tree));
		this.getContentPane().add(new JScrollPane(tree));
	}

	class LeafDataObject {
		private List<String> nameSpaces;

		public LeafDataObject(List<String> nameSpaces) {
			this.nameSpaces = nameSpaces;
		}

		public int getNameSpacesCount() {
			return nameSpaces.size();
		}

		public String getNameSpaces(int index) {
			if (index >= nameSpaces.size())
				throw new IllegalArgumentException("No valid index: " + index);
			return nameSpaces.get(index);
		}

		public void addNameSpace(String name) {
			nameSpaces.add(name);
		}
		
		public void removeNameSpace(String name) {
			nameSpaces.remove(name);
		}
	}

	class LeafDataEditor extends JPanel implements TreeCellEditor, ActionListener {
		private LeafDataObject leafObject;
		private JTree tree;
		private boolean reedit = false;

		public LeafDataEditor(JTree tree) {
			this.tree = tree;
			this.setLayout(new GridLayout(0, 1));
			this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		}

		private void prepare(LeafDataObject obj) {
			this.removeAll();
			this.add(new JLabel(" Namensräume"));
			for (int i = 0; i < obj.getNameSpacesCount(); i++) {
				JCheckBox check = new JCheckBox(obj.getNameSpaces(i), i < obj
						.getNameSpacesCount() - 1);
				check.addActionListener(this);
				this.add(check);
			}
		}
		
		public void actionPerformed(ActionEvent e) {
			// Hier muss das Datenobjekt modifiziert werden
			JCheckBox check = (JCheckBox)e.getSource();
			if (check.isSelected())
				leafObject.addNameSpace("Neuer Namensraum "	+ (leafObject.getNameSpacesCount() + 1));
			else
				leafObject.removeNameSpace(check.getText());
			prepare(leafObject);
			this.validate();
			TreePath path = tree.getEditingPath();
			this.stopCellEditing();
			reedit = true;
			tree.startEditingAtPath(path);
			reedit = false;
		}

		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean isSelected, boolean expanded, boolean leaf, int row) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
			if (node.getUserObject() instanceof LeafDataObject) {
				leafObject = (LeafDataObject) node.getUserObject();
				prepare(leafObject);
				return this;
			} else
				leafObject = null;
			return null;
		}

		public Object getCellEditorValue() {
			if (leafObject != null)
				return leafObject;
			return null;
		}

		public boolean isCellEditable(EventObject anEvent) {
			if (reedit)
				return true;
			if (anEvent instanceof MouseEvent) {
				TreePath path = tree.getPathForLocation(((MouseEvent) anEvent).getX(), ((MouseEvent)anEvent).getY());
				if (path!=null && ((DefaultMutableTreeNode)path.getLastPathComponent()).isLeaf())
					return true;
				return false;
			}
			return false;
		}
		
		public void addCellEditorListener(CellEditorListener l) {}
		public void cancelCellEditing() {}
		public void removeCellEditorListener(CellEditorListener l) {}
		public boolean shouldSelectCell(EventObject anEvent) {return true;}
		public boolean stopCellEditing() {return true;}
	}

	public static void main(String[] args) {
		JFrame frame = new DemoTree();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------



## Systalisma (30. Nov 2010)

Michael... hat gesagt.:


> In dem Code ist nur das Datenobjekt und der Editor rudimentär implementiert und wie man sieht oder erahnen kann, wird Dein Vorhaben extrem kompliziert umzusetzen zu sein.



Oje Oje 



Michael... hat gesagt.:


> An Deiner Stelle würde ich mir aber Überlegen:
> - ob man die Einträge tatsächlich im Tree editieren muss oder nicht in einem seperaten Bereich/Dialog
> - ob man diese Einträge (entsprechend Ihrer Struktur) nicht weiter zerlegt: Namensräume, Attribute, Elemente als jeweils eigenständige Knoten mit den Kind/Blatt-Knoten Namensraum1, Namesraum2... bzw. Attribut1, Attribut2... usw. (so wie es jetzt ausschaut, versuchst Du eine Teilstruktur des Baumes in einem Knoten zusammenzufassen)



Also erstmal danke für die Überlegung.
Ich denke es sollte möglich sein, dass es auch mit einzelnen Knoten und Kinder umsetzbar ist. Ein eigener Bereich, bzw. Dialog sollte ebenso möglich sein.

Ich habe hier mal dein Beispiel erweitert/bearbeitet und versucht diese Idee zu realisieren, grundsätzlich.

Kannst ja mal nen Blick drauf werfen und mir dann sagen, ob ich dich richtig verstanden hab.


```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

public class test3 extends JFrame {

	private static JPanel paneltree;
	private static JPanel paneledit;

	public test3() {

		paneltree = new JPanel();

		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");

		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");
		DefaultMutableTreeNode child = new DefaultMutableTreeNode("Namensräume");

		child.add(new DefaultMutableTreeNode("Namensraum1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Attribute");

		child.add(new DefaultMutableTreeNode("Attribut1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Elemente");

		child.add(new DefaultMutableTreeNode("Element1"));

		node.add(child);

		root.add(node);

		node = new DefaultMutableTreeNode("Verfahren 1");
		child = new DefaultMutableTreeNode("Namensräume");

		child.add(new DefaultMutableTreeNode("Namensraum1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Attribute");

		child.add(new DefaultMutableTreeNode("Attribut1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Elemente");

		child.add(new DefaultMutableTreeNode("Element1"));

		node.add(child);

		root.add(node);

		node = new DefaultMutableTreeNode("Verfahren 2");
		child = new DefaultMutableTreeNode("Namensräume");

		child.add(new DefaultMutableTreeNode("Namensraum1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Attribute");

		child.add(new DefaultMutableTreeNode("Attribut1"));

		node.add(child);

		child = new DefaultMutableTreeNode("Elemente");

		child.add(new DefaultMutableTreeNode("Element1"));

		node.add(child);

		root.add(node);

		JTree tree = new JTree(root);
		tree.setEditable(true);
		tree.setCellEditor(new LeafDataEditor(tree));

		paneltree.setBounds(0, 0, 400, 625);
		paneltree.setLayout(new BorderLayout());
		paneltree.add(tree);

		JScrollPane js2 = new JScrollPane(paneltree);

		paneledit = new JPanel();
		paneledit.setBounds(400, 0, 400, 625);
		paneledit.setLayout(null);

		JScrollPane js1 = new JScrollPane(paneledit);

		JSplitPane jp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, js2, js1);
		jp.setBounds(10, 25, 770, 535);
		jp.setOneTouchExpandable(true);
		jp.setDividerLocation(430);

		Dimension minimumSize = new Dimension(800, 100);
		js1.setMinimumSize(minimumSize);
		js2.setMinimumSize(minimumSize);

		JPanel panel_all = new JPanel();
		panel_all.setLayout(null);
		panel_all.add(jp);
		panel_all.setBounds(10, 25, 775, 510);

		this.getContentPane().add(panel_all);
	}

	class LeafDataObject {
		private List<String> nameSpaces;

		public LeafDataObject(List<String> nameSpaces) {
			this.nameSpaces = nameSpaces;
		}

		public int getNameSpacesCount() {
			return nameSpaces.size();
		}

		public String getNameSpaces(int index) {
			if (index >= nameSpaces.size())
				throw new IllegalArgumentException("No valid index: " + index);
			return nameSpaces.get(index);
		}

		public void addNameSpace(String name) {
			nameSpaces.add(name);
		}

		public void removeNameSpace(String name) {
			nameSpaces.remove(name);
		}
	}

	class LeafDataEditor extends JPanel implements TreeCellEditor,
			ActionListener {
		private LeafDataObject leafObject;
		private JTree tree;
		private boolean reedit = false;

		public LeafDataEditor(JTree tree) {
			this.tree = tree;
			this.setLayout(new GridLayout(0, 1));
			this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		}

		private void prepare(LeafDataObject obj) {
			this.removeAll();
			this.add(new JLabel(" Namensräume"));
			for (int i = 0; i < obj.getNameSpacesCount(); i++) {
				JCheckBox check = new JCheckBox(obj.getNameSpaces(i), i < obj
						.getNameSpacesCount() - 1);
				check.addActionListener(this);
				this.add(check);
			}
		}

		public void actionPerformed(ActionEvent e) {

			System.out.println("Hallo");

			// Hier muss das Datenobjekt modifiziert werden
			JCheckBox check = (JCheckBox) e.getSource();
			if (check.isSelected())
				leafObject.addNameSpace("Neuer Namensraum "
						+ (leafObject.getNameSpacesCount() + 1));
			else
				leafObject.removeNameSpace(check.getText());
			prepare(leafObject);
			this.validate();
			TreePath path = tree.getEditingPath();
			this.stopCellEditing();
			reedit = true;
			tree.startEditingAtPath(path);
			reedit = false;
		}

		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean isSelected, boolean expanded, boolean leaf, int row) {
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
			if (node.getUserObject() instanceof LeafDataObject) {
				leafObject = (LeafDataObject) node.getUserObject();
				prepare(leafObject);
				return this;
			} else
				leafObject = null;

			final JCheckBox chk = new JCheckBox("Namensraum1");
			chk.setBounds(20, 20, 110, 25);
			chk.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JCheckBox c1 = new JCheckBox("Namensraum2");
					c1.setBounds(20, 45, 110, 25);
					JLabel pref = new JLabel("pref = ");
					pref.setBounds(160, 20, 50, 25);
					JTextField pref_txt = new JTextField("");
					pref_txt.setBounds(220, 20, 100, 25);

					JLabel pref1 = new JLabel("pref = ");
					pref1.setBounds(160, 75, 50, 25);
					JTextField pref_txt1 = new JTextField("");
					pref_txt1.setBounds(220, 75, 100, 25);
					JLabel name = new JLabel("name = ");
					name.setBounds(160, 50, 50, 25);
					JTextField name_txt = new JTextField("");
					name_txt.setBounds(220, 50, 100, 25);

					if (chk.isSelected()) {
						paneledit.add(c1);
						paneledit.add(pref1);
						paneledit.add(pref_txt1);
						paneledit.add(pref);
						paneledit.add(pref_txt);
						paneledit.add(name);
						paneledit.add(name_txt);

						paneledit.revalidate();
						paneledit.repaint();
					} else if(chk.isSelected() == false){
						paneledit.remove(c1);
						paneledit.add(pref1);
						paneledit.add(pref_txt1);
						paneledit.remove(pref);
						paneledit.remove(pref_txt);
						paneledit.remove(name);
						paneledit.remove(name_txt);

						paneledit.revalidate();
						paneledit.repaint();
					}
				}
			});

			JLabel pref = new JLabel("pref = ");
			pref.setBounds(160, 20, 50, 25);
			paneledit.add(pref);

			JTextField pref_txt = new JTextField("");
			pref_txt.setBounds(220, 20, 100, 25);
			paneledit.add(pref_txt);

			paneledit.add(chk);
			paneledit.revalidate();
			paneledit.repaint();

			//Hier weis ich nicht was ich zurückgeben soll
			//Am besten wäre einfach, wenn sich gar nichts verändert
			return new JLabel("Namensraum1");
		}

		public Object getCellEditorValue() {
			if (leafObject != null)
				return leafObject;
			return null;
		}

		public boolean isCellEditable(EventObject anEvent) {
			if (reedit)
				return true;
			if (anEvent instanceof MouseEvent) {
				TreePath path = tree.getPathForLocation(((MouseEvent) anEvent)
						.getX(), ((MouseEvent) anEvent).getY());
				if (path != null
						&& ((DefaultMutableTreeNode) path
								.getLastPathComponent()).isLeaf())
					return true;
				return false;
			}
			return false;
		}

		public void addCellEditorListener(CellEditorListener l) {
		}

		public void cancelCellEditing() {
		}

		public void removeCellEditorListener(CellEditorListener l) {
		}

		public boolean shouldSelectCell(EventObject anEvent) {
			return true;
		}

		public boolean stopCellEditing() {
			return true;
		}
	}

	public static void main(String[] args) {
		JFrame frame = new test3();
		frame.setBounds(0, 0, 800, 625);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------



## Michael... (30. Nov 2010)

Da geht jetzt einiges durcheinander.
Jetzt hast Du ja beides gemacht: den Tree tiefer strukturiert und eine Eingabe Oberfläche implementiert. Meine Vorschläge waren eigentlich eher: entweder oder ;-)
Den TreeCellEditor brauchst Du in dem Fall gar nicht mehr, jetzt kannst Du ja einfach mit einem TreeSelectionListener am SelectionModel auf die Selektion bzw. einen MouseListener auf einen Mausklick reagieren.

Ich würde mal mit einem einfachen Baum (ohne CellEditor und Renderer) anfangen und erst einmal die wesentlichen Kernfunktionen implementieren. Hier mal eine Demo wie man z.B. mittels Popup neue Namensräume einfügen könnte. Gleiches könnte man auch mittes Dialog, Button... umsetzen

```
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;

public class DemoTree2 extends JFrame {
	
	private DefaultTreeModel treeModel;
	private JTree tree;
	
	private NameSpaceMenu nameSpaceMenu = new NameSpaceMenu();
	
	public DemoTree2() {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");
		DefaultMutableTreeNode leaf;
		node.add(leaf = new DefaultMutableTreeNode(new NameSpaceParent()));
		leaf.add(new DefaultMutableTreeNode("Namensraum A"));
		node.add(leaf = new DefaultMutableTreeNode(new AttributeParent()));
		leaf.add(new DefaultMutableTreeNode("Attribute A"));
		root.add(node);
		node = new DefaultMutableTreeNode("Verfahren 1");
		node.add(leaf = new DefaultMutableTreeNode(new NameSpaceParent()));
		leaf.add(new DefaultMutableTreeNode("Namensraum B"));
		node.add(leaf = new DefaultMutableTreeNode(new AttributeParent()));
		leaf.add(new DefaultMutableTreeNode("Attribute B"));
		root.add(node);
		treeModel = new DefaultTreeModel(root);
		tree = new JTree(treeModel);
		this.getContentPane().add(new JScrollPane(tree));
		
		tree.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				checkPopup(e);
			}

			public void mouseReleased(MouseEvent e) {
				checkPopup(e);
			}
			
			public void checkPopup(MouseEvent e) {
				TreePath path = tree.getPathForLocation(e.getX(), e.getY());
				if (path==null)
					return;
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
				if (node.isLeaf())
					node = (DefaultMutableTreeNode) node.getParent();
				Object obj = node.getUserObject();
				if (obj instanceof NameSpaceParent)
					nameSpaceMenu.showMenu(e.getPoint(), node);
				else if (obj instanceof AttributeParent)
					JOptionPane.showMessageDialog(tree, "...this function is not implemented!", "Sorry but...", JOptionPane.INFORMATION_MESSAGE);
			}
		});
	}
	
	class NameSpaceMenu extends JPopupMenu {
		private MutableTreeNode node;
		
		public NameSpaceMenu() {
			JMenuItem item;
			item = new JMenuItem("Namesraum hinzufügen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					String name = JOptionPane.showInputDialog(tree, "Geben Sie einen Namen ein!");
					DefaultMutableTreeNode child = new DefaultMutableTreeNode(name); 
					treeModel.insertNodeInto(child, node, node.getChildCount());
					tree.scrollPathToVisible(new TreePath(child.getPath()));
				}
			});
			item = new JMenuItem("Namesraum entfernen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JOptionPane.showMessageDialog(tree, "...this function is not implemented!", "Sorry but...", JOptionPane.INFORMATION_MESSAGE);
				}
			});
		}
		
		public void showMenu(Point p, MutableTreeNode node) {
			this.node = node;
			super.show(tree, p.x, p.y);
		}
	}
	
	class NameSpaceParent {
		public String toString() {
			return "Namensräume";
		}
	}
	
	class AttributeParent {
		public String toString() {
			return "Attribute";
		}
	}

	public static void main(String[] args) {
		JFrame frame = new DemoTree2();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------



## Systalisma (1. Dez 2010)

So ich bin gerade noch dabei die grunsätzlichen Funktionalitäten zu implementieren.
Dabei bin ich af ein kleineres Problem gestoßen.
Wenn du meinen Code startest, dann erscheinen 3 Panel, ein linkes, der Baum, das mittlere, Auswahl des Types, das rechte, Festlegung von Parametern und Werten.

Zum Testen des Fehlers im Baum unter: Main -> Namensräume (mit einem einfachen Klick)
Danach erscheinen im mittleren Panel ein paar Typen mit Checkboxen.
Hier einfach die erste CheckBox anwählen.
Dann kommt auch schon der Fehler.
Hier vergrößere ich das Panel und verschiebe die anderen 4 Panel (Element, Attribut, Anyxml und Array) auch um den selben Abstand weiter nach unten.

1. Was schon mal sehr sonderbar ist: Der "Namensraum1" wird angzeigt, bei den anderen 4 muss man erst mit der Maus "drüber-hovern" damit diese sichtbar/angzeigt werden.

2. Wenn man die Splitpaneleiste verschiebt, dann verschiebt sich auch bei "Namensraum1" die CheckBox nach oben, was eigentlich nicht passieren sollte.

Hier noch der Javacode:

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;

public class test4 extends JFrame {

	private static List<Object> list;

	private DefaultTreeModel treeModel;
	private JTree tree;

	private NameSpaceMenu nameSpaceMenu = new NameSpaceMenu();
	private AttributMenu attributMenu = new AttributMenu();
	private ElementMenu elementMenu = new ElementMenu();
	private JPanel paneledit;
	private JPanel paneltree;
	private JPanel panelparm;

	public test4() {

		list = new ArrayList<Object>();

		DefaultMutableTreeNode root = new DefaultMutableTreeNode(
				"EXTraEDIDefinition");
		DefaultMutableTreeNode node = new DefaultMutableTreeNode("Main");
		DefaultMutableTreeNode leaf;

		node.add(leaf = new DefaultMutableTreeNode(new NameSpaceParent()));
		leaf.add(new DefaultMutableTreeNode("Namensraum1"));
		node.add(leaf = new DefaultMutableTreeNode(new AttributeParent()));
		leaf.add(new DefaultMutableTreeNode("Attribut1"));
		node.add(leaf = new DefaultMutableTreeNode(new ElementParent()));
		leaf.add(new DefaultMutableTreeNode("Element1"));
		root.add(node);

		node = new DefaultMutableTreeNode("Verfahren 1");
		node.add(leaf = new DefaultMutableTreeNode(new NameSpaceParent()));
		leaf.add(new DefaultMutableTreeNode("Namensraum1"));
		node.add(leaf = new DefaultMutableTreeNode(new AttributeParent()));
		leaf.add(new DefaultMutableTreeNode("Attribut1"));
		node.add(leaf = new DefaultMutableTreeNode(new ElementParent()));
		leaf.add(new DefaultMutableTreeNode("Element1"));
		root.add(node);

		node = new DefaultMutableTreeNode("Verfahren 2");
		node.add(leaf = new DefaultMutableTreeNode(new NameSpaceParent()));
		leaf.add(new DefaultMutableTreeNode("Namensraum1"));
		node.add(leaf = new DefaultMutableTreeNode(new AttributeParent()));
		leaf.add(new DefaultMutableTreeNode("Attribut1"));
		node.add(leaf = new DefaultMutableTreeNode(new ElementParent()));
		leaf.add(new DefaultMutableTreeNode("Element1"));
		root.add(node);

		treeModel = new DefaultTreeModel(root);
		tree = new JTree(treeModel);

		paneltree = new JPanel();
		paneltree.setBounds(0, 0, 400, 625);
		paneltree.setLayout(new BorderLayout());
		paneltree.add(tree);

		paneledit = new JPanel();
		paneledit.setBounds(400, 0, 170, 625);
		paneledit.setLayout(new BorderLayout());

		panelparm = new JPanel();
		panelparm.setBounds(570, 0, 430, 625);
		panelparm.setLayout(null);
		panelparm.setBackground(new Color(230, 240, 240));

		// /////////////////
		JScrollPane js1 = new JScrollPane(paneledit);
		JScrollPane js2 = new JScrollPane(paneltree);
		JScrollPane js3 = new JScrollPane(panelparm);
		js3.setBounds(610, 10, 490, 606);
		js3.setBorder(BorderFactory.createLineBorder(Color.GRAY));

		JSplitPane jp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, js2, js1);
		jp.setBounds(10, 10, 600, 606);
		jp.setBorder(BorderFactory.createLineBorder(Color.GRAY));
		jp.setOneTouchExpandable(true);
		jp.setDividerLocation(290);

		Dimension minimumSize = new Dimension(150, 600);
		js1.setMinimumSize(minimumSize);
		js2.setMinimumSize(minimumSize);
		js3.setMinimumSize(minimumSize);

		JPanel panel_all = new JPanel();
		panel_all.setLayout(null);
		panel_all.add(jp);
		panel_all.add(js3);
		panel_all.setBounds(10, 25, 1100, 650);

		this.getContentPane().add(panel_all);

		// this.getContentPane().add(new JScrollPane(tree));

		tree.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				if (e.getModifiers() == 4)
					checkPopup(e);
				else if (e.getModifiers() == 16)
					newWindow(e);
			}

			public void mouseReleased(MouseEvent e) {
				if (e.getModifiers() == 4)
					checkPopup(e);
				else if (e.getModifiers() == 16)
					// newWindow(e);
					;
			}

			public void checkPopup(MouseEvent e) {

				TreePath path = tree.getPathForLocation(e.getX(), e.getY());
				if (path == null)
					return;
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
						.getLastPathComponent();
				DefaultMutableTreeNode tmp = (DefaultMutableTreeNode) path
						.getLastPathComponent();
				// if (node.isLeaf())
				// node = (DefaultMutableTreeNode) node.getParent();
				Object obj = node.getUserObject();
				if (obj instanceof NameSpaceParent)
					nameSpaceMenu.showMenu(e.getPoint(), node);
				else if (obj instanceof AttributeParent)
					attributMenu.showMenu(e.getPoint(), node);
				else if (obj instanceof ElementParent)
					elementMenu.showMenu(e.getPoint(), node);
				else if (node.isLeaf())
					;
			}

			public void newWindow(MouseEvent e) {
				TreePath path = tree.getPathForLocation(e.getX(), e.getY());
				if (path == null)
					return;
				DefaultMutableTreeNode tmp = (DefaultMutableTreeNode) path
						.getLastPathComponent();
				if (tmp.toString().equals("Namensräume")) {
					Panelvorlage panel = new Panelvorlage();
					panel.prepare_namensraum();

					//paneledit.revalidate();
					//paneledit.repaint();
				}
			}

		});
	}
	
// Hier beginnt die Klasse für die zwei Panel für die Auswahl der Typen und Parameter
	// sprich das zweite und dritte Panel
	class Panelvorlage extends JPanel {

		private int counter1 = 0;
		private JPanel panel_namensraum;
		private JPanel panel_attribut;
		private JPanel panel_element;
		private JPanel panel_array;
		private JPanel panel_anyxml;

		private JCheckBox array_chk;
		private JCheckBox anyxml_chk;
		private JCheckBox element_chk;
		private JCheckBox namensraum_chk;
		private JCheckBox attribut_chk;

		public void prepare_namensraum() {

			namensraum_chk = new JCheckBox("Namensraum1");
			namensraum_chk.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if(namensraum_chk.isSelected()){
					JLabel name = new JLabel();
					name.setBounds(10, 10, 120, 25);

					JLabel parameter = new JLabel("Parameter");
					parameter.setBounds(57, 10, 120, 25);

					JLabel wert = new JLabel("Wert");
					wert.setBounds(233, 10, 120, 25);

					final JComboBox combo = new JComboBox();
					combo.setBounds(15, 50, 150, 24);
					String[] values = { "compressconditionProc",
							"countTagBytes", "encrypt", "getParm", "getPref",
							"getProc", "inhalt", "isBinary", "isDigest",
							"isSignature", "mandatory", "name", "nameGetParm",
							"nameSetParm", "parse", "pfad", "pref", "setParm",
							"setProc", "signate", "valueId" };
					for (String s : values)
						combo.addItem(s);

					final JTextField text = new JTextField("");
					text.setBounds(180, 50, 150, 25);

					String[] columnNames = { "Parameter", "Wert", };

					Object[][] data = {};

					final DefaultTableModel model = new DefaultTableModel(data,
							columnNames);

					final JTable table = new JTable(model);

					final JScrollPane pane = new JScrollPane(table);
					pane.setBounds(15, 90, 458, 32);

					JButton button = new JButton("Add Parameter");
					button.setBounds(350, 50, 120, 24);
					button.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							model.insertRow(counter1, new Object[] {
									combo.getSelectedItem().toString(),
									text.getText() });
							counter1++;
							if (pane.getSize().height < 470)
								pane.setSize(pane.getSize().width, pane
										.getSize().height + 16);
						}
					});

					panelparm.add(parameter);
					panelparm.add(wert);
					panelparm.add(pane);
					panelparm.add(name);
					panelparm.add(combo);
					panelparm.add(text);
					panelparm.add(button);
					panelparm.revalidate();
					panelparm.repaint();

					JCheckBox c1 = new JCheckBox("Namensraum" + counter1);
					c1.setBounds(namensraum_chk.getBounds());
					c1.setSize(c1.getSize().width, c1.getSize().height + 50);

					panel_array.setLocation(panel_array.getX(), panel_array.getY() + 30);
					panel_element.setLocation(panel_element.getX(), panel_element.getY() + 30);
					panel_anyxml.setLocation(panel_anyxml.getX(), panel_anyxml.getY() + 30);
					panel_attribut.setLocation(panel_attribut.getX(), panel_attribut.getY() + 30);

					array_chk.setLocation(array_chk.getX(), array_chk.getY() + 30);
					element_chk.setLocation(element_chk.getX(), element_chk.getY() + 30);
					anyxml_chk.setLocation(anyxml_chk.getX(), anyxml_chk.getY() + 30);
					attribut_chk.setLocation(attribut_chk.getX(), attribut_chk.getY() + 30);

					panel_namensraum.add(c1);
					panel_namensraum.setSize(panel_namensraum.getSize().width, panel_namensraum.getSize().height + 30);
					}
					else
						//removeAll();
						;

				}
			});
			namensraum_chk.setBounds(15, 35, 125, 25);

			panel_namensraum = new JPanel();
			panel_namensraum.setBounds(10, 30, 135, 35);
			panel_namensraum.setLayout(new BorderLayout());
			panel_namensraum.setBorder(BorderFactory.createEtchedBorder());
			panel_namensraum.add(namensraum_chk);

			attribut_chk = new JCheckBox("Attribut1");
			attribut_chk.setBounds(15, 100, 125, 25);

			panel_attribut = new JPanel();
			panel_attribut.setBounds(10, 95, 135, 35);
			panel_attribut.setLayout(new BorderLayout());
			panel_attribut.setBorder(BorderFactory.createEtchedBorder());
			panel_attribut.add(attribut_chk);

			element_chk = new JCheckBox("Element1");
			element_chk.setBounds(15, 150, 125, 25);

			panel_element = new JPanel();
			panel_element.setBounds(10, 145, 135, 35);
			panel_element.setBorder(BorderFactory.createEtchedBorder());
			panel_element.add(element_chk);

			array_chk = new JCheckBox("Array1");
			array_chk.setBounds(15, 200, 125, 25);

			panel_array = new JPanel();
			panel_array.setBounds(10, 195, 135, 35);
			panel_array.setBorder(BorderFactory.createEtchedBorder());
			panel_array.add(array_chk);

			anyxml_chk = new JCheckBox("AnyXml1");
			anyxml_chk.setBounds(15, 250, 125, 25);

			panel_anyxml = new JPanel();
			panel_anyxml.setBounds(10, 245, 135, 35);
			panel_anyxml.setBorder(BorderFactory.createEtchedBorder());
			panel_anyxml.add(anyxml_chk);

			JLabel labeltyp = new JLabel("Typenauswahl");
			labeltyp.setBounds(15, 5, 110, 25);

			this.add(labeltyp);
			this.add(panel_namensraum);
			this.add(panel_attribut);
			this.add(panel_element);
			this.add(panel_array);
			this.add(panel_anyxml);
			this.add(attribut_chk);
			this.add(element_chk);
			this.add(array_chk);
			this.add(anyxml_chk);
			this.setLayout(null);
			//this.setBounds(10, 10, 100, 300);
			this.revalidate();
			this.repaint();
			paneledit.add(this);
			paneledit.revalidate();
			paneledit.repaint();
			// paneledit.setBackground(Color.RED);

		}

		public void prepare_attribut() {
			JCheckBox namensraum_chk = new JCheckBox("Namensraum1");
			namensraum_chk.setBounds(15, 15, 110, 25);

			JCheckBox attribut_chk = new JCheckBox("Attribut1");
			attribut_chk.setBounds(15, 15, 110, 25);

			JCheckBox element_chk = new JCheckBox("Element1");
			element_chk.setBounds(15, 15, 110, 25);

			JCheckBox array_chk = new JCheckBox("Array1");
			array_chk.setBounds(15, 15, 110, 25);

			JCheckBox anyxml_chk = new JCheckBox("AnyXml1");
			anyxml_chk.setBounds(15, 15, 110, 25);

			JComboBox combo = new JComboBox();
			String[] values = { "compressconditionProc", "countTagBytes",
					"encrypt", "getParm", "getPref", "getProc", "inhalt",
					"isBinary", "isDigest", "isSignature", "mandatory", "name",
					"nameGetParm", "nameSetParm", "parse", "pfad", "pref",
					"setParm", "setProc", "signate", "valueId" };
			for (String s : values)
				combo.addItem(s);
		}

		public void prepare_element() {
			JCheckBox namensraum_chk = new JCheckBox("Namensraum1");
			namensraum_chk.setBounds(15, 15, 110, 25);

			JCheckBox attribut_chk = new JCheckBox("Attribut1");
			attribut_chk.setBounds(15, 15, 110, 25);

			JCheckBox element_chk = new JCheckBox("Element1");
			element_chk.setBounds(15, 15, 110, 25);

			JCheckBox array_chk = new JCheckBox("Array1");
			array_chk.setBounds(15, 15, 110, 25);

			JCheckBox anyxml_chk = new JCheckBox("AnyXml1");
			anyxml_chk.setBounds(15, 15, 110, 25);

			JComboBox combo = new JComboBox();
			String[] values = { "compressconditionProc", "countTagBytes",
					"encrypt", "getParm", "getPref", "getProc", "inhalt",
					"isBinary", "isDigest", "isSignature", "mandatory", "name",
					"nameGetParm", "nameSetParm", "parse", "pfad", "pref",
					"setParm", "setProc", "signate", "valueId" };
			for (String s : values)
				combo.addItem(s);

		}

		public void prepare_array() {
			JCheckBox namensraum_chk = new JCheckBox("Namensraum1");
			namensraum_chk.setBounds(15, 15, 110, 25);

			JCheckBox attribut_chk = new JCheckBox("Attribut1");
			attribut_chk.setBounds(15, 15, 110, 25);

			JCheckBox element_chk = new JCheckBox("Element1");
			element_chk.setBounds(15, 15, 110, 25);

			JCheckBox array_chk = new JCheckBox("Array1");
			array_chk.setBounds(15, 15, 110, 25);

			JCheckBox anyxml_chk = new JCheckBox("AnyXml1");
			anyxml_chk.setBounds(15, 15, 110, 25);

			JComboBox combo = new JComboBox();
			String[] values = { "compressconditionProc", "countTagBytes",
					"encrypt", "getParm", "getPref", "getProc", "inhalt",
					"isBinary", "isDigest", "isSignature", "mandatory", "name",
					"nameGetParm", "nameSetParm", "parse", "pfad", "pref",
					"setParm", "setProc", "signate", "valueId" };
			for (String s : values)
				combo.addItem(s);

		}

		public void prepare_anyxml() {
			JCheckBox namensraum_chk = new JCheckBox("Namensraum1");
			namensraum_chk.setBounds(15, 15, 110, 25);

			JCheckBox attribut_chk = new JCheckBox("Attribut1");
			attribut_chk.setBounds(15, 15, 110, 25);

			JCheckBox element_chk = new JCheckBox("Element1");
			element_chk.setBounds(15, 15, 110, 25);

			JCheckBox array_chk = new JCheckBox("Array1");
			array_chk.setBounds(15, 15, 110, 25);

			JCheckBox anyxml_chk = new JCheckBox("AnyXml1");
			anyxml_chk.setBounds(15, 15, 110, 25);

			JComboBox combo = new JComboBox();
			String[] values = { "compressconditionProc", "countTagBytes",
					"encrypt", "getParm", "getPref", "getProc", "inhalt",
					"isBinary", "isDigest", "isSignature", "mandatory", "name",
					"nameGetParm", "nameSetParm", "parse", "pfad", "pref",
					"setParm", "setProc", "signate", "valueId" };
			for (String s : values)
				combo.addItem(s);

		}

		public void clear() {
			paneledit.removeAll();
		}

	}

// Hier endet die Klasse

	private static int counter_namensraum = 2;
	private static int counter_attribut = 2;
	private static int counter_element = 2;

	class NameSpaceMenu extends JPopupMenu {
		private MutableTreeNode node;

		public NameSpaceMenu() {
			JMenuItem item;
			item = new JMenuItem("Namesraum hinzufügen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					DefaultMutableTreeNode child = new DefaultMutableTreeNode(
							"Namensraum" + counter_namensraum);
					counter_namensraum++;
					treeModel.insertNodeInto(child, node, node.getChildCount());
					tree.scrollPathToVisible(new TreePath(child.getPath()));
				}
			});
			item = new JMenuItem("Namesraum entfernen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					TreePath currentSelection = tree.getSelectionPath();
					if (currentSelection != null) {

						DefaultMutableTreeNode node = (DefaultMutableTreeNode)

						currentSelection.getLastPathComponent();

						DefaultTreeModel model = ((DefaultTreeModel) tree
								.getModel());

						model.removeNodeFromParent(node.getLastLeaf());
						counter_namensraum--;
					}
				}
			});
		}

		public void showMenu(Point p, MutableTreeNode node) {
			if (node.isLeaf() == false)
				this.node = node;
			super.show(tree, p.x, p.y);
		}
	}

	class AttributMenu extends JPopupMenu {
		private MutableTreeNode node;

		public AttributMenu() {
			JMenuItem item;
			item = new JMenuItem("Attribut hinzufügen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					DefaultMutableTreeNode child = new DefaultMutableTreeNode(
							"Attribut" + counter_attribut);
					counter_attribut++;
					treeModel.insertNodeInto(child, node, node.getChildCount());
					tree.scrollPathToVisible(new TreePath(child.getPath()));
				}
			});
			item = new JMenuItem("Attribut entfernen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					TreePath currentSelection = tree.getSelectionPath();
					if (currentSelection != null) {

						DefaultMutableTreeNode node = (DefaultMutableTreeNode)

						currentSelection.getLastPathComponent();

						DefaultTreeModel model = ((DefaultTreeModel) tree
								.getModel());

						model.removeNodeFromParent(node.getLastLeaf());
						counter_attribut--;
					}
				}
			});
		}

		public void showMenu(Point p, MutableTreeNode node) {
			if (node.isLeaf() == false)
				this.node = node;
			super.show(tree, p.x, p.y);
		}
	}

	class ElementMenu extends JPopupMenu {
		private MutableTreeNode node;

		public ElementMenu() {
			JMenuItem item;
			item = new JMenuItem("Element hinzufügen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					DefaultMutableTreeNode child = new DefaultMutableTreeNode(
							"Element" + counter_element);
					counter_element++;
					treeModel.insertNodeInto(child, node, node.getChildCount());
					tree.scrollPathToVisible(new TreePath(child.getPath()));
				}
			});
			item = new JMenuItem("Element entfernen");
			this.add(item);
			item.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					TreePath currentSelection = tree.getSelectionPath();
					if (currentSelection != null) {

						DefaultMutableTreeNode node = (DefaultMutableTreeNode)

						currentSelection.getLastPathComponent();

						DefaultTreeModel model = ((DefaultTreeModel) tree
								.getModel());

						model.removeNodeFromParent(node.getLastLeaf());
						counter_element--;
					}
				}
			});
		}

		public void showMenu(Point p, MutableTreeNode node) {
			if (node.isLeaf() == false)
				this.node = node;
			super.show(tree, p.x, p.y);
		}
	}

	class NameSpaceParent {
		public String toString() {
			return "Namensräume";
		}
	}

	class AttributeParent {
		public String toString() {
			return "Attribute";
		}
	}

	class ElementParent {
		public String toString() {
			return "Elemente";
		}
	}

	public static void main(String[] args) {
		JFrame frame = new test4();
		frame.setTitle("XML-Converter");
		frame.setBounds(0, 0, 1127, 664);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
```


----------

