Jtree CheckNode mit JPanel

Systalisma

Mitglied
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):

Java:
+[JCheckBox] [JPanel]
     +[JCheckBox] [JPanel]
     -[JCheckBox] [JPanel]
          [JCheckBox] [JPanel]
          [JCheckBox] [JPanel]
     +[JCheckBox] [JPanel]


Danke im Voraus


Mit freundlichen Grüßen

Systalisma
 
Zuletzt bearbeitet:

Michael...

Top Contributor
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

Mitglied
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.

Java:
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:

Java:
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...

Top Contributor
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:
Java:
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

Mitglied
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)

Java:
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...

Top Contributor
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

Mitglied
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...

Top Contributor
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

Mitglied
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...

Top Contributor
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

Mitglied
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...

Top Contributor
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...

Top Contributor
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.
Java:
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

Mitglied
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)

Java:
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

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

Java:
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...

Top Contributor
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

Mitglied
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.

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:
Java:
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...

Top Contributor
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

Mitglied
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...

Top Contributor
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

Mitglied
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:
Java:
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...

Top Contributor
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

Mitglied
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 :D

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

Mitglied
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:
Java:
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...

Top Contributor
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:
Java:
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.
mit
Code:
h.get(Object key)
Allerdings richt die Anmerkung mit der Hintergrundfarbe, danach dass Du Datenmodell und Repräsentation vermischt?
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

Mitglied
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.

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:

Java:
...
			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?

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...

Top Contributor
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.

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.
Java:
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

Mitglied
Du übergibst diese Objekte einfach eine DefaultMutableTreeNode, diese Klasse kann ja Objekte aller Art entgegennehmen.
Java:
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?

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...

Top Contributor
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)


Java:
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

Mitglied
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 ;);)

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.

Java:
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...

Top Contributor
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
Java:
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

