#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 для этого, чтобы вы могли немного больше изолировать функциональность, подробнее см. Как использовать действия.