Изменить размер панели при нажатии кнопки

У меня есть следующий код:

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));
}

person Tapas Bose    schedule 14.08.2011    source источник
comment
может быть, это может помочь увеличить уменьшить размер окна при нажатии кнопки"> stackoverflow.com/questions/3889498/   -  person Shadow    schedule 15.08.2011
comment
+1 за sscce.   -  person trashgod    schedule 15.08.2011
comment
@Tapas Bose, я дал тебе ответ за 4 часа до ответа, который ты принял. Я нашел время, чтобы объяснить проблему и объяснить решение с помощью нескольких демонстрационных строк кода. Что не так с моим ответом? Или вы ожидаете, что люди будут каждый раз писать код за вас?   -  person camickr    schedule 15.08.2011
comment
@camickr Я считаю, что это потому, что трэшбод опубликовал полный пример   -  person Eng.Fouad    schedule 15.08.2011
comment
@Eng, это моя точка зрения. Не должно быть необходимости публиковать полный пример. Объяснение было дано с решением. Люди учатся, пробуя и решая проблемы самостоятельно, и НЕ должны ожидать, что мы напишем за них код. Публикация рабочего кода не объясняет, в чем заключается исходная проблема, и не освещает фактическое решение. Форум предназначен для ответа на вопрос или это соревнование, кто может опубликовать лучший рабочий код?   -  person camickr    schedule 15.08.2011
comment
@camickr, по правилу stackoverflow мы, пользователи, можем принять не более одного ответа, и если бы такого правила не было, ваш ответ также был бы принят, это одинаково полезно. Поэтому я дал вам голосование. У меня есть несколько панелей, которые можно поменять местами не при нажатии кнопки, а при изменении выбора JList, поэтому для этого будет дорого помнить ранее замененную панель, а структура не будет поддерживать повторную реализацию своей базы, и я не публиковал фактическую код, если бы я это сделал, мне пришлось бы опубликовать как минимум 10 java-кодов, поэтому я сделал небольшой прототип той же потребности. Выкладываю основной фрагмент в редактирование.   -  person Tapas Bose    schedule 15.08.2011
comment
Никто не может научиться программированию, если он/она не напишет свой собственный код. :) и я не нахожусь в ситуации/стадии, когда мне нужно, чтобы другие люди писали весь код.   -  person Tapas Bose    schedule 15.08.2011
comment
@Tapas, разница в опубликованном коде заключалась в том, что он использовал removeAll(), а я использовал remvoe(). Поэтому, несмотря на то, что я трачу все время на объяснение двух проблем, которые у вас были с вашим кодом, это было потрачено впустую. Вы не могли бы даже немного подумать, чтобы использовать метод removeAll() самостоятельно? Это проблема, которая у меня есть с кодом платы за ложку, люди просто смотрят на код и не смотрят на объяснение, а затем возятся со своими. И вы все еще не посмотрели на свой предыдущий вопрос, где я дал вам гораздо более простое решение. Удачи с будущими вопросами.   -  person camickr    schedule 16.08.2011
comment
@camickr Так что, несмотря на то, что я трачу все время на объяснение двух проблем, которые у вас возникли с вашим кодом, это было потрачено впустую. меня это сильно задело, так как это не факт. :(   -  person Tapas Bose    schedule 16.08.2011


Ответы (3)


Вы никогда не должны использовать setSize() при использовании менеджера компоновки. Задача менеджера по компоновке — определить размер. Вы можете предоставить подсказки менеджеру компоновки, установив предпочтительные, минимальные или максимальные размеры. Однако делать это не рекомендуется, поскольку компоненты и панели должны отображаться в предпочтительном для них размере, который будет определяться используемым менеджером компоновки. Если вы переопределили размер, код должен быть:

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

Однако это по-прежнему не будет работать так, как вы хотите, потому что задача CardLayout состоит в том, чтобы определить наибольший размер всех панелей, добавляемых к панели с помощью CardLayout. Поэтому, когда вы переключаетесь с панели на панель, вы не получаете размер каждой отдельной панели. Это удобнее для пользователя, потому что пользователь не хочет видеть, как размер кадра меняется каждый раз, когда он нажимает кнопку.

Если вы хотите, чтобы размер кадра менялся каждый раз, когда вы нажимаете кнопку, тогда базовый код будет таким:

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

Затем менеджер компоновки главной панели будет следить за предпочтительным размером новой панели, добавленной в новый слой.

person camickr    schedule 15.08.2011

После изменения размера JFrame используйте: yourframe.validate();

person Eng.Fouad    schedule 14.08.2011
comment
Изменение размера фрейма приведет к его проверке. - person camickr; 15.08.2011

В качестве конкретного примера ответа camickr программа ниже показывает как полагаться на предпочтительный размер компонентов при изменении размера кадра через pack(). Искусственный контент представляет собой серию ярлыков, но подойдет любой JComponent. Поскольку контент воссоздается динамически, он может изменяться в соответствии с другими условиями в программе.

введите здесь описание изображения

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;
        }
    }
}
person trashgod    schedule 15.08.2011