XJMenu.java
001 /*
002  *  Copyright (c) 1995-2012, The University of Sheffield. See the file
003  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
004  *
005  *  This file is part of GATE (see http://gate.ac.uk/), and is free
006  *  software, licenced under the GNU Library General Public License,
007  *  Version 2, June 1991 (in the distribution as file licence.html,
008  *  and also available at http://gate.ac.uk/gate/licence.html).
009  *
010  *  Valentin Tablan 20 Feb 2003
011  *
012  *  $Id: XJMenu.java 17612 2014-03-10 08:51:17Z markagreenwood $
013  */
014 
015 package gate.swing;
016 
017 import gate.event.StatusListener;
018 
019 import javax.swing.*;
020 import javax.swing.event.*;
021 import java.awt.event.MouseAdapter;
022 import java.awt.event.MouseEvent;
023 import java.awt.*;
024 
025 /**
026  * A modified version of JMenu that uses {@link MenuLayout} as its layout.
027  * Adds also a description and a StatusListener as parameters.
028  * The description is used in the statusListener.
029  */
030 @SuppressWarnings("serial")
031 public class XJMenu extends JMenu {
032   public XJMenu(){
033     super();
034     getPopupMenu().setLayout(new MenuLayout());
035   }
036 
037   public XJMenu(Action a){
038     super(a);
039     // stop showing tooltip in the menu, status bar is enough
040     setToolTipText(null);
041     getPopupMenu().setLayout(new MenuLayout());
042   }
043 
044   public XJMenu(Action a, StatusListener listener){
045     super(a);
046     this.description = (String)a.getValue(Action.SHORT_DESCRIPTION);
047     this.listener = listener;
048     // stop showing tooltip in the menu, status bar is enough
049     setToolTipText(null);
050     initListeners();
051     getPopupMenu().setLayout(new MenuLayout());
052   }
053 
054   public XJMenu(String s){
055     super(s);
056     getPopupMenu().setLayout(new MenuLayout());
057   }
058 
059   public XJMenu(String s, String description, StatusListener listener){
060     super(s);
061     this.description = description;
062     this.listener = listener;
063     initListeners();
064     getPopupMenu().setLayout(new MenuLayout());
065   }
066 
067   public XJMenu(String s, boolean b){
068     super(s, b);
069     getPopupMenu().setLayout(new MenuLayout());
070   }
071 
072   /**
073    * Force separators to be the same width as the JPopupMenu.
074    * This is because the MenuLayout make separators invisible contrary
075    * to the default JMenu layout manager.
076    @param aFlag true if the popupmenu is visible
077    */
078   @Override
079   public void setPopupMenuVisible(boolean aFlag) {
080     super.setPopupMenuVisible(aFlag);
081     if (!aFlag) { return}
082     MenuLayout layout = (MenuLayoutgetPopupMenu().getLayout();
083     for (int i = 0; i < getMenuComponents().length; i++) {
084       Component component = getMenuComponents()[i];
085       if (component instanceof JSeparator) {
086         JSeparator separator = (JSeparatorcomponent;
087         int column = layout.getColumnForComponentIndex(i);
088         int preferredWidth = layout.getPreferredWidthForColumn(column);
089         // use the popupmenu width to set the separators width
090         separator.setPreferredSize(new Dimension(
091           preferredWidth, separator.getHeight()));
092       }
093     }
094     getPopupMenu().revalidate();
095   }
096 
097   protected void initListeners(){
098     this.addMouseListener(new MouseAdapter() {
099       @Override
100       public void mouseExited(MouseEvent e) {
101         // clear the status
102         listener.statusChanged("");
103       }
104     });
105     this.addChangeListener(new ChangeListener() {
106       @Override
107       public void stateChanged(ChangeEvent e) {
108         // display the menu description in the status
109         listener.statusChanged(description);
110       }
111     });
112     this.addMenuListener(new MenuListener() {
113       @Override
114       public void menuCanceled(MenuEvent e) {
115         // do nothing
116       }
117       @Override
118       public void menuDeselected(MenuEvent e) {
119         // clear the status
120         listener.statusChanged("");
121       }
122       @Override
123       public void menuSelected(MenuEvent e) {
124         // do nothing
125       }
126     });
127   }
128 
129   protected StatusListener listener;
130   private String description;
131 }