Как получить событие JTextField, которое запускает всплывающее меню в Java? - PullRequest
0 голосов
/ 01 января 2011

У меня есть JTextField, который представляет день, например, «Воскресенье», когда я щелкаю по нему левой кнопкой мыши, он меняет цвет фона, когда я щелкаю по нему правой кнопкой мыши, появляется всплывающее меню, после того как я нажимаю напункт меню, такой как «1-е число месяца», он получает значение, закрывает меню и затем изменяет цвет 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 ]

1 голос
/ 01 января 2011

Прочтите раздел из учебника по Swing на Как использовать меню для рабочих примеров.MouseListener используется только для отображения всплывающего окна, а не для обработки выбора пункта меню.Вам необходимо добавить ActionListener для каждого элемента меню, чтобы обработать выбор.

В этом случае ActionEvent будет пунктом меню.Следовательно, вы должны иметь возможность использовать метод getSource () ActionEvent, чтобы получить пункт меню.Затем вы можете использовать метод getParent (), чтобы получить всплывающее меню.Наконец, вы можете использовать метод getInvoker () для получения текстового поля.Что-то вроде:

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

Тем не менее, лучшим подходом является создание элемента меню с помощью действия.В руководстве также есть раздел «Как использовать действия», который содержит объяснение и пример.В этом случае вы бы расширили TextAction.Теперь, когда Action вызывается, вы можете просто использовать метод getFocusedComponent () Action, чтобы получить текстовое поле.Что-то вроде:

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

    public void actionPerformed(ActionEvent e)
    {
        JTextComponent component = getFocusedComponent();
        component.selectAll();
    }
}
0 голосов
/ 19 февраля 2016

Я сделал это так:

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

0 голосов
/ 01 января 2011

Я подумал о быстром исправлении:

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

Работает нормально.

0 голосов
/ 01 января 2011

Вы получаете ClassCastException, потому что слушатель мыши находится не в JTextField, а в JMenuItem. Это два разных компонента, не связанных друг с другом, поэтому 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.

...