【问题标题】:Jsplitpane automatically resizesJsplitpane 自动调整大小
【发布时间】:2018-02-06 07:16:50
【问题描述】:

我有一个 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();
            }
        });
    }
}

【问题讨论】:

    标签: java swing


    【解决方案1】:

    但是,当我在右侧添加一些 JLabel 时,jsplitpane 会忽略我的 50% 分隔线,左侧窗格会增加其大小并挤压右侧。

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

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

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

    在第二种情况下,第一个面板的首选尺寸将是添加到面板的所有标签的宽度,第二个面板为 0。由于第一个面板的首选宽度大于那里的框架尺寸没有多余的空间可以分配给第二个面板。

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

    编辑:

    几个问题:

    1) 调整大小的权重不像您预期​​的那样起作用。当分隔器以低速移动时,会为每个像素生成一个事件。好吧,一个像素不能被两个组件共享,所以像素被分配给正确的组件。

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

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

    解决办法是覆盖面板的getMinimumSize()方法,返回一些更小的维度

    1. 将分隔线位置手动设置为初始显示拆分窗格时拆分窗格大小的 50%。

    这可以通过将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();
                }
            });
        }
    }
    

    【讨论】:

    • But there is heaps of space beneath so can the 20 JLabels not fill up that space first - 使用不同的布局管理器。 FlowLayout 的规则是在假设所有组件都显示在一行上的情况下计算首选大小。 i strictly want the 50% ratio - 你还是不明白setResizeWeight() 方法的用法。此方法仅适用于根据添加到拆分窗格的每个组件的首选大小分配空间之后。
    • 那么我使用哪个布局管理器,这样我就可以保持 50% 的比例并让 jlabels 正确可见?请建议
    • 不要使用 JSplitPane,这不是拆分窗格的设计方式。使用拆分窗格的目的是让每个组件确定自己的首选大小并根据需要分配额外的空间。然后用户可以根据需要调整分频器。如果您希望每个组件占 50%,那么您可以使用 GridLayout。
    • @Skux,JSplitPane 没有提供您想要的确切功能。请参阅编辑以获取我可以提供的最接近的解决方案。
    猜你喜欢
    • 2011-06-17
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 2012-01-05
    • 1970-01-01
    • 2018-04-20
    相关资源
    最近更新 更多