【问题标题】:JScrollPanes inside GridBagLayout gets resized randomlyGridBagLayout 中的 JScrollPanes 随机调整大小
【发布时间】:2012-03-26 20:06:21
【问题描述】:

这对你们来说很难:)

基本上我有一个 GridBagLayout 有 2 列:一个 list 包裹在一个 scrollpane 中。滚动窗格沿 BOTH 方向拉伸。

如果我逐渐减小此面板的高度(通过拖动窗口的边缘),我会看到滚动窗格上发生“随机”调整大小:

  • 当第一个的 Hscroll bar 出现时,第二个的宽度会减小

  • 那么,第二个的宽度又无缘无故地缩小了……

如果我不包装我的组件,请不要出现这种行为。


如果你用 tree 替换右边的列表,它的行为会有所不同: 将窗口的高度缩小到 380 像素以下,树的大小会被调整...

如果我不包装我的组件,如果你不断调整窗口大小,树就会重新调整大小!

你们知道发生了什么吗???

PS:我尝试构建的实际布局比这个示例更复杂。与此同时,我使用 SpringLayout 来做我想做的事,但它需要很多(不是那么漂亮)的东西来设置

protected static ListModel newListModel(int n) {
    DefaultListModel lm = new DefaultListModel();

    for (int i = 0; i < n; ++i)
        lm.addElement("AAA");

    return lm;
}

protected static JComponent createContentPane() {
    JPanel  pane = new JPanel(new GridBagLayout());

    GridBagConstraints  gbc = new GridBagConstraints();

    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.gridy = 0;
    gbc.gridx = 0;

    pane.add(new JScrollPane(new JList(newListModel(12))), gbc);

    ++gbc.gridx;

    pane.add(new JScrollPane(new JList(newListModel(4))), gbc);

    return pane;
}

public static void main(String[] args) {
    JFrame f = new JFrame();

    f.getContentPane().add(createContentPane());
    f.setSize(800, 400);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    f.setVisible(true);
}

【问题讨论】:

    标签: java swing resize jscrollpane gridbaglayout


    【解决方案1】:
    • 这是GridBagLayout的基本原理,你忘了定义anchor,那么你可以将放置的JComponent修复为相关的Point,我认为GridBagLayout会使你的GUI复杂化,这个LayoutManager 更适合在一个容器中放置大量JComponents,(不使用nested layout

    例如

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.border.*;
    
    public class BorderPanels extends JFrame {
    
        private static final long serialVersionUID = 1L;
    
        public BorderPanels() {
            setLayout(new GridBagLayout());// set LayoutManager
            GridBagConstraints gbc = new GridBagConstraints();
            JPanel panel1 = new JPanel();
            Border eBorder = BorderFactory.createEtchedBorder();
    
            panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
            gbc.gridx = gbc.gridy = 0;
            gbc.gridwidth = gbc.gridheight = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            gbc.weightx = gbc.weighty = 20;
            add(panel1, gbc); // add compoenet to the COntentPane
    
            JPanel panel2 = new JPanel();
            panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "60pct"));
            gbc.gridy = 1;
            gbc.weightx = gbc.weighty = 60;
            //gbc.insets = new Insets(2, 2, 2, 2);
            add(panel2, gbc); // add component to the COntentPane
    
            JPanel panel3 = new JPanel();
            panel3.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
            gbc.gridy = 2;
            gbc.weightx = gbc.weighty = 20;
            gbc.insets = new Insets(2, 2, 2, 2);
            add(panel3, gbc);
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
            pack();
            setVisible(true); // important
        }
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() { // important
    
                public void run() {
                    BorderPanels borderPanels = new BorderPanels();
                }
            });
        }
    }
    

    避免把简单的事情复杂化

    【讨论】:

    • 我的示例中设置了锚点。无论我选择中心还是任何角落(比如西北),我仍然遇到这个问题。我的示例并未在我的最终版本中显示所有内容。我为帖子简化了它。其实有点复杂
    • @Jordan 使用正确的 LayoutManager,GridBagLayout 是最复杂的 LayoutManager 并接受所有可能的参数,我认为您想提供 BoxLayout 或 BorderLayout,只需选择其中一个
    【解决方案2】:

    我有一个在 GridBagLayout 中有几个 ScrollPanes 的应用程序,当我调整窗口大小时,它们也会突然调整大小。当 ScrollPane 的实际大小超过其“首选大小”时,似乎会发生跳跃。我找到了一种解决方法:将首选大小设置为 1x1 像素。如果组件具有正权重并同时拉伸两者,它仍然会占据整个单元格,但不会跳跃。如果您需要多个单元格以不同的比例调整大小,您可以将另一个单元格的首选大小设置为 2x1 像素。

    【讨论】:

    • 哇,解决了我的问题。我有一个类似的问题。我有一个 4x4 网格,滚动窗格设置在右下角。我的限制是给右上角的单元格赋予权重,给左上角的单元格赋予垂直权重。所有其他单元格的权重为 0。我想要实现的是,如果我展开包含该容器的对话框,那么只有顶部的单元格会展开,而底部的单元格会在底部对齐。它在模拟面板上运行良好,但是当我将右下角的单元格设置为 jscrollpne 时,发生了突然的调整大小。所以我将首选大小设置为 1,1。突然的跳跃不再发生,一切都很好。
    • 我爱你的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 2014-02-20
    • 2011-10-15
    • 2015-11-17
    • 2015-07-21
    相关资源
    最近更新 更多