Проблема Swing BoxLayout с JComboBox без использования setXXXSize - PullRequest
5 голосов
/ 28 сентября 2011

вот SSCCE:

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class BoxLayoutTest extends JFrame {

    public BoxLayoutTest(){
        JPanel main = new JPanel();
        main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
        main.setBackground(Color.red);
        this.add(main);
        JPanel northPanel = new JPanel();

        JPanel middle = new JPanel();
        middle.setLayout(new BoxLayout(middle, BoxLayout.X_AXIS));
        middle.add(new JButton("FOO"));
        middle.add(Box.createHorizontalGlue());

        JPanel aPanel = new JPanel();
        aPanel.setBackground(Color.black);

            JComboBox b = new JComboBox();
    //b.setPreferredSize(new Dimension(100,16)); //uncomment this to see the layout I would like to achieve
    //b.setMaximumSize(new Dimension(100,16));
        //middle.add(b); //uncomment this line 

        middle.setBackground(Color.green);
        northPanel.setBackground(Color.blue);

        main.add(northPanel);
        main.add(middle);
        main.add(Box.createVerticalGlue());

        this.setSize(800,600);
        this.setResizable(true);
        this.setVisible(true);
    }

    public static void main(String[] args) {
        new BoxLayoutTest();
    }

}

Я пытаюсь реорганизовать некоторые классы, которые я написал некоторое время назад, когда я не знал, что использование методов setXXXSize в компонентах неправильно.Используя рамку с изменяемым размером, я хочу получить следующий результат:

  1. NorthPanel должен оставаться сверху и изменять свой размер в соответствии с изменениями размера рамки (кажется, работает нормально)
  2. Зеленая панель, в которую я положил JButton, должна сохранять максимальный размер JButton и оставаться чуть ниже синей панели выше (это прекрасно работает, если я помещаю JButton только внутри этой панели).

проблема возникает, если я помещаю JComboBox в зеленую панель (попробуйте раскомментировать строку в SSCCE).Я предполагаю, что у JComboBox не указан максимальный размер, поэтому он растягивается с рамкой.В предыдущей неправильной версии моего кода я использовал методы setxxxSize в JComboBox, чтобы ограничить его размерность (попробуйте раскомментировать строку в методах setXXXSize, чтобы увидеть его).

Мой вопрос:

  1. Можно ли достичь того же результата, используя BoxLayout, без вызова методов setXXXSize ()?
  2. Если да, то как?
  3. Есть ли другой LayoutManager, который можно использовать для получения этого эффекта?

Пожалуйста, поставьте меня в правильном направлении

Ответы [ 2 ]

9 голосов
/ 28 сентября 2011

JComboBox ведет себя неправильно (так же, как и JTextField), сообщая о неограниченной максимальной высоте: никогда не должен отображать более одной строки. Средство не изменилось: подкласс и возвращение разумной высоты

        JComboBox b = new JComboBox() {

            /** 
             * @inherited <p>
             */
            @Override
            public Dimension getMaximumSize() {
                Dimension max = super.getMaximumSize();
                max.height = getPreferredSize().height;
                return max;
            }

        };

просто для удовольствия, вот фрагмент, использующий MigLayout (который сейчас мой личный фаворит: -)

    // two panels as placeholders
    JPanel northPanel = new JPanel();
    northPanel.setBackground(Color.YELLOW);
    JPanel southPanel = new JPanel();
    southPanel.setBackground(Color.YELLOW);
    // layout with two content columns
    LC layoutContraints = new LC().wrapAfter(2)
            .debug(1000);
    AC columnContraints = new AC()
    // first column pref, followed by greedy gap
            .size("pref").gap("push")
            // second
            .size("pref");
    // three rows, top/bottom growing, middle pref
    AC rowContraints = new AC()
       .grow().gap().size("pref").gap().grow();
    MigLayout layout = new MigLayout(layoutContraints, columnContraints,
            rowContraints);
    JPanel main = new JPanel(layout);
    main.setBackground(Color.WHITE);
    // add top spanning columns and growing
    main.add(northPanel, "spanx, grow");
    main.add(new JButton("FOO"));

    // well-behaved combo: max height == pref height
    JComboBox combo = new JComboBox() {

        @Override
        public Dimension getMaximumSize() {
            Dimension max = super.getMaximumSize();
            max.height = getPreferredSize().height;
            return max;
        }

    };
    // set a prototype to keep it from constantly adjusting
    combo.setPrototypeDisplayValue("somethingaslongasIwant");

    main.add(combo);
    // add top spanning columns and growing
    main.add(southPanel, "spanx, grow");
3 голосов
/ 28 сентября 2011

Я всегда видел, как с помощью менеджеров макетов в JDK не так просто. Они либо слишком просты и негибки, либо слишком мало проблем с решеткой. Вместо этого я начал использовать макет формы jgoodies и больше никогда не оглядывался назад. Посмотрите на это. Это очень просто и легко в использовании. Вот ссылка:

http://www.jgoodies.com/freeware/forms/

Обязательно ознакомьтесь с белой бумагой.

И теперь у нас также есть Google, предоставляющий нам редактор WYSISWG для formlayout в качестве плагина для eclipse. Это просто делает жизнь намного проще.

http://code.google.com/javadevtools/wbpro/palettes/swing_palette.html

...