不使用 setXXXSize 时使用 JComboBox 的 Swing BoxLayout 问题

发布于 2024-12-06 22:47:30 字数 2004 浏览 1 评论 0原文

这是一个 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. 北面板应保持在顶部,并根据框架尺寸修改相应地更改其尺寸(似乎工作正常)
  2. 我放置 JButton 的绿色面板应保持最大尺寸的 JButton 并停留在上面的蓝色面板下方(如果我只将 JButton 放在该面板内,则效果很好)。

如果我将 JComboBox 放入绿色面板中(尝试取消 SSCCE 中该行的注释),就会出现问题。我猜想 JComboBox 没有指定最大尺寸,因此它会随框架一起拉伸。在我的代码的先前错误版本中,我在 JComboBox 上使用 setxxxSize 方法来限制它的尺寸(尝试取消注释 setXXXSize 方法上的行以查看它)。

我的问题是:

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

请引导我走向正确的方向

here's an 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();
    }

}

I'm trying to refactor some classes I wrote some time ago, when I didn't know that using setXXXSize methods on components is wrong.
Using a resizable frame ,the result I want to achieve is the following:

  1. The northPanel should stay on top and change it's size accordingly to the frame size modifications (seems to work fine)
  2. The green panel where I put the JButton should keep the maximum dimension of the JButton and stay just below the blue panel above (this works fine if I only put JButtons inside that panel).

The problem arise if I put a JComboBox inside the green panel (try to uncomment the line in the SSCCE). I guess JComboBox hasn't a maximum size specified, so it stretches with the frame. In the previous wrong version of my code I was using setxxxSize methods on the JComboBox to limit it's dimension(try to uncomment the line on setXXXSize methods to see it).

My question are:

  1. Is it possible to achieve the same result using BoxLayout without invoking setXXXSize() methods?
  2. If yes, how?
  3. Is there any other LayoutManager that can I use to get that effect?

Please put me in the right direction

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雾里花 2024-12-13 22:47:30

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

JComboBox is misbehaving (the same as JTextField) in reporting an unbounded max height: should never show more than a single line. Remedy is the same: subclass and return a reasonable height

        JComboBox b = new JComboBox() {

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

        };

just for fun, here's a snippet using MigLayout (which is my personal favorite currently :-)

    // 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");
故事↓在人 2024-12-13 22:47:30

我一直认为使用 jdk 中的布局管理器并不容易。它们要么太简单、不灵活,要么 gridbaglayout 太麻烦。相反,我开始使用 jgoodies 表单布局,从此再也没有回头过......看看它。它非常简单且易于使用。这是一个链接:

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

确保你仔细阅读白皮书。

现在,我们还让 google 为我们提供了一个用于 formlayout 的 WYSISWG 编辑器作为 eclipse 的插件。这只会让生活变得更加轻松。

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

I have always seen using the layout managers in the jdk are not easy. They are either too simple and inflexible or the gridbaglayout is just too much trouble. Instead I started using the jgoodies form layout and never looked back since.. Have a look at it. Its very simple and easy to use. Here's a link:

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

Make sure you go through the white paper.

And now, we also have google providing us a WYSISWG editor for the formlayout as a plugin for eclipse. This just makes life a lot lot easier.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文