使用JFrame.pack()时如何使用均匀放置的分隔线布局两个JSplitPanes

时间:2011-03-29 12:09:32

标签: java swing jsplitpane

此代码应生成一个包含2个垂直拆分窗格的框架 这应该初始化,以便分配器均匀放置。

但是,这仅在帧大小固定时才有效。 看来这是因为分裂的首选高度的总和 窗格对我的屏幕来说太大了(1280x1024)。报告了JFrame高度 通过getSize()最终大于我的屏幕高度,因此 分隔线的位置很差。

使用frame.pack()时应该怎么做?

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

public class TestSplitPanels extends JPanel {


public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    TestSplitPanels tps = new TestSplitPanels();

    frame.setContentPane(tps);

    frame.pack();

    // uncomment this and the dividers are nicely positioned
    // frame.setSize(600,600);

    frame.setVisible(true);

}

public TestSplitPanels() {
    JTable jt1 = new JTable();

    JTable jt2 = new JTable();

    JTable jt3 = new JTable();

    // wrap every JTable in a scroll pane

    JScrollPane jsr1 = new JScrollPane();
    jsr1.setViewportView(jt1);

    JScrollPane jsr2 = new JScrollPane();
    jsr2.setViewportView(jt2);

    JScrollPane jsr3 = new JScrollPane();
    jsr3.setViewportView(jt3);


    final JSplitPane jsl1 = new JSplitPane();
    final JSplitPane jsl2 = new JSplitPane();

    /* 
     * Make a vertical split pane who's top component is
     * is the first scroll pane and bottom component is 
     * another scroll pane. Try to set the divider location
     * at a third of the height of the parent component,
     * when that value is known
     */
    jsl1.setOrientation(JSplitPane.VERTICAL_SPLIT);
    jsl1.setTopComponent(jsr1);
    jsl1.setBottomComponent(jsl2);
    jsl1.addAncestorListener(new BaseAncestorListener() {

        @Override
        public void ancestorAdded(AncestorEvent event) {
            jsl1.setDividerLocation(getSize().height/3);
        }
    });

    /*
     * Set components and set the divider position as before
     * for the second split pane
     */
    jsl2.setOrientation(JSplitPane.VERTICAL_SPLIT);
    jsl2.setTopComponent(jsr2);
    jsl2.setBottomComponent(jsr3);
    jsl2.addAncestorListener(new BaseAncestorListener() {

        @Override
        public void ancestorAdded(AncestorEvent event) {
            jsl2.setDividerLocation(getSize().height/3);
        }
    });

    setLayout(new BorderLayout());
    add(jsl1, BorderLayout.CENTER);

}

public static class BaseAncestorListener 
    implements AncestorListener {

    @Override
    public void ancestorAdded(AncestorEvent event) {
    }

    @Override
    public void ancestorRemoved(AncestorEvent event) {
    }

    @Override
    public void ancestorMoved(AncestorEvent event) {
    }

}

}

3 个答案:

答案 0 :(得分:5)

我使用setResizeWeigth告诉JSplitPanes如何分配大小。作为奖励,即使您调整窗口大小,分割窗格也会保持均匀分布。一旦调整其中一个窗格,它们将失去均匀分布。

请注意,您不一定需要AncestorListener。我用它打印出JScrollPanes的大小。

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

public class TestSplitPanels extends JPanel {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        final TestSplitPanels tps = new TestSplitPanels();
        frame.setContentPane(tps);
        frame.pack();
        frame.setVisible(true);
    }

    public TestSplitPanels() {

        JTable jt1 = new JTable();
        JTable jt2 = new JTable();
        JTable jt3 = new JTable();

        final JScrollPane jsr1 = new JScrollPane();
        final JScrollPane jsr2 = new JScrollPane();
        final JScrollPane jsr3 = new JScrollPane();

        jsr1.setViewportView(jt1);
        jsr2.setViewportView(jt2);
        jsr3.setViewportView(jt3);

        JSplitPane jsl1 = new JSplitPane();
        JSplitPane jsl2 = new JSplitPane();

        jsl1.setOrientation(JSplitPane.VERTICAL_SPLIT);
        jsl1.setTopComponent(jsr1);
        jsl1.setBottomComponent(jsl2);
        jsl1.setResizeWeight(0.33); // <-- here

        jsl2.setOrientation(JSplitPane.VERTICAL_SPLIT);
        jsl2.setTopComponent(jsr2);
        jsl2.setBottomComponent(jsr3);
        jsl2.setResizeWeight(0.5); // <-- here

        this.addAncestorListener(new BaseAncestorListener() {
            @Override
            public void ancestorMoved(AncestorEvent event) {
                System.out.println("jsr1 size: " + jsr1.getSize());
                System.out.println("jsr2 size: " + jsr2.getSize());
                System.out.println("jsr3 size: " + jsr3.getSize());
                System.out.println("----");
            }
        });

        setLayout(new BorderLayout());
        add(jsl1, BorderLayout.CENTER);
    }

    public static class BaseAncestorListener implements AncestorListener {

        @Override
        public void ancestorAdded(AncestorEvent event) {
        }

        @Override
        public void ancestorRemoved(AncestorEvent event) {
        }

        @Override
        public void ancestorMoved(AncestorEvent event) {
        }

    }
}

答案 1 :(得分:0)

jsl2.addAncestorListener(new BaseAncestorListener() {
            @Override
            public void ancestorAdded(AncestorEvent event) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        jsl2.setDividerLocation(getSize().height / 3);                    }
                });
            }
        });

答案 2 :(得分:-1)

您可以在JSplitPaneClass中使用 setDividerLocation 方法