使用GridBagLayout使JPanel子项可滚动

时间:2016-06-14 22:19:38

标签: java swing

我有一些问题要让JPanel组件可以滚动...我已经花了3个多小时来完成这项工作,但没有成功,这就是我向你寻求帮助的原因!

Window类:

public class Window extends JFrame {
    public Window(String title) {
        super();

        Dimension dimension = IHM.getDimension();

        this.setTitle(title);
        this.setSize(dimension.width, dimension.height);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setMaximumSize(dimension);
        this.setMinimumSize(dimension);
        this.setContentPane(new Container());
        this.setBackground(IHM.getBlue());
        this.pack();
        this.setVisible(true);
    }
}

Container类:

public class Container extends JPanel {
    public static Boolean debug = true;
    private Dimension lastDimension = new Dimension(0, 0);

    public Container() {
        // Layout
        GridBagLayout layout = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();

        // Panel configurations
        this.setLayout(layout);

        /**
         * HEADER
         */
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.gridheight = 1;

        this.add(new HeaderPanel(), gbc);

        /**
         * LEFT
         */
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 1;
        gbc.fill = GridBagConstraints.BOTH;

        JPanel leftPanel = new LeftPanel();

        JScrollPane leftPanelScrollable = new JScrollPane(leftPanel);

        leftPanelScrollable.setViewportView(leftPanel);
        leftPanelScrollable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        leftPanelScrollable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        leftPanelScrollable.setBounds(10, 10, leftPanel.getWidth() - 50, leftPanel.getHeight() - 50);

        this.add(leftPanelScrollable, gbc);

        // ...
    }
}

和leftPanel类:

public class LeftPanel extends JPanel {
    private static Dimension dimension = new Dimension(IHM.getWidth() / 2, IHM.getHeight() - 220);

    public LeftPanel() {
        this.setPreferredSize(dimension);

        // Add the labels
        this.addLabel();

        // Add the radios
        this.addRadios();

        this.setAutoscrolls(true);
    }
}

请看屏幕截图,我没有任何滚动条:(

图片中的结果:

http://i.stack.imgur.com/q40Ct.png

你对这个问题有什么看法吗?提前谢谢!

3 个答案:

答案 0 :(得分:2)

leftPanelScrollable.setBounds(10, 10, leftPanel.getWidth(), leftPanel.getHeight());

这应该造成伤害。上述方法强制JScrollPane与底层面板的大小相同。让布局管理员完成工作。

<子> P.S。我还没有测试过它。

您还应尝试制作JPanel工具Scrollable并设置

public boolean getScrollableTracksViewportHeight()

public boolean getScrollableTracksViewportWidth()

返回false。

答案 1 :(得分:2)

this.setPreferredSize(dimension);

不要手动设置首选大小。面板的布局管理器将确定首选大小。 JPanel的默认布局管理器是FlowLayout,它会给出一个首选大小,好像所有组件都在同一行上,这显然不是你想要的,所以使用不同的布局管理器。

this.setAutoscrolls(true);

滚动时不需要这样做。

    JScrollPane leftPanelScrollable = new JScrollPane(leftPanel);
    leftPanelScrollable.setViewportView(leftPanel);

无需设置视口视图。创建滚动窗格时,您指定的组件将添加到视口中。

   leftPanelScrollable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    leftPanelScrollable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

无需设置滚动条策略。滚动条将在需要时自动显示(一旦您的代码正常工作)并让布局管理器完成其工作。

    GridBagLayout layout = new GridBagLayout();
    GridBagConstraints gbc = new GridBagConstraints();
    this.setLayout(layout);

我建议您使用更易于使用的BorderLayout。只需将“headerPanel”添加到BorderLayout.PAGE_START即可。然后将“leftPane”添加到BorderLayout.CENTER。然后在调整框架大小时,所有额外空间都将转到CENTER,滚动条将根据需要显示。

  

所有重要的代码都是礼物

在问题解决之前,你不知道什么是或不是进口。如果上述建议有所帮助,则发布一个显示问题的正确SSCCE

答案 2 :(得分:-1)

在为每个JPanel删除定义的大小和preferredSize之后,将GridBagConstraints weightyweightxfill设置为GridBagConstraints.BOTH,最后使用setBoxLayout(new BoxLayout(this, BoxLayout.Y_AXIS))对于我的左侧面板,一切正常!无论如何,谢谢大家。

Final result