добавить панель в фрейм во внутреннем классе слушателя?

#java #listener #panel

#java #слушатель #панель

Вопрос:

 class MemberBook extends Frame {
        MenuBar     mb;
        Menu        menu;
        MenuItem    miReg, miList, miExit;

        MemberBook() {
                super();

                mb      = new MenuBar();
                menu    = new Menu("Menu");
                miReg   = new MenuItem("Register");
                miList  = new MenuItem("List");
                miExit  = new MenuItem("Exit");

                menu.add(miReg);
                menu.add(miList);
                menu.addSeparator();
                menu.add(miExit);

                mb.add(menu);
                setMenuBar(mb);

                MenuHandler handler = new MenuHandler(this);
                miReg.addActionListener(handler);
                miList.addActionListener(handler);
                miExit.addActionListener(handler);

                setSize(300, 500);
                setVisible(true);
        }

        public static void main(String args[]) {
                MemberBook win = new MemberBook();
        }

        class MenuHandler implements ActionListener {
                MemberBook frame;

                // I want to add panel to outer class but I don't know 
                // other way to do it so, get _frame in constructor
                MenuHandler(MemberBook _frame) {
                        frame = _frame;
                }

                // show different panels for each menu
                public void actionPerformed(ActionEvent e) {
                        String command = e.getActionCommand();

                        if (command.equals("Register")) {
                                RegisterPanel panel = new RegisterPanel();
                                frame.add(panel, "Center");
                        }
                        // else if ...
                }
        }

        // predefined panel to show in MemberBook frame 
        class RegisterPanel extends Panel {
        }                   
}
 

Я хочу создать предварительно определенную панель регистрации участников, панель списка участников (вы можете просматривать список участников и редактировать участников) и показывать при выборе меню, но RegisterPanel не отображается, когда я выбираю меню регистрации. Я не знаю другого способа добавить панель к фрейму во внутреннем классе слушателя, поэтому перенес фрейм в конструктор слушателя.

Комментарии:

1. Используйте CardLayout

Ответ №1:

Итак, основной ответ: используйте a CardLayout , подробнее см. Как использовать CardLayout .

 import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class MemberBook {

    public static void main(String[] args) {
        new MemberBook();
    }

    private JMenuBar mb;
    private JMenu menu;
    private JMenuItem miReg, miList, miExit;

    public MemberBook() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                mb = new JMenuBar();
                menu = new JMenu("Menu");
                miReg = new JMenuItem("Register");
                miList = new JMenuItem("List");
                miExit = new JMenuItem("Exit");

                menu.add(miReg);
                menu.add(miList);
                menu.addSeparator();
                menu.add(miExit);

                mb.add(menu);

                MainPane mainPane = new MainPane();

                MenuHandler handler = new MenuHandler(mainPane);
                miReg.addActionListener(handler);
                miList.addActionListener(handler);
                miExit.addActionListener(handler);

                JFrame frame = new JFrame();
                frame.setJMenuBar(mb);
                frame.add(mainPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public interface MemberBookController {
        public void registerUser();
    }

    public class MainPane extends JPanel implements MemberBookController {

        private CardLayout cardLayout;

        public MainPane() {
            cardLayout = new CardLayout();
            setLayout(cardLayout);

            add(new WelcomePane(), "welcome");
            add(new RegisterPanel(), "register");

            cardLayout.show(this, "welcome");
        }

        @Override
        public void registerUser() {
            cardLayout.show(this, "register");
        }

    }

    public class MenuHandler implements ActionListener {

        private MemberBookController controller;

        // I want to add panel to outer class but I don't know 
        // other way to do it so, get _frame in constructor
        MenuHandler(MemberBookController controller) {
            this.controller = controller;
        }

        // show different panels for each menu
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();

            if (command.equals("Register")) {
                controller.registerUser();
            }
            // else if ...
        }
    }

    public class WelcomePane extends JPanel {

        public WelcomePane() {
            setBorder(new EmptyBorder(16, 16, 16, 16));
            setLayout(new GridBagLayout());
            add(new JLabel("Welcome"));
            setBackground(Color.BLUE);
        }

    }

    // predefined panel to show in MemberBook frame 
    public class RegisterPanel extends JPanel {

        public RegisterPanel() {
            setBorder(new EmptyBorder(16, 16, 16, 16));
            setLayout(new GridBagLayout());
            add(new JLabel("Register"));
            setBackground(Color.RED);
        }

    }
}
 

Этот пример также демонстрирует использование a interface для обеспечения «скрытия информации». На самом MenuHandler деле ему не нужен доступ к фрейму или базовой панели, на самом деле, это не должно волновать. Все, что нужно сделать, это сообщить заинтересованным сторонам, что произошло какое-то действие.

Я мог бы рассмотреть возможность использования Action API для этого, чтобы вы могли немного больше изолировать функциональность, подробнее см. Как использовать действия.