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 всем, кто может помочь :)


person Kenny83    schedule 25.10.2014    source источник
comment
В итоге я решил это сам, явно настроив внешний вид, который я хотел. Все равно спасибо ребята :-)   -  person Kenny83    schedule 26.10.2014


Ответы (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(...), чтобы установить предпочтительную ширину безопасным для PLaF способом.

person dic19    schedule 25.10.2014
comment
В любом случае спасибо, но я пробовал оба ваших предложения безрезультатно... Я согласен, что это невероятно хакерский/грязный, но мне нужно, чтобы мое поле со списком было высотой не менее 40 пикселей неважно что... Я снова разговаривал со своим учителем (это задание университета), и он вообще не желает сдвинуться с места по этому вопросу... так что, черт возьми, я должен делать?! Используйте панель GroupLayouted внутри FormLayout?? Теперь это то, что я называю действительно хакерским! - person Kenny83; 26.10.2014