0

我有一个代表一天的JTextField,例如“星期日”,当我左键单击它时,它会更改背景颜色,当我右键单击它时,会出现一个弹出菜单,单击菜单项后,例如“1st of month”,它获取值,关闭菜单然后更改bgcolor,我的代码如下所示:

    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();
...
    }

我的问题是:在 menuItem.addMouseListener 部分,如何获取启动此弹出菜单的原始 JTextField 事件,以便我可以将其传递给 onHeadingClicked() ?

4

4 回答 4

1

阅读 Swing 教程中有关如何使用菜单的部分以获取工作示例。MouseListener 仅用于显示弹出窗口,不处理菜单项的选择。您需要为每个菜单项添加一个 ActionListener 来处理选择。

在这种情况下,ActionEvent 将是菜单项。因此,您应该能够使用 ActionEvent 的 getSource() 方法来获取菜单项。然后可以使用 getParent() 方法来获取弹出菜单。最后,您可以使用 getInvoker() 方法来获取文本字段。就像是:

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

但是,更好的方法是使用 Action 创建菜单项。本教程还有一个关于“如何使用操作”的部分,其中包含解释和示例。在这种情况下,您将扩展 TextAction。现在,当调用 Action 时,您可以简单地使用 Action 的 getFocusedComponent() 方法来获取文本字段。就像是:

class SelectAll extends TextAction
{
    public SelectAll()
    {
        super("Select All");
    }

    public void actionPerformed(ActionEvent e)
    {
        JTextComponent component = getFocusedComponent();
        component.selectAll();
    }
}
于 2011-01-01T19:37:27.963 回答
0

您收到 ClassCastException 是因为 mouselistener 不在 JTextField 上,而是在 JMenuItem 上。它们是彼此不相关的 2 个不同的组件,因此 JMenuItem 不知道 JTextField '启动了它',因此除非您自己进行关联,否则您无法真正直接实现这一点。

你为什么不稍微改变你的类,而不是使用匿名适配器:

让你的类直接实现 MouseListener。

实现 MouseListener 接口的方法(主要是 mouseReleased()、mousePressed() 等)。那些你不感兴趣的把它们留空(你仍然需要声明它们)。

然后改变这个:

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() ?
      }
    });

对此:

menuItem.addMouseListener(this);

这样您就可以访问类中的所有组件,并且可以访问您的 JTextField 对象。

于 2011-01-01T18:48:03.310 回答
0

我想到了一个快速修复:

  MouseEvent Right_Click_Mouse_Event;

...
    menuItem.addMouseListener(new MouseAdapter()
    {
      public void mouseReleased(final MouseEvent e)
      {
        Out(((JMenuItem)e.getComponent()).getText());
        onHeadingClicked(Right_Click_Mouse_Event,((JMenuItem)e.getComponent()).getText());
      }
    });
...
      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());
            Right_Click_Mouse_Event=evt;
          }
        }
      });
...
  void onHeadingClicked(final java.awt.event.MouseEvent evt,String Order_In_Month)
  {
    final javax.swing.JTextField fld=(javax.swing.JTextField) evt.getSource();
...
  }

工作正常。

于 2011-01-01T19:25:30.677 回答
0

我是这样做的::

private void CommonMenuItemActionPerformed(java.awt.event.ActionEvent evt) {                                           
    JMenuItem menuItem = (JMenuItem)evt.getSource();         // source is clicked JMenuItem
    JPopupMenu popupMenu = (JPopupMenu)menuItem.getParent(); // get parent JPopupMenu
    Component component = popupMenu.getInvoker();            // who called JPopupMenu?
    System.out.println(component.getName());                 // get component name
}

为此,您需要命名具有 JPopupMenus 的组件

于 2016-02-19T10:00:04.503 回答