Search code examples
javaeventsswingpopupjtextfield

How to get a JTextField event that started a pop up menu in Java?


I have a JTextField that represents a day, such as "Sunday", when I left mouse click on it, it changes background color, when I right mouse click on it, a pop up menu comes up, after I click on a menu item, such as "1st of month", it gets the value, closes the menu and then change the bgcolor, my code looks like this :

    JTextField dayHeading=new JTextField("Su");
......
    final JPopupMenu Pmenu;
    JMenuItem menuItem;
    Pmenu=new JPopupMenu();
    menuItem=new JMenuItem("1st of month");
    Pmenu.add(menuItem);
    menuItem=new JMenuItem("2nd of month");
    Pmenu.add(menuItem);
......
    menuItem.addMouseListener(new MouseAdapter()
    {
      public void mouseReleased(final MouseEvent e)
      {
        System.out.println(((JMenuItem)e.getComponent()).getText());
        onHeadingClicked(e);  // Error : java.lang.ClassCastException: javax.swing.JMenuItem cannot be cast to javax.swing.JTextField
                              // How to get the orininal JTextField event that started this pop up menu, so I can pass it onto  onHeadingClicked() ?
      }
    });
......
    dayHeading.setEditable(false);
    dayHeading.setFocusable(false);
    dayHeading.addMouseListener(new MouseAdapter()
    {
        public void mouseReleased(final MouseEvent evt)
        {
          if (SwingUtilities.isLeftMouseButton(evt)) onHeadingClicked(evt);
          else if (SwingUtilities.isRightMouseButton(evt)) Pmenu.show(evt.getComponent(),evt.getX(),evt.getY());
        }
    });

......
    void onHeadingClicked(final java.awt.event.MouseEvent evt)
    {
      final javax.swing.JTextField fld=(javax.swing.JTextField) evt.getSource();
...
    }

My question is : in the menuItem.addMouseListener section, how to get the orininal JTextField event that started this pop up menu, so I can pass it onto onHeadingClicked() ?


Solution

  • Read the section from the Swing tutorial on How to Use Menus for working examples. The MouseListener is only used to display the popup, not handle the selection of the menu item. You need to add an ActionListener to each menu item to handle the selection.

    In this case the ActionEvent will be the menu item. Therefore you should be able to use the getSource() method of the ActionEvent to get the menu item. Then you can use the getParent() method to get the popup menu. Finally you can use the getInvoker() method to get the text field. Something like:

    JMenuItem mi = (JMenuItem)e.getSource();
    JPopupMenu popup = (JPopupMenu)mi.getParent();
    JTextField tf = (JTextField)popup.getInvoker();
    

    However, a better approach is to create your menu item using an Action. The tutorial also has a section on "How to Use Actions", which contains an explanation and example. In this case you would extend TextAction. Now when the Action is invoked you can simply use the getFocusedComponent() method of the Action to get the text field. Something like:

    class SelectAll extends TextAction
    {
        public SelectAll()
        {
            super("Select All");
        }
    
        public void actionPerformed(ActionEvent e)
        {
            JTextComponent component = getFocusedComponent();
            component.selectAll();
        }
    }