Section 17.9. Component-Managed Pop-ups


17.9. Component-Managed Pop-ups

Things get a bit easier in Java 5.0, using the new pop-up menu API for components. In Java 5.0, any JComponent can manage a JPopupMenu directly with the setComponentPopupMenu( ) method. JComponents can also be told to simply inherit their parent container's pop-up menu via the setInheritsPopupMenu( ) method. This combination makes it very simple to implement a context menu that should appear in many components within a container.

Unfortunately, this doesn't lend itself well to our previous example (PopupColorMenu) for two reasons. First, we need to know which component the mouse was in when the pop-up was triggered and we don't get that information using this API. The pop-up handling is actually delegated to the container, not inherited. Second, not all types of components are registered to receive mouse events by default.[*] As a result, we'll create a new example that is more appropriate for a "one context menu to rule them all" application. The following example, ContextMenu, shows a TextArea and TextField that both inherit the same JPopupMenu from their JPanel container. When you select a menu item, the action is displayed in the text area.

[*] Components such as JPanel and JLabel by default do not expect to handle mouse events. When you register a listener such as MouseListener, it registers itself internally to begin processing these events. Unfortunately, at the time of this writing, using setInheritsPopupMenu( ) does not trigger this functionality. As a workaround, you could register a dummy mouse listener with these components to prompt them to expect mouse events and properly trigger context menus if you want them.

     import java.awt.*;     import java.awt.event.*;     import javax.swing.*;     public class ContextMenu implements ActionListener     {       JTextArea textArea = new JTextArea(  );       public ContextMenu(  )       {         final JPopupMenu contextMenu = new JPopupMenu("Edit");         contextMenu.add(makeMenuItem("Save"));         contextMenu.add(makeMenuItem("Save As"));         contextMenu.add(makeMenuItem("Close"));         JFrame frame = new JFrame("ContextMenu v1.0");         JPanel panel = new JPanel(  );         panel.setLayout( new BorderLayout(  ) );         frame.add( panel );         panel.setComponentPopupMenu( contextMenu );         textArea.setInheritsPopupMenu( true );         panel.add( BorderLayout.CENTER, textArea );         JTextField textField = new JTextField(  );         textField.setInheritsPopupMenu( true );         panel.add( BorderLayout.SOUTH, textField );         frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );         frame.setSize(400,200);         frame.setVisible(true);       }       public void actionPerformed( ActionEvent e ) {         textArea.append( e.getActionCommand(  ) +"\n" );       }       private JMenuItem makeMenuItem(String label) {         JMenuItem item = new JMenuItem(label);         item.addActionListener( this );         return item;       }       public static void main(String[] args) {          new ContextMenu(  );       }     } 

We've constructed our JPopupMenu as before, but this time we are not responsible for listening for mouse clicks or triggering the pop-up explicitly. Instead we use the setComponentPopupMenu( ) method to ask the JPanel to handle it for us. We use setInheritsPopupMenu( ) on both the JTextArea and JTextField so that they will both delegate pop-up trigger mouse clicks to the JPanel automatically.



    Learning Java
    Learning Java
    ISBN: 0596008732
    EAN: 2147483647
    Year: 2005
    Pages: 262

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net