是否可以在 JCombobox 中添加树?

Is it possible to add a Tree inside a JCombobox?

由于我的 JComboBox 中有太多选项,我认为或许可以根据它们在不同节点中的类型对它们进行重新分组并让用户根据他们喜欢的类型展开或折叠它们是个好主意。这将提高 JComboBox 的可读性,并为用户节省大量时间向下或向上滚动寻找他们的选项。

现在的问题是,是否可以在JComboBox中添加一棵树?

我在 SO 上找到的最接近解决方案的是这个:One Alternative

提出替代方案的人建议如下:

If you need expansion of nodes, then a better option would be to add a popup that appears below a button that listens for selections of items in the tree. Something like this might be a better choice depending on how your GUI is laid out.

但是,除非我误解了他们在说什么,否则他们不会在 JComboBox 中添加树,这正是我在这里想要的。

是的,您可以将弹出组件中的 JList 替换为 JTree。但是您还需要提供 ComboBoxModelTreeModel 之间的通信(当一个项目在 JTree 中被选中时,它也会在 JComboBox 中被选中,反之亦然)。例如,您可以构建 ComboBoxModel 的实现,它有一个 TreeModel 作为委托,并在每次 TreeModel 更改(触发 TreeModelEvent)时提供树的线性化,获取组合框的项目列表。您还需要为树中的 mouse/key 事件提供反应,以更新组合框中的选择。

您可以使用以下方法将任何组件设置为 JComboBox 的弹出窗口(在您的情况下,它应该是包装 JTreeJScrollPane):

/**
 * Sets the custom component as popup component for the combo-box.
 *
 * @param combo combo-box to get new popup component.
 * @param comp new popup component.
 * @param widthIncr width increment for pop-up.
 * @param heightIncr height increment for pop-up.
 */
public static void setPopupComponent(JComboBox<?> combo, Component comp, int widthIncr, int heightIncr) {
    final ComboPopup popup = (ComboPopup) combo.getUI().getAccessibleChild(combo, 0);
    if (popup instanceof Container) {
        final Container c = (Container) popup;
        c.removeAll();
        c.setLayout(new GridLayout(1, 1));
        c.add(comp);
        final Dimension size = comp.getPreferredSize();
        size.width += widthIncr;
        size.height += heightIncr;
        c.setPreferredSize(size);
    }
}

参数 widthIncrheightIncr 可用于某些外观,以更好地采用组合框中默认的 width/heght 弹出窗口。