Переключение между панелями JPanel в разных классах

Я наткнулся на эти сложности и потратил более 4 часов на отладку и гугление, но безрезультатно.

В основном у меня есть 1 JFrame, 2 JPanels. У меня был JFrame setContentPane равным 1 из JPanel, и когда я запускаю приложение, JFrame появится с JPanel внутри.

Теперь в этом JPanel есть 1 JButton внутри, когда я нажимаю на него, я хочу, чтобы он переключился на другой JPanel. Как видно из кода, когда я нажимаю JButton (Добавить продукт), я хочу, чтобы OnlineShopAdPane переключился на AddProduct. Я пытался использовать CardLayout, но он имеет только форматирование NSEW.

package OnlineShop.ui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.CardLayout;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class OnlineShopMainFrame extends JFrame {

    /**
     * Launch the application.
     */
    AddProduct Add;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
                    MainFrame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public OnlineShopMainFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);

        OnlineShopAdPane AdPanel = new OnlineShopAdPane();
        setContentPane(AdPanel);

    }


}


package OnlineShop.ui;

import javax.swing.JPanel;
import java.awt.CardLayout;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.BorderLayout;

public class OnlineShopAdPane extends JPanel {

    /**
     * Create the panel.
     */

    public OnlineShopAdPane() {

        JLabel lblWhatDoYou = new JLabel("What do you want to do?");
        lblWhatDoYou.setBounds(28, 26, 160, 26);
        add(lblWhatDoYou);

        JButton btnAddProduct = new JButton("Add Product");
        btnAddProduct.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
            MainFrame.removeAll();
            MainFrame.add(new AddProduct());
            MainFrame.revalidate();
            MainFrame.repaint();
            }
        });

        btnAddProduct.setBounds(46, 75, 115, 23);
        add(btnAddProduct);

    }

}


package OnlineShop.ui;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class AddProduct extends JPanel {
    private JTextField textField;

    /**
     * Create the panel.
     */
    public AddProduct() {

        JLabel lblProductName = new JLabel("Product Name:");
        lblProductName.setBounds(35, 26, 77, 24);
        add(lblProductName);

        JLabel lblProductDescription = new JLabel("Product Description:");
        lblProductDescription.setBounds(10, 50, 106, 24);
        add(lblProductDescription);

        textField = new JTextField();
        textField.setBounds(116, 28, 141, 20);
        add(textField);
        textField.setColumns(10);

        JTextArea textArea = new JTextArea();
        textArea.setBounds(116, 66, 141, 112);
        add(textArea);

        JButton btnClose = new JButton("Close");
        btnClose.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

            }
        });
        btnClose.setBounds(223, 244, 89, 23);
        add(btnClose);

    }

}

person Kyle    schedule 14.06.2013    source источник
comment
север восток юг юг восток восток запад восток   -  person PrR3    schedule 14.06.2013
comment
@PrR3 Приятно знать, спасибо.   -  person giannis christofakis    schedule 14.06.2013
comment
N orth S outh E ast W est - может это и означает, но что это значит? Нет такой вещи, как форматирование NSEW, как предлагает OP.   -  person camickr    schedule 14.06.2013
comment
Следуйте соглашениям об именах Java. Имена переменных не должны начинаться с заглавной буквы. Мейнфрейм должен быть mainframe.   -  person camickr    schedule 14.06.2013
comment
Я возьму на заметку соглашение об именах, это стало моей плохой привычкой, хе-хе. Думаю, я сам накосячил с форматированием NSEW в кардлейауте. Я попробую CardLayout еще раз, чтобы увидеть, поможет ли это мне в моей проблеме. Вернёмся к вам, ребята, о том, как всё прошло~!   -  person Kyle    schedule 14.06.2013
comment
Спасибо, ребята, за помощь, мне удалось решить проблему, используя ваш совет!   -  person Kyle    schedule 14.06.2013


Ответы (3)


Я пытался использовать CardLayout, но он имеет только форматирование NSEW.

Что это обозначает? CardLayout просто содержит две или более панелей. Одновременно видна только одна панель. Каждая панель может использовать любой макет для размещения компонентов на панели.

когда я нажимаю на нее, я хочу, чтобы она переключилась на другую JPanel.

Это именно то, что делает CardLayout. См. учебное пособие по Swing Как использовать макет карты для рабочего пример и объяснение.

Всякий раз, когда я вижу такой код, как удаление/добавление/перепроверка/перерисовка, его почти всегда следует заменять на CardLayout

person camickr    schedule 14.06.2013
comment
Я попробовал CardLayout, и это позволяет мне иметь только один компонент Swing внутри. Но я последую вашему совету и еще раз попробую CardLayout :) Я еще вернусь к этой теме~ Спасибо за помощь - person Kyle; 14.06.2013
comment
@kyle, вы добавляете панель в CardLayout. Панель может иметь столько компонентов, сколько вы хотите добавить к ней. Посмотрите на учебник, панель имеет более одного компонента. - person camickr; 14.06.2013
comment
Я последовал тому, что вы предложили, и это сработало как шарм, спасибо, camickr! - person Kyle; 14.06.2013

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

    private JComponent container; // this could be your Frame
    private JComponent loadedComponent;

public void loadContent(JComponent component, Object object ) {

        if (loadedComponent != null) {
            loadedComponent.setVisible(false);
            container.remove(loadedComponent);
            loadedComponent = null;
        }
        //TODO may check layout
        container.add(component,object);
        component.setVisible(true);
        loadedComponent = component;
        container.validate();
    }
person nachokk    schedule 14.06.2013

Проблема, вероятно, находится в следующих строках в классе OnlineShopAdPane.java

OnlineShopMainFrame MainFrame = new OnlineShopMainFrame();
MainFrame.removeAll();
MainFrame.add(new AddProduct());
MainFrame.revalidate();
MainFrame.repaint();

вы не имеете в виду фрейм, в котором вложена ваша JPanel. вместо этого вы создаете новый OnlineShopMainFrame

person PrR3    schedule 14.06.2013
comment
Я попытался ввести в OnlineShopAdPane следующий код: OnlineShopMainFrame MainFrame; Но это выдало мою ошибку, когда я запускаю программу. - person Kyle; 14.06.2013
comment
этот фрагмент кода не нов! Я просто хотел дать вам подсказку, откуда взялась ваша ошибка и в чем причина... - person PrR3; 14.06.2013
comment
Как мне обратиться к фрейму, в котором вложен мой JPanel? - person Kyle; 14.06.2013
comment
Я узнал, как обратиться к фрейму, где находится JPanel минуту назад, спасибо, что указали мне на это! - person Kyle; 14.06.2013