Jtrees 和组合框布局
Jtrees and combobox layout
所以我有一个 JTree,它将有不同数量的叶子和节点,我需要在树的叶子旁边添加 JComboBoxes,但是 tree.I 的其他部分没有尝试使用屏幕位置叶子和边框布局来实现这个但是盒子总是结束,当我有很多叶子时它变得非常糟糕而且它们似乎也只是定位在框架中的 1 个位置并且随着每个新的组合框不断挤压自己更薄添加。我怎么可能实现我正在寻找的东西?
i need to add JComboBoxes next to the leaves of the tree but no other part of the tree
考虑创建自己的 TreeCellRenderer
,将 JComboBox
直接合并到 JTree
中。要允许编辑 JComboBox,您还需要实现一个 TreeCellEditor
来处理编辑组件和编辑完成时该组件发生的操作。下面是一个非常简单的示例,它在 JTree
的叶子中将 JComboBox
放在 JLabel
旁边
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultTreeModel model = new DefaultTreeModel(root);
final JTree tree = new JTree(model);
//flyweight pattern components
//editor
final JComboBox editorComboBox = new JComboBox();
final JComboBox viewComboBox = new JComboBox();
final Box box = Box.createHorizontalBox();
final JLabel myLabel = new JLabel();
myLabel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 10));
box.add(myLabel);
box.add(Box.createHorizontalGlue());
box.add(viewComboBox);
//Custom Renderer
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer (){
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if ( leaf ){
if ( value instanceof MyLeafNode ){
MyLeafNode node = (MyLeafNode)value;
viewComboBox.removeAllItems();
myLabel.setText(value.toString());
for ( String item : node.items ){
viewComboBox.addItem(item);
}
viewComboBox.setSelectedItem(node.selected);
return box;
}
}
return this;
}
};
//Custom Editor
final DefaultTreeCellEditor editor = new DefaultTreeCellEditor(tree, renderer){
final ActionListener actionListener = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
cancelCellEditing();
tree.repaint();
}
};
@Override
public boolean isCellEditable(EventObject e){
if ( e.getSource() instanceof JTree ){
JTree tree = (JTree)e.getSource();
if ( tree.getLastSelectedPathComponent() == null ){
return false;
}
DefaultMutableTreeNode o = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
return o.isLeaf();
}
return false;
}
@Override
public void cancelCellEditing(){
super.cancelCellEditing();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if ( node instanceof MyLeafNode) {
String sel = editorComboBox.getSelectedItem().toString();
MyLeafNode mln = (MyLeafNode)node;
mln.selected = sel;
editorComboBox.removeActionListener(actionListener);
tree.repaint();
}
}
@Override
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
if ( leaf ){
if ( tree.getLastSelectedPathComponent() instanceof MyLeafNode ){
MyLeafNode o = (MyLeafNode)tree.getLastSelectedPathComponent();
editorComboBox.removeAllItems();
for ( String item : o.items ){
editorComboBox.addItem(item);
}
editorComboBox.setSelectedItem(o.selected);
editorComboBox.addActionListener(actionListener);
}
return editorComboBox;
}
return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
}
};
tree.setCellRenderer(renderer);
TreePath path = new TreePath(new TreeNode[]{root});
tree.expandPath(path);
for ( int i = 0; i < 2; i++ ){
DefaultMutableTreeNode p = new DefaultMutableTreeNode("P" + i);
model.insertNodeInto(p, root, i);
for ( int j = 0; j < 2; j++ ){
String[] items = {"Item 1", "Item 2", "Item 3", "Item 4"};
MyLeafNode n = new MyLeafNode("N" + j, items);
model.insertNodeInto(n, p, j);
}
path = new TreePath(new TreeNode[]{root, p});
tree.expandPath(path);
}
tree.setCellEditor(editor);
tree.setEditable(true);
JScrollPane scroller = new JScrollPane(tree);
frame.add(scroller);
frame.pack();
frame.setVisible(true);
其中MyLeafNode
是自定义的class用于存储JComboBox特定数据:
public class MyLeafNode extends DefaultMutableTreeNode{
private String[] items;
private String selected;
public MyLeafNode(String name, String...items){
super(name);
this.items = items;
this.selected = items[0];
}
}
所以我有一个 JTree,它将有不同数量的叶子和节点,我需要在树的叶子旁边添加 JComboBoxes,但是 tree.I 的其他部分没有尝试使用屏幕位置叶子和边框布局来实现这个但是盒子总是结束,当我有很多叶子时它变得非常糟糕而且它们似乎也只是定位在框架中的 1 个位置并且随着每个新的组合框不断挤压自己更薄添加。我怎么可能实现我正在寻找的东西?
i need to add JComboBoxes next to the leaves of the tree but no other part of the tree
考虑创建自己的 TreeCellRenderer
,将 JComboBox
直接合并到 JTree
中。要允许编辑 JComboBox,您还需要实现一个 TreeCellEditor
来处理编辑组件和编辑完成时该组件发生的操作。下面是一个非常简单的示例,它在 JTree
JComboBox
放在 JLabel
旁边
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultTreeModel model = new DefaultTreeModel(root);
final JTree tree = new JTree(model);
//flyweight pattern components
//editor
final JComboBox editorComboBox = new JComboBox();
final JComboBox viewComboBox = new JComboBox();
final Box box = Box.createHorizontalBox();
final JLabel myLabel = new JLabel();
myLabel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 10));
box.add(myLabel);
box.add(Box.createHorizontalGlue());
box.add(viewComboBox);
//Custom Renderer
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer (){
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if ( leaf ){
if ( value instanceof MyLeafNode ){
MyLeafNode node = (MyLeafNode)value;
viewComboBox.removeAllItems();
myLabel.setText(value.toString());
for ( String item : node.items ){
viewComboBox.addItem(item);
}
viewComboBox.setSelectedItem(node.selected);
return box;
}
}
return this;
}
};
//Custom Editor
final DefaultTreeCellEditor editor = new DefaultTreeCellEditor(tree, renderer){
final ActionListener actionListener = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
cancelCellEditing();
tree.repaint();
}
};
@Override
public boolean isCellEditable(EventObject e){
if ( e.getSource() instanceof JTree ){
JTree tree = (JTree)e.getSource();
if ( tree.getLastSelectedPathComponent() == null ){
return false;
}
DefaultMutableTreeNode o = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
return o.isLeaf();
}
return false;
}
@Override
public void cancelCellEditing(){
super.cancelCellEditing();
DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if ( node instanceof MyLeafNode) {
String sel = editorComboBox.getSelectedItem().toString();
MyLeafNode mln = (MyLeafNode)node;
mln.selected = sel;
editorComboBox.removeActionListener(actionListener);
tree.repaint();
}
}
@Override
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
if ( leaf ){
if ( tree.getLastSelectedPathComponent() instanceof MyLeafNode ){
MyLeafNode o = (MyLeafNode)tree.getLastSelectedPathComponent();
editorComboBox.removeAllItems();
for ( String item : o.items ){
editorComboBox.addItem(item);
}
editorComboBox.setSelectedItem(o.selected);
editorComboBox.addActionListener(actionListener);
}
return editorComboBox;
}
return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row);
}
};
tree.setCellRenderer(renderer);
TreePath path = new TreePath(new TreeNode[]{root});
tree.expandPath(path);
for ( int i = 0; i < 2; i++ ){
DefaultMutableTreeNode p = new DefaultMutableTreeNode("P" + i);
model.insertNodeInto(p, root, i);
for ( int j = 0; j < 2; j++ ){
String[] items = {"Item 1", "Item 2", "Item 3", "Item 4"};
MyLeafNode n = new MyLeafNode("N" + j, items);
model.insertNodeInto(n, p, j);
}
path = new TreePath(new TreeNode[]{root, p});
tree.expandPath(path);
}
tree.setCellEditor(editor);
tree.setEditable(true);
JScrollPane scroller = new JScrollPane(tree);
frame.add(scroller);
frame.pack();
frame.setVisible(true);
其中MyLeafNode
是自定义的class用于存储JComboBox特定数据:
public class MyLeafNode extends DefaultMutableTreeNode{
private String[] items;
private String selected;
public MyLeafNode(String name, String...items){
super(name);
this.items = items;
this.selected = items[0];
}
}