单击按钮更改面板大小

时间:2011-08-14 19:47:46

标签: java swing validation repaint cardlayout

我有以下代码:

package in.res.num.tapb.ui;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

class MainClass extends JPanel {
    public MainClass() {
        Registration registration = new Registration();
        ButtonPanel buttonPanel = new ButtonPanel();
        buttonPanel.setRegistration(registration);

        buttonPanel.setBorder(BorderFactory.createTitledBorder("Button Panel"));
        registration.setBorder(BorderFactory.createTitledBorder("Registration Panel"));

        setLayout(new BorderLayout());
        add(registration, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("Registration");
        frame.getContentPane().add(new MainClass());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }

    @SuppressWarnings("serial")
    private class ButtonPanel extends JPanel {
        private Registration registration;

        public ButtonPanel() {
            setLayout(new GridLayout(1, 0, 10, 0));     
            for (final String keyText : Registration.KEY_TEXTS) {
                JButton btn = new JButton(keyText);
                btn.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        if (registration != null) {
                            registration.swapView(keyText);
                        }
                    }
                });
                add(btn);
            }
        }

        public void setRegistration(Registration registration) {
            this.registration = registration;
        }
    }

    private static class Registration extends JPanel {
        private static final Dimension PREF_SIZE = new Dimension(450, 300);
        public static final String USER_AGREEMENT = "User Agreement";
        public static final String USER_INFO = "User Information";
        public static final String ENROLLMENT = "Enrollment";
        public static final String[] KEY_TEXTS = { USER_AGREEMENT, USER_INFO, ENROLLMENT };
        private CardLayout cardlayout = new CardLayout();
        private JPanel cards = new JPanel(cardlayout);

        public Registration() {
            cards.add(createUserAgreePanel(), USER_AGREEMENT);
            cards.add(createUserInfoPanel(), USER_INFO);
            cards.add(createEnrollmentPanel(), ENROLLMENT);
            setLayout(new BorderLayout());
            add(cards, BorderLayout.CENTER);
        }



        private JPanel createEnrollmentPanel() {
            JPanel enrol = new JPanel();
            enrol.setSize(new Dimension(400, 200));
            enrol.add(new JLabel("Enrollment"));
            return enrol;
        }

        private JPanel createUserAgreePanel() {
            JPanel userAgree = new JPanel();
            userAgree.setSize(new Dimension(200, 300));
            userAgree.add(new JLabel("User Agreement"));
            return userAgree;
        }

        private JPanel createUserInfoPanel() {
            JPanel userInfo = new JPanel();
            userInfo.setSize(new Dimension(300, 400));
            userInfo.add(new JLabel("User Information"));
            return userInfo;
        }

        public void swapView(String key) {
            cardlayout.show(cards, key);
        }

    }

}

如您所见,我想在按钮点击时更改大小。可能吗?上面的代码不起作用,我的意思是大小不变。如何在飞行中改变大小?

谢谢和问候。 编辑:

在选择一行JList时交换面板。

    getChoicesList().addListSelectionListener(new ListSelectionListener() {

        @Override
        public void valueChanged(ListSelectionEvent listSelectionEvent) {
            getViewPanel().changeView(getChoicesList().getSelectedIndex());
            getChoicePanel().changeView(Constants.PanelInfo.valueOf(getEngine().getChoiceList().get(getChoicesList().getSelectedIndex()).getEnumName()).getDimensionForScrollPaneOfChoicePanel());
            ((MainFrame) getTopLevelAncestor()).pack();
        }
    });

ViewPanel#changeView(),交换面板:

public void changeView(int index) {
    removeAll();
    getPanels().get(index).setPreferredSize(Constants.PanelInfo.valueOf(getEngine().getChoiceList().get(index).getEnumName()).getDimensionForViewPanel());
    add(getPanels().get(index));
}

3 个答案:

答案 0 :(得分:4)

调整JFrame大小后,使用:     yourframe.validate();

答案 1 :(得分:3)

使用布局管理器时,切勿使用setSize()。布局管理器的工作是确定大小。您可以通过设置已更改或最小或最大大小来为布局管理器提供提示。但是,建议您不要这样做,因为组件和面板应以其首选大小显示,这将由您使用的布局管理器确定。如果你确实覆盖了大小,那么代码应该是:

// enrol.setSize(new Dimension(400, 200));
enrol.setPreferredSize(new Dimension(400, 200));

但是,由于CardLayout的工作是使用CardLayout确定添加到面板的所有面板的最大尺寸,因此仍然无法按照您的方式工作。因此,当您从面板切换到面板时,您无法获得每个面板的大小。这对用户来说是更好的体验,因为用户不希望每次按下按钮时都看到帧大小不断变化。

如果您确实希望每次单击按钮时都更改框架大小,那么基本代码将是:

mainPanel.remove(oldPanel);
mainPanel.add(newPanel);
frame.pack();

然后主面板的布局管理器将观察添加了newlay的面板的首选大小。

答案 2 :(得分:3)

作为camickr的answer的一个具体示例,下面的程序显示了如何通过pack()调整框架的大小来优先考虑组件的大小。 faux 内容是一系列标签,但任何JComponent都可以。当动态重新创建内容时,它可以根据程序中的其他条件进行更改。

enter image description here

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/** @see https://stackoverflow.com/questions/7059278 */
class MainPanel extends JPanel {

    private static final String title = "Registration Panel";
    private JFrame frame = new JFrame(title);
    private JPanel registration = new JPanel();

    public MainPanel() {
        this.setLayout(new BorderLayout());
        registration.setBorder(BorderFactory.createTitledBorder(title));
        registration.add(PanelType.USER_AGREEMENT.panel);
        ButtonPanel buttonPanel = new ButtonPanel();
        buttonPanel.setBorder(BorderFactory.createTitledBorder("Button Panel"));
        add(registration, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);
    }

    private void display() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new MainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MainPanel().display();
            }
        });
    }

    private class ButtonPanel extends JPanel {

        public ButtonPanel() {
            for (final PanelType panel : PanelType.values()) {
                final JButton button = panel.button;
                this.add(button);
                button.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        registration.removeAll();
                        registration.add(panel.create());
                        frame.pack();
                        frame.setLocationRelativeTo(null);
                    }
                });
            }
        }
    }

    private enum PanelType {

        USER_AGREEMENT("User Agreement", 2),
        USER_INFO("User Information", 4),
        ENROLLMENT("Enrollment Form", 6);
        private String name;
        private int count;
        private JButton button;
        private JPanel panel;

        private PanelType(String name, int count) {
            this.name = name;
            this.count= count;
            this.button = new JButton(name);
            this.panel = create();
        }

        private JPanel create() {
            this.panel = new JPanel(new GridLayout(0, 1));
            this.panel.add(new JLabel(name));
            this.panel.add(new JLabel(" "));
            for (int i = 0; i < count; i++) {
                this.panel.add(new JLabel("Label " + String.valueOf(i + 1)));
                            }
            return panel;
        }
    }
}