业精于勤,荒于嬉
全部博文(763)
分类: Java
2008-06-17 08:38:14
在视窗式应用程序中菜单的使用是非常普遍的,Javax.swing提供的菜单功能非常强大。建立菜单要使用下面几个类:菜单条JMenuBar,菜单JMenu和菜单项JMenuItem。
在JFrame中创建菜单条很简单,使用JMenuBar的默认构建器并用setJMenuBar(JMenuBar mb)方法放置到窗体中就可。例如:
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu的构建器也很简单,只有提供菜单名就可以了,然后用add方法加入到菜单条中。例如:
JMenu filemenu = new JMenu("文件");
menuBar.add(fJMenuBarilemenu);
filemenu.addJMenuItem(菜单项或子菜单) 子菜单也是一个JMenu对象
菜单项JMenuItem是普通菜单项,此外,菜单项还可以是单选框和复选框,即JRadioButtonMenuItem和JCHeckBoxMenuItem。普通菜单项的显示内容可以是文字、图标或文字加图标。因此,JMenuItem的常用构建器是以下几种:
JMenuItem(String text) 文本式
JMenuItem(Icon icon) 图标式
JMenuItem(String text, Icon icon) 文本图标式
JMenuItem(String text,int mnemonic) 带助记符(keyboard mnemonic类)
在菜单JMenu中添加助记符必须使用setMnemonic()方法来实现。
在菜单项中还可以设置快捷键:
void setAccelerator(KeyStroke, KeyStroke)
例如:
在菜单中添加一条分隔线不用菜单项,只有用方法mennu.setSeparator()即可。
对菜单事件一般使用活动监听器,需要对每个菜单项添加。下面的例1演示创建菜单和监听菜单活动的基本方法。
例9 本程序演示创建菜单和普通菜单项以及菜单活动监听。
程序运行后的界面如图9所示。点击菜单项PG, Group和File/Open/javafile有所反应。
图9
程序的代码如下:
///
// Manu1.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
class MyFrame extends JFrame implements ActionListener{
public MyFrame() {
setTitle("普通菜单示例程序");
setSize(300, 200);
setLocation(100,100);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
myPanel = new MyPanel();
getContentPane().add(myPanel, "Center");
//新建一个菜单栏
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
//新建一个菜单对象
JMenu fileMenu = new JMenu("File");
//添加一个菜单项
fileMenu.add(new JMenuItem("New"));
//添加一个子菜单
JMenu openMenu = new JMenu("Open");
openMenu.add(new JMenuItem("TxtFile"));
openMenu.add(new JMenuItem("DocFile"));
JMenuItem javaFileItem = new JMenuItem("JavaFile");
openMenu.add(javaFileItem);
javaFileItem.addActionListener(this);
fileMenu.add(openMenu);
menuBar.add(fileMenu);
//新建一个菜单
JMenu findMenu = new JMenu("Find");
//设置助记符
findMenu.setMnemonic('F');
//新建7个不同的菜单项
findMenu.add(new JMenuItem());
ImageIcon icon = new ImageIcon("images/middle.gif");
findMenu.add(new JMenuItem(icon));
findMenu.add(new JMenuItem("File"));
findMenu.add(new JMenuItem("Directory", icon));
JMenuItem pcItem = new JMenuItem("PC", 'P');
pcItem.addActionListener(this);
findMenu.add(pcItem);
//新建一个分隔线
findMenu.addSeparator();
JMenuItem gp = new JMenuItem("Group");
//为group菜单项增加快捷键
gp.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_MASK));
gp.addActionListener(this);
findMenu.add(gp);
menuBar.add(findMenu);
}
public void actionPerformed(ActionEvent evt){
if (evt.getSource() instanceof JMenuItem){
//判断事件源是否为菜单项
String itemName = evt.getActionCommand();
if (itemName.equals("JavaFile")) {
myPanel.setMsg("You've pressed menu : JavaFile");
}
else if (itemName.equals("PC")) {
myPanel.setMsg("You've pressed menu : PC");
}
else if (itemName.equals("Group")){
myPanel.setMsg("You've pressed menu : Group");
}
}
}
private MyPanel myPanel;
}
class MyPanel extends JPanel{
public MyPanel() {
szShowMsg = "";
}
public void setMsg(String szMsg) {
szShowMsg = szMsg;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString(szShowMsg, 20, 20);
}
private String szShowMsg;
}
public class Menu1{
public static void main(String[] args){
JFrame frame = new MyFrame();
frame.setVisible(true);
}
}
///
简要说明
程序包括3个类Menu1,MyFrame和MyPanel。MyPanel中添加一个标签,用来显示鼠标点击某些菜单项时的反应信息。
类MyFrame是主要的,它是一个建立了菜单窗体,扩充了活动监听器ActionListener。MyFrame中实现了actionPerformed方法。
从上面的例子我们可以看到,要建立一个菜单需要写冗长而又单调的代码。如果能建立一个方法 让循环语句自动生成菜单好了。我们把几菜单需要的信息如菜单名、类型、快捷键等放在对象数组中,由“创建方法”读取和识别信息并自动生成菜单。下面的例程 好象一个通用菜单,包括“文件、编辑、查找、选项和帮助”五个一个菜单。您只要修改提供信息的数组内容,就可以把它变成适用于自己的菜单。
例10 通用菜单程序,由一个二维对象数组提供一个菜单及其菜单项的信息。
二维对象数组的第一个元素是菜单信息,其余的是菜单项的信息。菜单信息包括{名称,快捷键},菜单项信息包括{ "New", mi, new Character('N'), a1, bT } 即 {名称,菜单项类型,快捷键,监听器对象,是否可用}。菜单项类型有mi普通型,ch复选框,rb单选框三种静态变量。因此,“创建方法”能自动识别菜单项的类型和一个菜单中包含菜单项的个数。这就方便了使用者,只要修改数组内容就可以创建不同的菜单。
程序中定义了三个方法。
创建菜单条方法
static public JMenuBar createMenuBar(Object[] menuBarData) {
JMenuBar menuBar = new JMenuBar();
for(int i = 0; i < menuBarData.length; i++)
menuBar.add(createMenu((Object[][])menuBarData[i]));
return menuBar;
}
输入参数menuBarData数组中元素的JMenu对象。
创建菜单方法
static public JMenu createMenu(Object[][] menuData) {
JMenu menu = new JMenu();
menu.setText((String)menuData[0][0]);
menu.setMnemonic(((Character)menuData[0][1]).charValue());
// Create redundantly, in case there are
// any radio buttons:
bgroup = new ButtonGroup();
for(int i = 1; i < menuData.length; i++) {
if(menuData[i][0] == null)
menu.add(new JSeparator());
else
menu.add(createMenuItem(menuData[i]));
}
return menu;
}
菜单名称由首元素menuData[0][0]提供,利用menuData[i]的数据生成菜单项。
创建菜单项方法
static public JMenuItem createMenuItem(Object[] data) {
JMenuItem m = null;
MType type = (MType)data[1];
if(type == mi)
m = new JMenuItem();
else if(type == cb)
m = new JCheckBoxMenuItem();
else if(type == rb) {
m = new JRadioButtonMenuItem();
bgroup.add(m);
}
m.setText((String)data[0]);
m.setMnemonic(((Character)data[2]).charValue());
m.addActionListener((ActionListener)data[3]);
m.setEnabled(((Boolean)data[4]).booleanValue());
if(data.length == 6) //第6个元素的图标
m.setIcon((Icon)data[5]);
return m;
}
程序先根据data[1]判断类型以便生成不同的菜单项,然后设置其他各项,最后返回JMenuItem对象。程序运行后的界面如图10所示。
图10
本程序的完整原代码如下:
///
// Menus.java 通用菜单
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Menus extends JPanel {
Icon[] faces = {
new ImageIcon("images\\face0.gif"),
new ImageIcon("images\\face1.gif"),
new ImageIcon("images\\face2.gif"),
new ImageIcon("images\\face3.gif"),
new ImageIcon("images\\face4.gif"),
};
static final Boolean
bT = new Boolean(true),
bF = new Boolean(false);
// Dummy class to create type identifiers:
static class MType { MType(int i) {} };
static final MType
mi = new MType(1), // Normal menu item
cb = new MType(2), // Checkbox menu item
rb = new MType(3); // Radio button menu item
JTextField t = new JTextField(10);
JLabel l = new JLabel("Icon Selected", faces[0], JLabel.CENTER);
ActionListener a1 = new ActionListener() {
public void actionPerformed(ActionEvent e) {
t.setText(((JMenuItem)e.getSource()).getText());
}
};
ActionListener a2 = new ActionListener() {
public void actionPerformed(ActionEvent e) {
JMenuItem mi = (JMenuItem)e.getSource();
l.setText(mi.getText());
l.setIcon(mi.getIcon());
}
};
// Store menu data as "resources":
public Object[][] fileMenu = {
// Menu name and accelerator:
{ "File", new Character('F') },
// Name type accel listener enabled
{ "New", mi, new Character('N'), a1, bT },
{ "Open", mi, new Character('O'), a1, bT },
{ "Save", mi, new Character('S'), a1, bF },
{ "Save As", mi, new Character('A'), a1, bF},
{ null }, // Separator
{ "Exit", mi, new Character('x'), a1, bT },
};
public Object[][] editMenu = {
// Menu name:
{ "Edit", new Character('E') },
// Name type accel listener enabled
{ "Cut", mi, new Character('t'), a1, bT },
{ "Copy", mi, new Character('C'), a1, bT },
{ "Paste", mi, new Character('P'), a1, bT },
{ null }, // Separator
{ "Select All", mi,new Character('l'),a1,bT},
};
public Object[][] helpMenu = {
// Menu name:
{ "Help", new Character('H') },
// Name type accel listener enabled
{ "Index", mi, new Character('I'), a1, bT },
{ "Using help", mi,new Character('U'),a1,bT},
{ null }, // Separator
{ "About", mi, new Character('t'), a1, bT },
};
public Object[][] optionMenu = {
// Menu name:
{ "Options", new Character('O') },
// Name type accel listener enabled
{ "Option 1", cb, new Character('1'), a1,bT},
{ "Option 2", cb, new Character('2'), a1,bT},
};
public Object[][] faceMenu = {
// Menu name:
{ "Faces", new Character('a') },
// Optinal last element is icon
{ "Face 0", rb, new Character('0'), a2, bT,faces[0] },
{ "Face 1", rb, new Character('1'), a2, bT,faces[1] },
{ "Face 2", rb, new Character('2'), a2, bT,faces[2] },
{ "Face 3", rb, new Character('3'), a2, bT,faces[3] },
{ "Face 4", rb, new Character('4'), a2, bT,faces[4] },
};
public Object[] menuBar = {fileMenu, editMenu,
faceMenu, optionMenu, helpMenu,
};
static public JMenuBar
createMenuBar(Object[] menuBarData) {
JMenuBar menuBar = new JMenuBar();
for(int i = 0; i < menuBarData.length; i++)
menuBar.add(
createMenu((Object[][])menuBarData[i]));
return menuBar;
}
static ButtonGroup bgroup;
static public JMenu createMenu(Object[][] menuData) {
JMenu menu = new JMenu();
menu.setText((String)menuData[0][0]);
menu.setMnemonic(((Character)menuData[0][1]).charValue());
// Create redundantly, in case there are
// any radio buttons:
bgroup = new ButtonGroup();
for(int i = 1; i < menuData.length; i++) {
if(menuData[i][0] == null)
menu.add(new JSeparator());
else
menu.add(createMenuItem(menuData[i]));
}
return menu;
}
static public JMenuItem createMenuItem(Object[] data) {
JMenuItem m = null;
MType type = (MType)data[1];
if(type == mi)
m = new JMenuItem();
else if(type == cb)
m = new JCheckBoxMenuItem();
else if(type == rb) {
m = new JRadioButtonMenuItem();
bgroup.add(m);
}
m.setText((String)data[0]);
m.setMnemonic(((Character)data[2]).charValue());
m.addActionListener((ActionListener)data[3]);
m.setEnabled(((Boolean)data[4]).booleanValue());
if(data.length == 6)
m.setIcon((Icon)data[5]);
return m;
}
Menus() {
setLayout(new BorderLayout());
add(createMenuBar(menuBar),
BorderLayout.NORTH);
JPanel p = new JPanel();
p.setLayout(new BorderLayout());
p.add(t, BorderLayout.NORTH);
p.add(l, BorderLayout.CENTER);
add(p, BorderLayout.CENTER);
}
public static void main(String args[]) {
Show.inFrame(new Menus(), 300, 200);
}
}
///
简要说明
本程序利用构建器Menus()创建菜单、面版和布局,用一个add(createMenuBar(menuBar))就建立了全部菜单。main方法中的Show.inFrame的代码见例7。
弹出式菜单JPopupMenu
弹出式菜单用JPopupMenu创建,其用法和菜单项与JMenu一样。监听器使用PopupListener,它包含方法maybeShowPopup。
例11 弹出式菜单示例程序。
///public class Popup extends JPanel {
JPopupMenu popup = new JPopupMenu();
JTextField t = new JTextField(10);
public Popup() {
add(t);
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent e){
t.setText(((JMenuItem)e.getSource()).getText());
}
};
JMenuItem m = new JMenuItem("Hither");
m.addActionListener(al);
popup.add(m);
m = new JMenuItem("Yon");
m.addActionListener(al);
popup.add(m);
m = new JMenuItem("Afar");
m.addActionListener(al);
popup.add(m);
popup.addSeparator();
m = new JMenuItem("Stay Here");
m.addActionListener(al);
popup.add(m);
PopupListener pl = new PopupListener();
addMouseListener(pl);
t.addMouseListener(pl);
}
class PopupListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if(e.isPopupTrigger()) {
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
}
public static void main(String args[]) {
Show.inFrame(new Popup(),200,150);
}
}
///
程序运行后如图11所示
图11
简要说明
为弹出菜单创建类PopupListener,它从鼠标适配器继承,其中实现了鼠标“按下和松开”操作。
popup菜单用了popup.show(e.getComponent(), e.getX(), e.getY())方法显示菜单。