NOTE
以下共两种解决方案。
- 手动操作面板容器和其组件(add, remove等)
// 以contentPanel为底,其上覆盖想要展示的panel内容(切换panel)。
private void showSpecifiedPanel(Panel contentPanel, Panel showPanel) {
contentPanel.removeAll();
contentPanel.add(showPanel);
contentPanel.validate();
contentPanel.repaint();
}
- 直接设置窗口的
contentPane
属性(推荐)。
// 切换内容面板
public void changeContentPane(Container contentPane) {
this.setContentPane(contentPane);
this.revalidate();
}
后期如果有其他解决方案,我会继续追加。
需求
在Java GUI编程中,要求点击菜单栏中不同的菜单项,切换主面板中的显示内容。
解决:
主面板为Panel contentPanel
(用于放置其他具体的功能面板)。
其他面板,如Panel p1, p2
,先自定义好(这些功能面板,向contentPanel
面板上添加)。
当点击被监听器监听着的菜单项后,执行以下方法:
// 以contentPanel为底,其上覆盖想要展示的panel内容(切换panel)。
private void showSpecifiedPanel(Panel contentPanel, Panel showPanel) {
contentPanel.removeAll();
contentPanel.add(showPanel);
contentPanel.validate();
contentPanel.repaint();
}
即:先移除contentPanel
上的所有组件,然后放置所需的、具体的某个功能面板。
然后执行validate()
和repaint()
方法,重新绘制图形。
- 其他相关API
在处理多Panel切换的过程中,检索到的其他相关API如下:hide()
隐藏面板show()
显示面板isVisible()
面板是否可见setVisible(boolean isVisible)
设置面板的可见性
一开始的解决思路是重叠添加多个面板,然后控制各个面板的可见状态(显示,隐藏)。奈何不成。所以还是使用之上的方法。
效果图
学生
菜单项下有添加
和查看
两个菜单项。
点击添加
显示添加学生信息面板。
点击查看
显示查看学生信息面板。
- 主面板
- 添加学生信息(面板细节自定义)
- 查看学生面板(细节自定义)
Code
import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
MenuBar menuBar; // 菜单栏
Menu student; // 菜单
MenuItem add, show; // 菜单项
Panel contentPanel; // 内容面板,其上用于添加其他待切换的面板
public MyFrame() {
// 初始化组件
menuBar = new MenuBar();
student = new Menu("学生");
add = new MenuItem("添加");
show = new MenuItem("查看");
contentPanel = new Panel();
// 菜单项添加事件监听器
add.addActionListener(this);
show.addActionListener(this);
// 设置窗口的菜单栏,菜单和各个菜单项。
student.add(add);
student.add(show);
menuBar.add(student);
setMenuBar(menuBar);
// 设置布局为边界布局管理器。将contentPanel添加到窗口中心位置。
setLayout(new BorderLayout());
contentPanel.add(new Label("欢迎使用教学管理系统")); // 欢迎页消息
add(contentPanel, BorderLayout.CENTER);
// 窗口的其他参数
setTitle("测试");
setBounds(300, 50, 400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == add) {
showSpecifiedPanel(contentPanel, new MyPanel("请添加学生信息"));
} else if (source == show) {
showSpecifiedPanel(contentPanel, new MyPanel("您正在查看学生信息"));
}
}
// 以contentPanel为底,其上覆盖想要展示的panel内容(切换panel)。
private void showSpecifiedPanel(Panel contentPanel, Panel showPanel) {
contentPanel.removeAll();
contentPanel.add(showPanel);
contentPanel.validate();
contentPanel.repaint();
}
}
// 简易地获取所需的面板(使用时需自定义)
class MyPanel extends Panel {
public MyPanel(String msg) {
this.add(new Label(msg));
}
}
方案2
JFrame
类的实例方法:
setContentPane(Container contentPane)revalidate()
封装方法:
// 切换内容面板
public void changeContentPane(Container contentPane) {
this.setContentPane(contentPane);
this.revalidate();
}
运行效果相同。都是点击不同的菜单项后,切换不同的主面板。
代码(将以上源码稍作修改即可):
import java.awt.Container;
import java.awt.Label;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
MenuBar menuBar; // 菜单栏
Menu student; // 菜单
MenuItem add, show; // 菜单项
Panel contentPanel; // 内容面板,其上用于添加其他待切换的面板
public MyFrame() {
// 初始化组件
menuBar = new MenuBar();
student = new Menu("学生");
add = new MenuItem("添加");
show = new MenuItem("查看");
contentPanel = new Panel();
// 菜单项添加事件监听器
add.addActionListener(this);
show.addActionListener(this);
// 设置窗口的菜单栏,菜单和各个菜单项。
student.add(add);
student.add(show);
menuBar.add(student);
setMenuBar(menuBar);
// 设置布局为边界布局管理器。将contentPanel添加到窗口中心位置。
this.setContentPane(new MyPanel("这是欢迎页 - setContentPane()"));
// 窗口的其他参数
setTitle("测试");
setBounds(300, 50, 400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == add) {
changeContentPane(new MyPanel("添加学生信息 - setContentPane()"));
} else if (source == show) {
changeContentPane(new MyPanel("查看学生信息 - setContentPane()"));
}
}
// 切换内容面板
public void changeContentPane(Container contentPane) {
this.setContentPane(contentPane);
this.revalidate();
}
}
// 简易地获取所需的面板(使用时需自定义)
class MyPanel extends Panel {
public MyPanel(String msg) {
this.add(new Label(msg));
}
}