JFrame调整大小时移动JSplitPane分隔条。

3
我使用两个JSplitPanes来展示一些信息。一个是水平分隔符,另一个是垂直分隔符。以下问题适用于两个JSplitPanes。
当我调整应用程序的主JFrame大小时,JSplitPanes也会调整大小,因为它们必须占据屏幕的一定比例(所有JPanels都会根据MigLayout的宽度和高度参数调整到JFrame大小)。
分隔符位置很重要,并且需要与JSplitPane的大小保持不变。我使用setResizeWeight()和setDividerLocation()来实现这一点。
主要问题是,在JFrame调整大小时,分隔符不会保持在0.0 / 0%处,而是移动到大约5-10%:
我认为这是由于resizeWeight引起的,但我试着调整了一下,行为没有任何改变。
有谁能帮我解决这个问题吗?我实现了一个ComponentAdapter,但除了将分隔符位置保存在变量或Preferences XML键中外,我无法在componentResized()上恢复分隔符位置。
示例代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;

import net.miginfocom.swing.MigLayout;


public class JSplitPaneTest {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setMinimumSize(new Dimension(500, 500));

        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new MigLayout());

        JPanel panel1 = new JPanel();
        panel1.setBackground(Color.RED);

        JPanel panel2 = new JPanel();
        panel1.setBackground(Color.GREEN);

        final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
                panel1, panel2);
        splitPane.setResizeWeight(0.5);
        splitPane.setOpaque(false);
        splitPane.setOneTouchExpandable(true); // does not work on Linux :(
        splitPane.setBorder(null);

        mainPanel.add(splitPane, "w 100%, h 90%, wrap");

        JButton button = new JButton("Set to 0");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                splitPane.setDividerLocation(0.0);
            }
        });

        mainPanel.add(button, "span");

        frame.add(mainPanel);
        frame.setVisible(true);
    }
}

为了更快地获得帮助,请发布一个SSCCE/MCVE,即短小、可运行、可编译的示例。 - mKorbel
我已经添加了示例代码。setResizeWeight()确实会改变行为。但是分隔符永远不会真正停留在0处。 - ChrisK
1个回答

1
我和@ChrisK一起在同一个项目中工作,今天我看了一下这个问题。我相信我已经解决了这个问题,尽管我还没有确认窗口调整大小所触发的具体症状(因为我们转移到了一个静态大小的jSplitPane,调整窗口大小不再改变分隔符位置)。然而,我们还遇到了另一个问题,我认为这是由于同一潜在问题引起的:在将分隔符从位置0移动后,就不能再手动将分隔符拖回位置0。这实际上是由于jPanel的最小尺寸从未被明确设置。结果发现,leftComponent.getMinimumSize()返回(随机/任意?)32,这恰好是分隔符无法拖过的最左像素位置。

因此,我的做法是调用:

panel1.setMinimumSize(new Dimension(0,0));

允许将分隔线拖动到最左侧/顶部:

panel2.setMinimumSize(new Dimension(0,0));

允许将分隔条拖动到最右侧/底部。

我认为这些值干扰了组件调整大小时的分隔条位置。我无法弄清楚为什么面板大小的看似任意最小值(32x47)被设置。这些值在构建面板后立即由getMinimumSize返回。如果有人知道如何计算它们,可能会提供更完整的情况说明。如果有帮助的话,分割窗格的宽度/高度在分隔条拖动的尺寸上静态设置为180。


一年多以前,当我对此进行了一些研究时,我看到了这篇文章。它可能是一个有趣的阅读。 - ChrisK
你应该向@kleopatra发送消息,因为目前我们所知道的唯一解决方案是我的临时解决方法。我承认这可能不是明智之举,尽管我对Swing不像你那么熟悉,但我认为你认为分割窗格分隔符的这种行为是一个错误,如果是这样的话,在它被修复之前,似乎你能做的就只有绕过它了。 - hepcat72
你认为我们应该重写getminimumsize而不是像第二个答案中调用set minimum size吗? - hepcat72
是的,我认为覆盖它更可取。我认为这是一个错误,因为它也发生在我发布的短独立示例中。或者我可能对MigLayout有所遗漏。 - ChrisK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接