【问题标题】:Setting the width of a JList in a JScrollPane with GridBagLayout使用 GridBagLayout 在 JScrollPane 中设置 JList 的宽度
【发布时间】:2015-05-31 23:48:36
【问题描述】:

我有下面的示例 Java Swing 代码,它生成以下屏幕截图(屏幕截图已被编辑以使其更小):

代码如下:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;


public class Main extends JFrame {

    public Main() {
        JListTest theGui = new JListTest();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        add(theGui);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Main();
            }
        });
    }

    private class JListTest extends JPanel {
        private static final int PADDING = 3;
        private JLabel label;
        private JTextArea textarea;
        private String listOptions[] = 
            {"here is some veeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrry long text",
             "here is some more loooooooooooooooooooooooooooooooooooooooooooooooooooooong text",
             "here is some veeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrry long text",
             "here is some more loooooooooooooooooooooooooooooooooooooooooooooooooooooong text",
             "here is some veeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrry long text",
             "here is some more loooooooooooooooooooooooooooooooooooooooooooooooooooooong text",
             "here is some veeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrry long text",
             "here is some more loooooooooooooooooooooooooooooooooooooooooooooooooooooong text",
             "here is some veeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrrrrrrrrrrrry long text",
             "here is some more loooooooooooooooooooooooooooooooooooooooooooooooooooooong text"};
        private JList<String> list;
        private JScrollPane scrollpane;
        private GridBagConstraints gbc;

        public JListTest() {
            super(new GridBagLayout());
            label = new JLabel("Here is a label:");
            textarea = new JTextArea(20, 50);
            list = new JList<String>(listOptions);
            scrollpane = new JScrollPane(list);

            gbc = new GridBagConstraints();
            gbc.gridheight = 1;
            gbc.insets = new Insets(PADDING, PADDING, PADDING, PADDING);
            gbc.anchor = GridBagConstraints.LINE_START;

            gbc.gridwidth = 4;
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(label, gbc);

            // I want the scrollpane to take up 1/4 the width of the window.
            gbc.gridwidth = 1;
            gbc.gridx = 0;
            gbc.gridy = 1;
            add(scrollpane, gbc);

            // I want the textarea to take up 3/4 the width of the window.
            gbc.gridwidth = 3;
            gbc.gridx = 1;
            gbc.gridy = 1;
            add(textarea, gbc);
        }
    }
}

如您所见,我在左侧的 JScrollPane 和右侧的 JTextArea 中有一个 JList,其中包含带有很长文本的项目。我希望 JScrollPane/JList 占据窗口宽度的 1/4,并在 JList 项的文本过长时出现水平滚动条。我希望 JTextArea 占据窗口宽度的 3/4。

我尝试使用 GridBagLayout 来执行此操作,但显然我做得不对,因为外观已关闭。

感谢任何帮助。谢谢!

【问题讨论】:

    标签: java swing layout-manager gridbaglayout


    【解决方案1】:

    GridBagLayout 想要使用首选尺寸的组件,这是您认为可以做的事情和实际可以做的事情发生冲突的奇怪点之一。

    本质上,您想要做的是覆盖GridBagLayout 使用您自己的逻辑做出的布局决策(您占用 25% 的宽度和 75% 的宽度)。问题是,GridBagLayout 不这么认为,它更多地认为,你可以拥有 25% 的空间,在我计算出每个人的首选布局要求后剩余的空间,你可以拥有 75%。这并不总是以您最初认为的方式出现。

    第一步,使用weightxweighty

    // I want the scrollpane to take up 1/4 the width of the window.
    gbc.fill = GridBagConstraints.BOTH;
    gbc.gridwidth = 1;
    gbc.gridx = 0;
    gbc.gridy = 1;
    gbc.weightx = 0.25;
    gbc.weighty = 1;
    add(scrollpane, gbc);
    
    // I want the textarea to take up 3/4 the width of the window.
    gbc.gridx = 1;
    gbc.gridy = 1;
    gbc.weightx = 0.75;
    add(textarea, gbc);
    

    这为GridBagLayout 提供了大小调整提示,在它完成初始布局后它应该如何处理可能有的任何剩余空间。

    但是,等等,这似乎并没有改变任何东西!不,实际上它没有,除非您将窗口调整到足够大,正如我所说,组件被布置(尽可能)到它们的首选大小。所以JListJTextArea 正在与我们争吵。

    JScrollPane 从视图组件中获取首选大小。 JList 实现了Scrollable 接口,该接口提供了一个getPreferredScrollableViewportSize 方法,JScrollPane 使用该方法作为它的首选大小(否则它使用组件的首选大小)

    所以,我们现在可以有点厚颜无耻地修改首选的视口宽度...

    list = new JList<String>(listOptions) {
        @Override
        public Dimension getPreferredScrollableViewportSize() {
            Dimension size = super.getPreferredScrollableViewportSize();
            size.width = 100;
            return size;
        }
    };
    

    (ps,我确实测试了setFixedCellWidthsetPrototypeCellValue,但是这两个都阻止了水平滚动条的出现)。

    好的,这会更好一点:P。有时最小尺寸会与首选尺寸竞争,因此请注意:P

    请记住,weightx/y 仅适用于剩余空间,它不会影响初始布局:P

    【讨论】:

      【解决方案2】:

      定义JScrollPane 的首选大小以保持初始宽度的 1/4。然后为JScrollPane 添加 weightX =1,为JTextArea 添加 =3。

      pack() 之后,您的初始状态将反映首选大小。如果宽度增加,则根据权重分配额外的像素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 2012-12-06
        • 2017-10-18
        • 1970-01-01
        相关资源
        最近更新 更多