从弹出菜单捕获鼠标XY位置

时间:2019-10-24 17:22:55

标签: java swing popup mouse

我能够捕获两个鼠标移动的XY坐标以及鼠标右键单击以打开弹出菜单的位置。

问题是如何从弹出菜单的顶部获取与JFrame相关的XY坐标。弹出窗口起源的XY位置与在弹出窗口上单击鼠标的位置不同。

我尝试将鼠标侦听器添加到JPopupMenu对象,但是它从未输入代码。

MousePopupListener看起来很有希望,但这也没有帮助。

以下示例实际上是将两个示例混在一起的。它应该在鼠标移动时显示XY坐标,以便在弹出菜单中可见XY,但是“图层”并不是一个强大的区域,我只能让鼠标XY显示或弹出菜单才能工作,但是不是都。

无论如何,我想做的是捕获在弹出菜单被调用时的XY坐标(可以完成),但是我还希望XY相对于从中选择项目时按下鼠标的帧的位置。弹出菜单。

需要添加什么来捕获该信息?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.border.BevelBorder;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class MousePopupExample extends JPanel {

  public JPopupMenu popup;

  public MousePopupExample()
  {
    popup = new JPopupMenu();
    ActionListener menuListener = new ActionListener() {
      public void actionPerformed(ActionEvent event) 
      {
        System.out.println("Popup menu item ["
            + event.getActionCommand() + "] was pressed.");
      }
    };
    JMenuItem item;
    popup.add(item = new JMenuItem("Left", new ImageIcon("1.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Center", new ImageIcon("2.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Right", new ImageIcon("3.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.add(item = new JMenuItem("Full", new ImageIcon("4.gif")));
    item.setHorizontalTextPosition(JMenuItem.RIGHT);
    item.addActionListener(menuListener);
    popup.addSeparator();
    popup.add(item = new JMenuItem("Settings . . ."));
    item.addActionListener(menuListener);

    popup.setLabel("Justification");
    popup.setBorder(new BevelBorder(BevelBorder.RAISED));
    popup.addPopupMenuListener(new PopupPrintListener());

    addMouseListener(new MousePopupListener());
  }


// An inner class to check whether mouse events are the popup trigger
  class MousePopupListener extends MouseAdapter 
  {
    public void mouseMoves(MouseEvent e) {
      checkPopup(e);
    }

    public void mousePressed(MouseEvent e) {
      checkPopup(e);
    }

    public void mouseClicked(MouseEvent e) {
      checkPopup(e);
    }

    public void mouseReleased(MouseEvent e) {
      checkPopup(e);
    }

    private void checkPopup(MouseEvent e) {
      if (e.isPopupTrigger()) {
        popup.show(MousePopupExample.this, e.getX(), e.getY());
      }
    }
  }

  // An inner class to show when popup events occur
  class PopupPrintListener implements PopupMenuListener {
    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
      System.out.println("Popup menu will be visible!");
    }

    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
      System.out.println("Popup menu will be invisible!");
    }

    public void popupMenuCanceled(PopupMenuEvent e) {
      System.out.println("Popup menu is hidden!");
    }
  }

  public static void main(String s[]) {
    JFrame frame = new JFrame("Popup Menu Example");
    XYMouseLabel xyMouseLabel = new XYMouseLabel();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MousePopupExample mpe = new MousePopupExample();

    xyMouseLabel.setBounds(0, 0, frame.getWidth(), frame.getHeight());    
    mpe.add(xyMouseLabel);

    frame.setContentPane(mpe);
    frame.setPreferredSize(new Dimension(400, 300));
    frame.pack();

    frame.addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseMoved(MouseEvent me)
        {
            System.out.println("Mouse Move");
          xyMouseLabel.x = me.getX();
          xyMouseLabel.y = me.getY();
          xyMouseLabel.repaint();
        }
      });

    frame.setVisible(true);
  }


}

1 个答案:

答案 0 :(得分:1)

JPopupMenu的子组件正在拦截鼠标事件。您需要同时在菜单及其子菜单中添加一个侦听器。

您可以使用SwingUtilities.convertMouseEvent将MouseEvent的坐标转换为相对于另一个组件(例如JFrame)的坐标:

   #include <iostream>
   #include <string>
   #include <vector>
   #include <list>
   #include <tuple>
   #include <iterator>

   using namespace std;

   class Bus {
   public:
    int StopsAmount;
    string BusNumber;
    vector<string> Stops;

    Bus(tuple<string, int, vector<string>> BusParams) {
        BusNumber = get<0>(BusParams);
        StopsAmount = get<1>(BusParams);
        Stops = get<2>(BusParams);
    }

    void ShowStops() {
        cout << BusNumber << ": ";
        for (int i = 0; i < StopsAmount; i++) cout << Stops[i] << " ";
        cout << "\n";
    }

    bool FindStop(string Stop) {
        for (int i = 0; i < StopsAmount; i++) {
            if (Stops[i] == Stop) {
                return true;
            }
        }
        return false;
            }
         };   

      class BusTraffic {
      public:
        BusTraffic() {
            while (true) {
                string Request;
                cin >> Request;
                switch (Request[0]) {
                case 'N': NEW_BUS(Request.substr(8, Request.length() - 8))      ;
                break;
            case 'B': BUSES_FOR_STOP(Request.substr(15, Request.length() - 15));
                break;
            case 'S': STOPS_FOR_BUS(Request.substr(14, Request.length() - 14));
                break;
            case 'A': ALL_BUSES();
                break;
            }
        }
    }

      private:
        list<Bus> BusList;

    void NEW_BUS(string Request) {
        BusList.push_back(Bus::Bus(SplitString(Request)));
    }

    void BUSES_FOR_STOP(string Stop) {
        cout << Stop << ": ";
        for (list<Bus>::iterator It = BusList.begin(); It != BusList.end(); It++) {
            if (It->FindStop(Stop)) {
                cout << It->BusNumber << " ";
            }
        }
        cout << endl;
    }

    void STOPS_FOR_BUS(string Name) {
        cout << Name << ": ";
        for (list<Bus>::iterator It = BusList.begin(); It != BusList.end(); It++) {
            if (It->BusNumber == Name) {
                It->ShowStops();
            }
        }
    }

    void ALL_BUSES() {
        if (BusList.size() > 0) {
            BusList.sort();
            for (list<Bus>::iterator It = BusList.begin(); It != BusList.end(); It++) {
                cout << It->BusNumber << ": ";
                It->ShowStops();
            }
        }
        else {
            cout << "No buses" << endl;
        }
    }

    // Converting string to information about bus
    tuple<string, int, vector<string>> &SplitString(string str) {
        tuple<string, int, vector<string>> BusParams;
        string Word = "";
        int WordNum = 0;

        for (auto Letter : str) {
            if (Letter == ' ') {
                if (WordNum == 0) get<0>(BusParams) = Word; 
                if (WordNum == 1) get<1>(BusParams) = stoi(Word);
                if (WordNum == 2) get<2>(BusParams).push_back(Word);
                Word = "";
                WordNum++;
            }
            else {
                Word = Word + Letter;
            }
        }
        get<2>(BusParams).push_back(Word);
        return BusParams;
        }
      };

      int main() {
        BusTraffic TestTraffic;
        return 0;
      }
相关问题