Mitglied
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:
Java:
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);
	}
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
FrittenFritze JTree, LazyLoading und "Rückwärtstraversion" AWT, Swing, JavaFX & SWT 3
J Falsches Rendern durch JCheckBox in eigenem JTree AWT, Swing, JavaFX & SWT 6
F jTree und das Model aus einer eigenen Klasse AWT, Swing, JavaFX & SWT 1
F Jtree aus Klasse mit Arraylisten AWT, Swing, JavaFX & SWT 1
A Swing JList zu JTree AWT, Swing, JavaFX & SWT 11
richis-fragen JTree +/- verschwidet wenn Knoten keine Kinder hat... AWT, Swing, JavaFX & SWT 6
RalleYTN Modaler Dialog und JTree Node mit sehr... seeeeehr vielen Elementen AWT, Swing, JavaFX & SWT 6
Z Swing JTree DefaultMultipleTreeNode Repräsentation ändern AWT, Swing, JavaFX & SWT 1
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
W Swing Anzeigefehler bei JTree AWT, Swing, JavaFX & SWT 1
S Zwei JTree, ein Model, bei Selection im ersten JTree soll der zweite die Inhlate anzeigen AWT, Swing, JavaFX & SWT 2
S JRadioButton und JCheckBox im JTree AWT, Swing, JavaFX & SWT 14
H Swing JTree: Zählt der rootNode mit? AWT, Swing, JavaFX & SWT 2
krgewb Swing JTree - Farbe von nodes ändern AWT, Swing, JavaFX & SWT 4
R JTree behandeln AWT, Swing, JavaFX & SWT 2
E Swing Copy und Paste eines einzelnen Knoten aus einem JTree AWT, Swing, JavaFX & SWT 1
U dynamisches JTree erstellen AWT, Swing, JavaFX & SWT 2
J JTree updaten AWT, Swing, JavaFX & SWT 2
N Swing JTree Problem beim erstellen der Knoten AWT, Swing, JavaFX & SWT 0
H JTree in JScrollPane passt sich nicht an Größe von JPanel an AWT, Swing, JavaFX & SWT 2
T Swing API Frage zu Verzeichnisbäumen und JTree AWT, Swing, JavaFX & SWT 1
T JTree mit Symbolen? AWT, Swing, JavaFX & SWT 8
R Anfängerfrage: Ansichten des JTree AWT, Swing, JavaFX & SWT 1
H Swing JTree Minimumgröße AWT, Swing, JavaFX & SWT 2
F Swing JTree + DiffUtils // Markierung Nodes aufheben AWT, Swing, JavaFX & SWT 2
I JTree wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
M Swing JTree AWT, Swing, JavaFX & SWT 4
M Nodes in JTree nicht anzeigen AWT, Swing, JavaFX & SWT 0
T JTree mit Cloud verbinden AWT, Swing, JavaFX & SWT 0
H JTree Probleme AWT, Swing, JavaFX & SWT 9
F Swing Drag and Drop in JTree aus verschiedenen Listen AWT, Swing, JavaFX & SWT 6
M JButton wird von JTree überdeckt AWT, Swing, JavaFX & SWT 4
J Auf Dateien in JTree zugreifen AWT, Swing, JavaFX & SWT 15
F jTree.startEditingAtPath(path); funktioniert nicht bei eigenem CellEditor? AWT, Swing, JavaFX & SWT 8
D Swing JTree Steuerung AWT, Swing, JavaFX & SWT 11
S Swing JTree verwirrt mich AWT, Swing, JavaFX & SWT 2
T JTree - Elemente mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 6
J JTree speichern AWT, Swing, JavaFX & SWT 4
N Swing JTree TreeCellRenderer mit html und automatischen Zeilenumbruch AWT, Swing, JavaFX & SWT 8
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
T JTree, Knoten mehrmals verwenden AWT, Swing, JavaFX & SWT 5
B JTree mit Ordneransicht in JPanel einbinden AWT, Swing, JavaFX & SWT 4
D JTree node reagiert bei Klick nicht immer AWT, Swing, JavaFX & SWT 2
M Swing JTree: Wie kann ich die Hintergrundfarbe der selection ändern?!?! AWT, Swing, JavaFX & SWT 7
D Mehrmals auf Node im JTree klicken AWT, Swing, JavaFX & SWT 2
D JSplitPane, Jtree, CardLayout (constraint must be a string) AWT, Swing, JavaFX & SWT 9
N Swing FileFilter lässt JTree sich nicht öffnen AWT, Swing, JavaFX & SWT 2
X Swing 2 TreeModel und ein JTree synchronisieren AWT, Swing, JavaFX & SWT 3
N Swing JTree TreePath zu Windows Pfad? AWT, Swing, JavaFX & SWT 2
RELAXccc Swing JTree + JScrollPane, refresh Problem AWT, Swing, JavaFX & SWT 17
X Swing JTree aktualisieren AWT, Swing, JavaFX & SWT 2
V Swing JTree - Umbenennen selbst handlen. AWT, Swing, JavaFX & SWT 2
E Übergebenem JTree Blätter hinzufügen AWT, Swing, JavaFX & SWT 2
E Wert eines selektierten Knotens in einem JTree auslesen AWT, Swing, JavaFX & SWT 3
A Swing JTree - Nodes expanden AWT, Swing, JavaFX & SWT 2
D JTree nach Klick auf einen Hyperlink aktualisieren AWT, Swing, JavaFX & SWT 3
B JTree AWT, Swing, JavaFX & SWT 9
T Menüacceleratoren verschwinden bei JTree AWT, Swing, JavaFX & SWT 5
1 Swing JTree collapse child nodes AWT, Swing, JavaFX & SWT 4
B JTree - sehr individuell AWT, Swing, JavaFX & SWT 3
G Swing JTree - Verbindungslinien entfernen AWT, Swing, JavaFX & SWT 4
A Swing Herausfinden ob bei JTree Klick auf "+"/"-" anahnd x,y AWT, Swing, JavaFX & SWT 2
S Swing JTree und seine Listener... AWT, Swing, JavaFX & SWT 4
L Swing JTree wird nicht selektiert AWT, Swing, JavaFX & SWT 2
P [JTree] Markierhilfe der Drop-Location selber gestalten. AWT, Swing, JavaFX & SWT 4
A JTree aus Pfaden erzeugen AWT, Swing, JavaFX & SWT 3
K Swing Hilfe beim JTree! AWT, Swing, JavaFX & SWT 3
X Datensätze in JTree AWT, Swing, JavaFX & SWT 2
L Update JTree Verzeichnisse AWT, Swing, JavaFX & SWT 9
E JTree Auswahl AWT, Swing, JavaFX & SWT 2
K JTree width der Treenodes auf 100% AWT, Swing, JavaFX & SWT 6
C JTree LastSelectedPathComponent benutzen? AWT, Swing, JavaFX & SWT 3
S Swing JTree Node Text nicht richtig angezeigt AWT, Swing, JavaFX & SWT 2
Landei Swing JTree mit "Tabellenzeilen"? AWT, Swing, JavaFX & SWT 5
Rudolf Swing JTree Node anhand vom Namen finden AWT, Swing, JavaFX & SWT 4
S JTree Elemente nach BaumLevel abspeichern AWT, Swing, JavaFX & SWT 2
Z JTree rootChilds AWT, Swing, JavaFX & SWT 2
D JTree DefaultMutableTreeNode ActionPerformed AWT, Swing, JavaFX & SWT 3
T JTree Daten in DB schreiben am besten SQL AWT, Swing, JavaFX & SWT 21
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
J Lazy Loading eine JTree während Scrollen AWT, Swing, JavaFX & SWT 11
S JTree & JComboBox - Elemente übers Fenster hinaus anzeigen AWT, Swing, JavaFX & SWT 9
E Swing JTree AWT, Swing, JavaFX & SWT 2
J Swing Lazy Loading in JTree wenn gescrollt wird AWT, Swing, JavaFX & SWT 3
N Knotenanordnung in JTree AWT, Swing, JavaFX & SWT 4
S JTree mit Liste zur Speicherung AWT, Swing, JavaFX & SWT 3
G JTree entfernt Nodes nicht AWT, Swing, JavaFX & SWT 12
C Swing JTree und TreeModel AWT, Swing, JavaFX & SWT 15
S Swing JTree wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
J JTree AWT, Swing, JavaFX & SWT 2
R [JTree/DefaultTreeCellRenderer] eigenes Renderer-Panel, so breit wie der JTree AWT, Swing, JavaFX & SWT 2
S Swing JTree mit KeyListener AWT, Swing, JavaFX & SWT 2
E Swing JTree setSelectedPath funktioniert nicht?! AWT, Swing, JavaFX & SWT 5
E JTree Autoscroll bei Drag and Drop AWT, Swing, JavaFX & SWT 4
S JTree aus List<File> erstellen AWT, Swing, JavaFX & SWT 8
C Swing MouseEntered(?) für jeden Node im JTree AWT, Swing, JavaFX & SWT 4
M JTree mit eigenen Knoten - Zugriff auf Daten AWT, Swing, JavaFX & SWT 6
C Swing JTree UI Probleme AWT, Swing, JavaFX & SWT 6
G JTree - Observer oder Listener? AWT, Swing, JavaFX & SWT 6
L Swing [JTree] Selektierte Nodes nummerieren AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen

Neue Themen


Oben