14

对于我在 Java 中创建的 GUI 应用程序,我有以下内容:

  • 一个 JFrame,设置为具有 (300,200) 的最小大小
  • 一个 JSplitPane,其中包含:
    • 在左边,一个最小尺寸为 (100,0) 的 JScrollPane(包含一个 JTree)(我只想将宽度限制为 200)
    • 在右侧,最小尺寸为 (200,0) 的 JPanel

在以下条件下,尺寸不会给我任何问题:

  • 一直调整 JSplitPane 的大小(到 JScrollPane 的最小大小),然后调整窗口大小
  • 只是在一定程度上调整窗口大小

当我将 JSplitPane 移动得太靠近右侧时会出现问题,因此调整窗口大小时 JSplitPane 右侧的 JPanel 无法遵守我设置的最小宽度。

我尝试在 JScrollPane 上设置最大宽度,这似乎根本没有帮助。

有没有我必须做的涉及最大尺寸的事情?或者也许有一种方法可以将 Listener 附加到其中一个面板以强制执行我想要的行为?最终,我只希望 JSplitPane 中的右侧面板的宽度永远不会小于 200 像素。

这是我遇到的行为示例:

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;

public class ResizeTest
{
    private JFrame frame;
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                try
                {
                    ResizeTest window = new ResizeTest();
                    window.frame.setVisible(true);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
            }
        });
    }
    public ResizeTest()
    {
        initialize();
    }
    private void initialize()
    {
        frame = new JFrame();
        frame.setMinimumSize(new Dimension(300, 200));
        frame.setBounds(100,100,450,300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(0, 1, 0, 0));

        JSplitPane splitPane = new JSplitPane();
        frame.getContentPane().add(splitPane);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setMinimumSize(new Dimension(100, 0));
        splitPane.setLeftComponent(scrollPane);

        JTree tree = new JTree();
        tree.setMinimumSize(new Dimension(100, 0));
        scrollPane.setViewportView(tree);

        JPanel panel = new JPanel();
        panel.setMinimumSize(new Dimension(200, 0));
        splitPane.setRightComponent(panel);
    }
}

更新:

恐怕我不完全理解在提议的解决方案中试图提出的观点,除了 setPreferred() 和 setMinimum/Maximum() 最好避免。

我的问题是,在使用这些方法之外限制 JSplitPane 分隔符的选项是什么MadProgrammer提到了监听 componentResized 事件,但我需要进一步说明原因。我是否调用 setDividerLocation() 来响应此事件?

如果附加的问题完全是一个单独的 StackOverflow 问题,我提前道歉,如有必要,我可以在此处发布另一个问题并链接。

更新 2:

只是不规范用户如何选择窗口大小并在 JScrollPane 中设置右侧面板是一个可行的选项吗?在我看来,这有点像一种标准做法。

4

2 回答 2

9

首先,该方法setMinimumSize是对LayoutManagerAPI 的建议。一个可能被忽略的建议。

为了能够接近支持这一点,您将需要使用ComponentListener之类的东西并监视componentResized事件。

我能想到的最佳解决方案是使用LayoutManager实际使用最小和最大尺寸约束的 a,例如GridBagLayout.

在“内容”窗格上使用它并将您JSplitPane放在上面(相应地设置它的最小和最大尺寸),然后将“内容”窗格添加到框架中。

更新

抱歉,我可能遗漏了一些非常明显的东西,但我把这个小测试放在一起,我希望它有一些帮助:P

public class TestFrameSize extends JFrame {

    public TestFrameSize() throws HeadlessException {

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setLocationRelativeTo(null);

        setMinimumSize(new Dimension(250, 250));

        JLabel left = new JLabel("Left");
        JLabel right = new JLabel("Right");

        Dimension pSize = new Dimension(100, 100);
        Dimension mSize = new Dimension(25, 100);

        left.setPreferredSize(pSize);
        left.setMinimumSize(mSize);
        right.setPreferredSize(pSize);
        right.setMinimumSize(mSize);

        JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, right);

        JPanel content = new JPanel(new GridBagLayout());
        content.add(pane);

        setLayout(new BorderLayout());
        add(content);

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        new TestFrameSize().setVisible(true);

    }
}
于 2012-09-18T23:08:33.940 回答
3

在此示例中,a 内容的首选大小JSplitPane最初设置为 中组件首选大小的小倍数getPreferredSize()。请注意,JSplitPane将不小于面板的最小尺寸,由封闭的Jlabel.

图片

于 2012-09-18T23:52:27.200 回答