Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5543024
  • 博文数量: 763
  • 博客积分: 12108
  • 博客等级: 上将
  • 技术积分: 15717
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-28 21:21
个人简介

业精于勤,荒于嬉

文章分类

全部博文(763)

文章存档

2018年(6)

2017年(15)

2016年(2)

2015年(31)

2014年(14)

2013年(87)

2012年(75)

2011年(94)

2010年(190)

2009年(38)

2008年(183)

2007年(28)

分类: 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  弹出式菜单示例程序。

///
// Popup.java
弹出式菜单
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

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())方法显示菜单。

阅读(3566) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~