如何设置JFrame大小以适合显示JPanel的CardLayout?

Jér*_*nge 6 java swing jpanel jframe cardlayout

我有一个JFrame包含了一组JPanelsCardLayout.每个JPanel都有不同的大小,我希望JFrame适应当前显示的大小JPanel(JPanel不适应大小JFrame).

我怎样才能做到这一点?

kle*_*tra 13

一般是:如果您有布局问题,请始终使用适当的LayoutManager解决它.永远不要调整组件的大小提示来达到目标​​.

在这种情况下,调整CardLayout特别容易.默认情况下,它会将prefSize计算为所有卡的prefSizes的最大值.只需子类化并实现以返回当前可见卡的prefSize(加上insets):

public static class MyCardLayout extends CardLayout {

    @Override
    public Dimension preferredLayoutSize(Container parent) {

        Component current = findCurrentComponent(parent);
        if (current != null) {
            Insets insets = parent.getInsets();
            Dimension pref = current.getPreferredSize();
            pref.width += insets.left + insets.right;
            pref.height += insets.top + insets.bottom;
            return pref;
        }
        return super.preferredLayoutSize(parent);
    }

    public Component findCurrentComponent(Container parent) {
        for (Component comp : parent.getComponents()) {
            if (comp.isVisible()) {
                return comp;
            }
        }
        return null;
    }

}
Run Code Online (Sandbox Code Playgroud)

使用它(借用@ mKorbel的例子),主要方法干净利落:

private static void createAndShowUI() {
    final CardLayout cardLayout = new MyCardLayout();
    final JPanel cardHolder = new JPanel(cardLayout);
    final JFrame frame = new JFrame("MultiSizedPanels");
    JLabel[] labels = {
        new JLabel("Small Label", SwingConstants.CENTER),
        new JLabel("Medium Label", SwingConstants.CENTER),
        new JLabel("Large Label", SwingConstants.CENTER)};

    for (int i = 0; i < labels.length; i++) {
        int padding = 50 * (i + 1);
        Border lineBorder = BorderFactory.createCompoundBorder(
            BorderFactory.createLineBorder(Color.blue),
            BorderFactory.createEmptyBorder(padding, padding, padding, padding));
        labels[i].setBorder(lineBorder);
        JPanel containerPanel = new JPanel();
        containerPanel.add(labels[i]);
        cardHolder.add(containerPanel, String.valueOf(i));
    }
    JButton nextButton = new JButton("Next");
    nextButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            cardLayout.next(cardHolder);
            frame.pack();
        }
    });
    JPanel btnHolder = new JPanel();
    btnHolder.add(nextButton);

    frame.add(cardHolder, BorderLayout.CENTER);
    frame.add(btnHolder, BorderLayout.SOUTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setLocation(150, 150);
    frame.setVisible(true);
}
Run Code Online (Sandbox Code Playgroud)