java - 不使用 setXXXSize 的 JComboBox 的 Swing BoxLayout 问题

标签 java swing jcombobox layout-manager boxlayout

这是一个 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 没有指定最大尺寸,所以它会随框架一起拉伸(stretch)。在我的代码的前一个错误版本中,我在 JComboBox 上使用 setxxxSize 方法来限制它的维度(尝试取消注释 setXXXSize 方法上的行以查看它)。

我的问题是:

  1. 是否可以在不调用 setXXXSize() 方法的情况下使用 BoxLayout 获得相同的结果?
  2. 如果是,怎么做?
  3. 我可以使用任何其他 LayoutManager 来获得这种效果吗?

请把我引向正确的方向

最佳答案

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");

关于java - 不使用 setXXXSize 的 JComboBox 的 Swing BoxLayout 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7581846/

相关文章:

java - 使用 JAVA swing 选择日历或 slider 中的日期范围

java - 当我运行它时图表不会显示?

java - 程序运行时更改笔画大小

java - 数字签名 jar 文件

java - NewProxyCallableStatement 无法转换为 SQLServerCallableStatement

java - 如何等到 TCP 端口在 Java 中真正( native )关闭?

java - 操作 JComboBox

java - 嵌套运行时异常 : Cannot parse POST parameters of request

java - 将 Jbutton 添加到 Jpanel

java - JTable 中 JComboBox 的单元格渲染器类,构造函数中不带参数