JGoodies FormLayout отказывается изменить размер моего JComboBox

Кажется, что JComboBox - это один Java-компонент, который действительно очень не хочет настраивать его высоту... Я пробовал бесчисленные комбинации set[Preferred|Minimum|Maximum]Size() и различные различные менеджеры макетов до следующего GroupLayout код наконец заработал:

JComboBox cmbCategories = new JComboBox(new String[] { "Category 1", "Category 2" });
...
layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
        .addComponent(cmbCategories, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE)
...
layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
        .addComponent(cmbCategories, GroupLayout.PREFERRED_SIZE, 40, GroupLayout.PREFERRED_SIZE)

Но теперь я перешел на JGoodies FormLayout который еще раз отказывается изменить размер чертового списка! В настоящее время я получил следующий код:

JPanel contentPane = new JPanel();
contentPane.setLayout(new FormLayout("50dlu, $lcgap, 110dlu, $glue, " +
    "default, 1dlu, 45dlu, 1dlu, 45dlu", "2*(default, 0dlu), default, " +
    "$lgap, fill:30dlu, $lgap, default:grow"));
...
contentPane.add(cmbPanel, CC.xy(1, 7, CC.FILL, CC.FILL));

который отображает то, что я хочу, в редакторе JFormDesigner, но после запуска программы он просто возвращается к значению по умолчанию!

Так какого рода волшебный фокус-фокус мне нужно вызвать в воображении, чтобы это сработало?! Я действительно не хочу возвращаться к определению всего дважды в GroupLayout, но после 5 часов попыток изменить размер чертового комбобокса я на грани облысения!

MTIA всем, кто может помочь:)

1 ответ

Прежде всего, мы должны избегать установки жестко закодированных размеров в наших компонентах, потому что Swing предназначен для использования с менеджерами компоновки, и наше приложение должно быть способно выполняться на разных платформах, разных разрешениях экрана, разных PLaF и разных шрифтах. размеры. Определение размера и расположение компонентов - это ответственность менеджеров по компоновке, а не разработчиков.

Теперь, вообще говоря, когда мы хотим установить предпочтительный размер для наших компонентов Swing, мы не используем setXxxSize() методы, но переопределяют getPreferredSize() метод вместо:

JComboBox comboBox = new JComboBox() {
    @Override
    public Dimension getPreferredSize() {
        return isPreferredSizeSet() ? 
                super.getPreferredSize() : new Dimension(100, 40);
    }
};

Однако выполнение этого не влияет на размер элементов в списке, когда всплывающее окно становится видимым: ячейки по-прежнему имеют предпочтительный размер, определенный средством визуализации ячеек со списком. Итак, чтобы избежать этого нежелательного поведения, лучшим решением будет:

Например:

JComboBox comboBox = new JComboBox();
comboBox.setPrototypeDisplayValue("This is a cell's prototype text");
comboBox.setRenderer(new DefaultListCellRenderer() {
    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        int width = c.getPreferredSize().width; // let the preferred width based on prototype value
        int height = 40;
        c.setPreferredSize(new Dimension(width, height));
        return c;
    }
});

Еще раз хочу подчеркнуть, что это своего рода хакерский / грязный способ определения размера нашего поля со списком. ИМХО, лучше бы вообще не связываться с высотой комбо-бокса, а просто поиграть с setPrototypeDisplayValue(...) установить предпочтительную ширину безопасным способом.

Другие вопросы по тегам