更改 JComboBox 的内部弹出窗口 (JList) 的边框颜色

Change the border color of the inner popup (JList) of a JComboBox

我有一个 JComboBox,其中关于布局的几乎所有内容都已更改。我更改了弹出窗口中的选择颜色、箭头按钮、背景颜色等。最后剩下的部分是弹出窗口的边框颜色(内部 JList)。

我的组合框是这样的:

如您所见,它有一个黑色边框,与整个布局不匹配。我想将其更改为您在上方边框中看到的蓝色。

我做了一些研究,但没有适合我的解决方案。最接近的解决方案是 post。但是没用。

随着选择颜色的改变,我已经尝试通过以下方式改变边框颜色:

public static void setSelectionColorOfComboBox(JComboBox<String> comboBox)
{
    Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
    BasicComboPopup popup = (BasicComboPopup) child;
    JList list = popup.getList();
    list.setBorder(new LineBorder(ColorPalette.LIGHT_BLUE, 1));
    list.setSelectionBackground(ColorPalette.LIGHT_BLUE);
    list.setSelectionForeground(Color.WHITE);
    list.setFocusable(false);
}

为了确保不错过任何东西,我创建了一个单独的方法来更改边框,根据上面的链接 post:

public static void setBorderColorOfComboBoxPopup(JComboBox<String> comboBox)
{
    Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
    BasicComboPopup popup = (BasicComboPopup) child;
    JList list = popup.getList();
    list.setBorder(new LineBorder(ColorPalette.LIGHT_BLUE));
}

但这也没有用。有谁知道为什么这些常用方法对我不起作用,或者至少有谁知道另一种更改边框颜色的方法,以便我可以尝试不同的方法?

目前我在考虑,如果 JList 周围有类似滚动窗格的东西,我会研究一下是否可以访问它并设置它的边框,如果可能的话。

您可以覆盖 BasicComboBoxUI class 中的 createPopup() 方法来更改弹出窗口的边框:

jComboBox.setUI(new BasicComboBoxUI() {
    @Override
    protected ComboPopup createPopup() {
        BasicComboPopup basicComboPopup = new BasicComboPopup(comboBox);
        basicComboPopup.setBorder(new LineBorder(Color.RED));
        return basicComboPopup;
    }
});

经过数小时的尝试和研究,我对滚动窗格的最后想法在短短几分钟内引导我找到了解决方案。想到一个包含列表的组件,我想到了弹出窗口。弹出窗口包含两个级别,可以有边框。 第一个是弹出窗口中的 JList,第二个是弹出窗口本身。黑色边框以某种方式覆盖了我内部 JList 的蓝色边框。 长话短说,以下代码片段完成了工作:

public static void setBorderColorOfComboBoxPopup(JComboBox<String> comboBox)
{
    Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
    BasicComboPopup popup = (BasicComboPopup) child;
    popup.setBorder(new LineBorder(ColorPalette.LIGHT_BLUE));
//  JList list = popup.getList();
//  list.setBorder(new LineBorder(ColorPalette.LIGHT_BLUE));
}