我能够捕获两个鼠标移动的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);
}
}
答案 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;
}