Jsplitpane会自动调整大小

时间:2017-08-28 23:55:14

标签: java swing

我有一个JSPlitPane,它们之间有50%的分隔符。 这是正常的。

然而,当我向右侧添加一些JLabel时,jsplitpane忽略了我的50%分隔符,左侧窗格增加了它的大小,只是压扁了右侧。

为什么会发生这种情况以及如何解决?

我的代码是:

import javax.swing.*;
import java.awt.*;

public class Example {

    private static void setup() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(500, 500));
        frame.setFocusable(true);

        JSplitPane pane= new JSplitPane();
        pane.setResizeWeight(0.5);
        pane.setRightComponent(new JPanel());

        JPanel myPanel = new JPanel();
        myPanel.setLayout(new FlowLayout());

        for(int i=0; i<20; i++) myPanel.add(new JLabel("hello"));

        pane.setLeftComponent(myPanel);

        frame.add(pane);

        frame.pack();
        frame.setVisible(true);
    }

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

1 个答案:

答案 0 :(得分:2)

  

然而,当我向右侧添加一些JLabel时,jsplitpane忽略了我的50%分隔符,左侧窗格增加了它的大小,只是压扁了右侧。

拆分窗格最初将计算每个组件的首选大小。

调整大小权重用于在调整拆分窗格大小时分配空间。在这种情况下,当框架可见时会发生这种情况。因此,如果在使框架可见时,添加到拆分窗格的组件的首选大小小于拆分窗格的大小,则每个组件将获得额外空间的50%。

在第一种情况下,没有组件,因此每个面板的首选大小是相同的,因此当分割窗格调整大小时,它们每个都会获得相同的空间。

在第二种情况下,第一个面板的首选尺寸是添加到面板的所有标签的宽度,第二个面板是0.因为第一个面板的首选宽度大于框架的尺寸没有额外的空间来分配给第二个面板。

尝试添加1或2个标签而不是20来看看会发生什么。

编辑:

一些问题:

1)调整重量不会像您预期的那样起作用。当分频器以慢速移动时,将为每个像素生成事件。那么两个组件都不能共享像素,因此像素被赋予正确的组件。

我建议在你的情况下解决方案是使用“1.0”的调整大小权重,以便标签组件获得所有空间。

2)JSplitPane尊重组件的最小尺寸,这意味着您无法将条拖动到组件的最小尺寸之外。对于面板,最小尺寸与首选尺寸相同,因此您无法将分隔线拖得更小。

解决方案是覆盖面板的getMinimumSize()方法以返回一些较小的维度

  1. 在最初显示拆分窗格时,手动将分隔符位置设置为拆分窗格大小的50%。
  2. 这可以通过将setDividerLocation(...)方法包装在SwingUtilities.invokeLater()中来完成。

    以上3条建议已添加到您的MCVE中:

    import javax.swing.*;
    import java.awt.*;
    
    public class Example {
    
        private static void setup() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setPreferredSize(new Dimension(500, 500));
            frame.setFocusable(true);
    
            JSplitPane pane= new JSplitPane();
            pane.setResizeWeight(1.0);
            pane.setRightComponent(new JPanel());
    
            JPanel myPanel = new JPanel()
            {
                @Override
                public Dimension getMinimumSize()
                {
                    return new Dimension(50, 50);
                }
            };
            myPanel.setLayout(new FlowLayout());
    
            for(int i=0; i<20; i++) myPanel.add(new JLabel("hello"));
    
            pane.setLeftComponent(myPanel);
    
            frame.add(pane);
    
            frame.pack();
            frame.setVisible(true);
    
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    pane.setDividerLocation(0.5f);
                }
            });
        }
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    setup();
                }
            });
        }
    }