JPopupMenu

12-7:使用 JPopupMenu 组件。

  JPopupMenu 的类层次结构图:

  java.lang.Object
   --java.awt.Component
    --java.awt.Container
     --javax.swing.JComponent
      --javax.swing.JPopupMenu

   JPopupMenu 是一种特别形式的 Menu,其性质与 Menu 几乎完全相同,但是 PopupMenu 并不固定在窗口的任何一个位置,而是由鼠标指针和系统判断决定 PopupMenu 要出现在哪里。相信大家在使用许多软件时都有用过 Popupmenu 的功能,例如在使用 Word 文书编辑器软件时,当我们在编辑区域的任一处按下鼠标右键,就会跳出一个 PopupMenu 菜单。

  JPopupMenu 构造函数:
  JPopupMenu():建立一个新的 JPopupMenu;
  JPopupMenu(String label):建立一个指定标题的 JPopupMenu。

  12-7-1:构造 JPopupMenu 组件:

  我们知道 JPopupMenu 的构造方法并不复杂,两种构造方法的差异只在于是否赋予 JPopupMenu 一个标题文字。我们马上来看下面这个范例,了解如何应用 JPopupMenu。

  import javax.swing.*;
  import java.awt.*;
  import java.awt.event.*;
  import javax.swing.event.*;
  import javax.swing.border.*;
  import java.util.*;
  import com.incors.plaf.alloy.*;
  import com.incors.plaf.alloy.themes.glass.*;

  public class JPopupMenu1 extends JFrame{

    JTextArea theArea = null;
    static final String ComboStr[] = {"Times New Roman","Dialog","宋体","黑体","楷体"};
    JPopupMenu Popup = null;//声明一个全局 (Global) 并设置初始值为 null 的 JPopupMenu 组件。

    public JPopupMenu1(){
   
      super("JPopupMenu1");
      theArea = new JTextArea();
      theArea.setEditable(false);
      this.getContentPane().add(new JScrollPane(theArea),BorderLayout.CENTER);
      JMenuBar MBar = new JMenuBar();
      MBar.setOpaque(true);
      JMenu mfile = buildFileMenu();
      JToolBar theBar = buildToolBar();
      this.getContentPane().add(theBar,BorderLayout.NORTH);
      PopupPanel pp = new PopupPanel();//new 一个 PopupPanel 组件来放置 JPopupMenu。
      this.getContentPane().add(pp,BorderLayout.SOUTH); //将 PopupPanel 组件放置到窗口中。

      MBar.add(mfile);
      setJMenuBar(MBar);
    }//end of JPopupMenu1()

    /*****************begin**********************
    分别建立程序中菜单,工具栏和事件处理模式的部份,我们在此不再加以说明。
    ****************************************/

    public JMenu buildFileMenu() {

      JMenu thefile = new JMenu("File");
      thefile.setMnemonic('F');

      JMenuItem newf = new JMenuItem("New",new ImageIcon("icons/new24.gif"));
      JMenuItem open = new JMenuItem("Open",new ImageIcon("icons/open24.gif"));
      JMenuItem close= new JMenuItem("Close",new ImageIcon("icons/close24.gif"));
      JMenuItem quit = new JMenuItem("Exit",new ImageIcon("icons/exit24.gif"));

      newf.setMnemonic('N');
      open.setMnemonic('O');
      close.setMnemonic('L');
      quit.setMnemonic('X');

      newf.setAccelerator( KeyStroke.getKeyStroke('N', java.awt.Event.CTRL_MASK, false) );
      open.setAccelerator( KeyStroke.getKeyStroke('O', java.awt.Event.CTRL_MASK, false) );
      close.setAccelerator( KeyStroke.getKeyStroke('L', java.awt.Event.CTRL_MASK, false) );
      quit.setAccelerator( KeyStroke.getKeyStroke('X', java.awt.Event.CTRL_MASK, false) );

      newf.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          theArea.append("- MenuItem New Performed -\n");
      }});

      open.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          theArea.append("- MenuItem Open Performed -\n");
      }});

      close.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          theArea.append("- MenuItem Close Performed -\n");
      }});

      quit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          System.exit(0);
      }});

      thefile.add(newf);
      thefile.add(open);
      thefile.add(close);
      thefile.addSeparator();
      thefile.add(quit);

      return thefile;
    }//end of buildFileMenu()
 
    public JToolBar buildToolBar() {
  
      JToolBar toolBar = new JToolBar();
      toolBar.setFloatable(true);

      ToolBarAction tba_new = new ToolBarAction("new",new ImageIcon("icons/new24.gif"));
      ToolBarAction tba_open = new ToolBarAction("open",new ImageIcon("icons/open24.gif"));
      ToolBarAction tba_close = new ToolBarAction("close",new ImageIcon("icons/close24.gif"));

      JButton JB;
      JB = toolBar.add(tba_new);
      JB.setActionCommand("#TooBar_NEW performed!");
      JB.setToolTipText((String)tba_new.getValue(Action.NAME));
      JB = toolBar.add(tba_open);
      JB.setActionCommand("#ToolBar_OPEN performed!");
      JB.setToolTipText((String)tba_open.getValue(Action.NAME));
      JB = toolBar.add(tba_close);
      JB.setActionCommand("#ToolBar_CLOSE performed!");
      JB.setToolTipText((String)tba_close.getValue(Action.NAME));
  
      toolBar.addSeparator();
 
      ToolBarAction tba_B = new ToolBarAction("bold",new ImageIcon("icons/bold24.gif"));
      ToolBarAction tba_I = new ToolBarAction("italic",new ImageIcon("icons/italic24.gif"));
      ToolBarAction tba_U = new ToolBarAction("underline",new ImageIcon("icons/underline24.gif"));
      JB = toolBar.add(tba_B);
      JB.setActionCommand("#ToolBar_Bold performed!");
      JB.setToolTipText((String)tba_B.getValue(Action.NAME));
      JB = toolBar.add(tba_I);
      JB.setActionCommand("#ToolBar_Italic performed!");
      JB.setToolTipText((String)tba_I.getValue(Action.NAME));
      JB = toolBar.add(tba_U);
      JB.setActionCommand("#ToolBar_Underline performed!");
      JB.setToolTipText((String)tba_U.getValue(Action.NAME));
 
      toolBar.addSeparator();
      JLabel JLfont = new JLabel("Font Type");
      toolBar.add(JLfont);
      toolBar.addSeparator();
      JComboBox jcb = new JComboBox(ComboStr);
      jcb.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
        theArea.append("*Combobox "+((JComboBox)e.getSource()).getSelectedItem()+"performed!\n");
      }});
      toolBar.add(jcb);
  
      return toolBar;
    }//end of buildToolBar()
    /*****************End**********************
    分别建立程序中菜单,工具栏和事件处理模式的部份,我们在此不再加以说明。
    ****************************************/
  
    public static void main(String[] args){
      SwingUtil.setLookAndFeel();
      JFrame F = new JPopupMenu1();
      F.setSize(430,200);
      F.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          System.exit(0);
        }
      });//end of addWindowListener
      F.setVisible(true);
    } // end of main

  class ToolBarAction extends AbstractAction{

    public ToolBarAction(String name,Icon icon){
      super(name,icon);
    }

    public void actionPerformed(ActionEvent e){
 
      try{
        theArea.append(e.getActionCommand()+"\n");
      }catch(Exception ex){}
    }
  }//end of inner class ToolBarAction

  本方法建立inner class PopupPanel。这个类继承 JPanel 并实作 MouseListener,PopupMenuListener,ActionListener 和 ActionListener等 3 个 Listener。MouseListener为处理鼠标事件的 Listener,PopupMenuListener 为 Popup 菜单事件的 Listener,ActionListener 则是大家最熟悉用来处理 JMenuItem 事件的 Listener。

  class PopupPanel extends JPanel implements MouseListener,PopupMenuListener,ActionListener{

    public PopupPanel(){
 
    Popup = new JPopupMenu();//new 一个新的JPopupMenu。
 
    JMenuItem theItem;
 
    //分别建立四个 JMenuItem 和其事件处理模式将将 JMenuItem 加入 JPopupMenu 中。

    Popup.add(theItem = new JMenuItem("Cut",new ImageIcon("icons/cut24.gif")));//建立JMenuItem 组件。
    theItem.addActionListener(this);//将 JMenuItem 组件加入事件处理模式。
    Popup.add(theItem = new JMenuItem("Copy",new ImageIcon("icons/copy24.gif")));
    theItem.addActionListener(this);
    Popup.add(theItem = new JMenuItem("Paste",new ImageIcon("icons/paste24.gif")));
    theItem.addActionListener(this);
    Popup.addSeparator();//在 JPopupMenu 中加入分隔线,我们在前面有提到 JPopupMenu 和 Menu 大致上的性质是一样的,所以在 JPopupMenu 中一样是以 JMenuItem 来当作选项的组件。

    Popup.add(theItem = new JMenuItem("Page Setup..."));
    theItem.addActionListener(this);
 
    //利用 setBorder() 方法将 BevelBorde r类当作参数传入,使 JPopupMenu 产生立体边框浮起的效果。我们也可以将参数设置改为 BevelBorder.LOWERED 使得 JPopupMenu 产生立体边框凹陷的效果。

    Popup.setBorder(new BevelBorder(BevelBorder.RAISED));

    Popup.addPopupMenuListener(this); //将 JPopupMenu 组件加入 PopupMenu 事件处理模式中。
    addMouseListener(this);//将PopupPanel类加入 Mouse 事件处理模式中。
    theArea.addMouseListener(this);//后面有说明
  
  }//end of PopupPanel()

  由于 PopupPanel 这个 inner class 中实作了 MouseListener,因此需要覆写 mouseClicked(),mousePressed(),*mouseReleased(),mouseEntered() 和 mouseExited() 等 5 个方法。在这个范例里当 mouseClicked(),mousePressed() 和 mouseReleased() 等 3 个方法被触发时会调用 checkPopup() 方法来判断是否要将 PopupMenu 输出来。

    public void mouseClicked(MouseEvent me){ checkPopup(me);}
    public void mousePressed(MouseEvent me){ checkPopup(me);}
    public void mouseReleased(MouseEvent me){ checkPopup(me);}
    public void mouseEntered(MouseEvent me){}
    public void mouseExited(MouseEvent me){}

    checkPopup() 方法。其中,在程序中利用 isPopupTrigger() 方法判断 PopupMenu 是否已经输出。若没有,则在程序中利用 show() 方法将 PopupMenu 输出目前鼠标指针(利用 getX() 和 getY() 方法得知)的位置上。

    private void checkPopup(MouseEvent me){
      if(me.isPopupTrigger()){
        Popup.show(me.getComponent(), me.getX(), me.getY());
      }
    }//end of checkPopup()
   
    由于 PopupPanel 这个 inner class 实作了 PopupMenuListener,因此需要覆写popupMenuWillBecomeVisible(), popupMenuWillBecomeInvisible() 方法和 popupMenuCanceled() 等 3 个方法。在这个范例里当这 3 个方法被触发后会在JTextArea中加入一个信息。

    public void popupMenuWillBecomeVisible(PopupMenuEvent pme){
      theArea.append("-PopupMenu Visibel!\n");
    }
    public void popupMenuWillBecomeInvisible(PopupMenuEvent pme){
      theArea.append("-PopupMenu Invisibel!\n");
    }
    public void popupMenuCanceled(PopupMenuEvent pme){
      theArea.append("-PopupMenu Hidden!\n");
    }

    //当某个 JMenuItem 被触发后会在 JTextArea 中加入一个信息。
    public void actionPerformed(ActionEvent ae){
      theArea.append("+Popup "+ae.getActionCommand()+" performed!\n");
    }
   }//end of inner class PopupPanel
  }//end of class JPopupMenu1

  class SwingUtil{
    public static final void setLookAndFeel() {
      try{
        Font font = new Font("JFrame", Font.PLAIN, 12);
        Enumeration keys = UIManager.getLookAndFeelDefaults().keys();

        while (keys.hasMoreElements()) {
          Object key = keys.nextElement();
          if (UIManager.get(key) instanceof Font) {
            UIManager.put(key, font);
          }
        }
        AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");
        AlloyTheme theme = new GlassTheme();
        LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);
        UIManager.setLookAndFeel(alloyLnF);
      }catch(UnsupportedLookAndFeelException ex){
        ex.printStackTrace();
      }
    }
  }

   说明:(1):由于 JPopupMenu 只是一种 Menu 的组件,因此在使用 JPopupMenu 时我们都需要一个Container 来放置 JPopupMenu,在这里这们选择使用 JPanel 组件来作为 JPopupMenu 的 Container。

   (2):这个程序的运行结果可发现 JPopupMenu 只有在 JTextArea 下缘,也就是 JPanel 的部份才有作用,因为我们并没有在JTextArea中加入 addMouseListener() 方法,你可以在 PopupPanel() 构造函数中加入:

  theArea.addMouseListener(this);

  就能够解决在 JTextArea 上无法显示 JPopupMenu 的问题。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值