Swing JTree mit "Tabellenzeilen"?

Landei

Top Contributor
Ich muss meine GUI von einer Tabelle auf einen Tree ändern. Allerdings habe ich ziemlich viele Werte in einer Zeile, und muss auch weiterhin in der Lage sein, einzelne "Zellen" ansprechen zu können (also z.B. editieren oder einfärben). Leider kommt eine JTreeTable nicht in Betracht, da die einzelnen Knotentypen völlig unterschiedliche "Spalten" haben. Kennt ihr da schon etwas fertiges?
 
Soweit bin ich inzwischen (die Zeilen sind hier alle gleich, würden sich aber im richtigen Leben unterscheiden). Jetzt müsste ich nur noch die Komponenten "editierbar" machen. Habt ihr da ein Beispiel für mich?
 

Anhänge

  • tree.png
    tree.png
    39,2 KB · Aufrufe: 42
Schon klar, aber wie ich das mit mehreren Komponenten zusammendöpseln muss, muss ich erst mal "auseruieren". Deshalb da hatte ich auf ein Beispiel gehofft (etwa Knoten mit einer JCheckBox und einem JTextField oder so). Außerdem soll z.B. ein Button in der Leiste möglichst sofort reagieren, und nicht erst, nachdem der Knoten irgendwie im Editmodus landet.
 
Habe mal eine alte Demo von mir umgebaut:
Java:
package demo;

import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;

public class TreeButtonEditorRendererDemo extends JFrame {
	private JTree tree;
	private DefaultTreeModel model;

	public TreeButtonEditorRendererDemo() {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
		root.add(new DefaultMutableTreeNode(0));
		root.add(new DefaultMutableTreeNode(0));
		root.add(new DefaultMutableTreeNode(0));
		model = new DefaultTreeModel(root);
		tree = new JTree(model);
		tree.setCellRenderer(new CustomRenderer(new NodeComponent()));
		tree.setCellEditor(new CustomEditor(tree, new NodeComponent()));
		tree.setEditable(true);

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

	class NodeComponent extends JPanel {
		private JLabel label;
		private JButton button;

		public NodeComponent() {
			this.setLayout(new GridLayout(1, 2));
			add(button = new JButton("+"));
			add(label = new JLabel("", JLabel.RIGHT));
		}

		public void setValue(String text) {
			label.setText(text);
		}

		public Object getValue() {
			return label.getText();
		}
		
		public void increase() {
			label.setText("" + (Integer.parseInt(label.getText())+1));
		}

		public void addActionListener(ActionListener listener) {
			button.addActionListener(listener);
		}
	}

	class CustomRenderer extends DefaultTreeCellRenderer {
		private NodeComponent nodePanel;

		public CustomRenderer(NodeComponent comp) {
			nodePanel = comp;
		}

		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);
			DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
			if (treeNode.isLeaf()) {
				nodePanel.setValue(treeNode.getUserObject().toString());
				nodePanel.setBackground(super.getBackground());
				return nodePanel;
			}
			this.setIcon(null);
			return this;
		}
	}

	class CustomEditor implements TreeCellEditor, ActionListener {
		private JTree tree;
		private NodeComponent nodePanel;

		public CustomEditor(JTree tree, NodeComponent comp) {
			this.tree = tree;
			this.nodePanel = comp;
			this.nodePanel.addActionListener(this);
		}

		public void actionPerformed(ActionEvent evt) {
			nodePanel.increase();
			tree.stopEditing();
		}

		public Component getTreeCellEditorComponent(JTree tree, Object value,
				boolean isSelected, boolean expanded, boolean leaf, int row) {
			DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) value;
			if (treeNode.isLeaf()) {
				nodePanel.setValue(treeNode.getUserObject().toString());
				return nodePanel;
			}
			return tree.getCellRenderer().getTreeCellRendererComponent(tree,
					value, true, true, false, row, true);
		}

		public Object getCellEditorValue() {
			return nodePanel.getValue();
		}

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

		public boolean stopCellEditing() {
			return true;
		}

		public void addCellEditorListener(CellEditorListener l) {
		}

		public void cancelCellEditing() {
		}

		public void removeCellEditorListener(CellEditorListener l) {
		}

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

	public static void main(String[] args) {
		JFrame frame = new TreeButtonEditorRendererDemo();
		frame.setBounds(0, 0, 500, 300);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}
}
 
Danke, probiere ich morgen aus!

Inzwischen ist meine Optik ganz brauchbar, aber Editieren fehlt immer noch. Die Arbeit mit Trees ist wirklich mühselig, heute habe ich ewig gesucht, wie ich den Tree darüber informieren kann, dass ein Node geändert wurde (fürs Protokoll: Das TreeModel muss erst zu einem DefaultTreeModel gecastet werden, und das hat dann entsprechende Methoden). Wirklich grausam, sobald man irgend etwas mit dem Ding machen will, was nicht ganz ins vorgesehene Schema passt.
 

Neue Themen


Zurück
Oben