Ich muss in der Lage zu verfolgen, welche Komponente unter der Maus ist. In dem Legacy-Projekt, an dem ich gerade arbeite, wurde dies mit einem MouseListener mit den Triggern mouseEntered() und mouseExited() durchgeführt.Wie auslösen Maus eingeben und verlassen Ereignisse, wenn die Maus nicht bewegt
Dies gilt jedoch nicht zwei Grenzfälle abdecken
- Mauszeiger bewegt sich nicht, aber die Komponente unterhalb von der Anzeige entfernt wird
- Mauszeiger nicht bewegt, sondern eine neue Komponente wird unter dem Mauszeiger
Das bedeutet, dass Schaltflächen an anderer Stelle in der Anwendung, mit denen der Benutzer den Mauszeiger verknüpft hat, angezeigt werden, auch wenn die Komponenten, auf die sie sich beziehen, nicht mehr angezeigt werden. Normalerweise würde dies über den mouseExited() - Trigger bereinigt werden.
Mein bisher bester Versuch, ComponentListener und Hierarchielistener den Komponenten, die ich verfolgen möchte, hinzuzufügen und sie verwenden, um eine Überprüfung der Maus über sie mit button.getMousePosition() != null
auszulösen. Zusätzlich verwende ich dies, um synthetische MOUSE_ENTER- und MOUSE_EXIT-Ereignisse zu senden, so dass sich keiner der vorhandenen Legacy-Codes ändern muss.
Ich suche nach einer einfacheren Lösung, wenn eine existiert.
public class MouseTracker {
private static int clock;
public static void main(String[] args) {
JFrame frame = new JFrame();
Container content = frame.getContentPane();
JButton button1 = new JButton("one");
button1.setName("one");
Timer timer = new Timer(2000, (e) -> {
content.removeAll();
if (clock % 2 == 0) {
content.add(button1);
}
frame.revalidate();
frame.repaint();
clock++;
});
timer.setRepeats(true);
timer.start();
frame.setSize(200, 100);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
track(button1);
}
private static void track(JButton component) {
component.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse enter ");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Mouse exit ");
}
});
component.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent e) {
checkMouse(component);
}
@Override
public void componentHidden(ComponentEvent e) {
checkMouse(component);
}
@Override
public void componentResized(ComponentEvent e) {
checkMouse(component);
}
@Override
public void componentMoved(ComponentEvent e) {
checkMouse(component);
}
});
component.addHierarchyListener(new HierarchyListener() {
@Override
public void hierarchyChanged(HierarchyEvent e) {
checkMouse(component);
}
});
}
private static void checkMouse(JComponent component) {
Point mousePosition = component.getMousePosition();
if (component.isShowing() && mousePosition != null) {
System.out.println("Equivalent mouse enter " + component.getName());
component.dispatchEvent(new MouseEvent(component, MouseEvent.MOUSE_ENTERED, 0, 0, mousePosition.x,
mousePosition.y, 0, false));
} else {
System.out.println("Equivalent mouse exit " + component.getName());
component.dispatchEvent(new MouseEvent(component, MouseEvent.MOUSE_EXITED, 0, 0, 0, 0, 0, false));
}
}
}
Haben Sie einen 'AncestorListener' versucht? –
@CatalinaIsland Danke, nein, habe ich nicht, aber ja, ich kann sehen, wie es Beispiele geben könnte, wo dies erforderlich wäre, d.h. die Komponente bewegt sich unter der Maus, weil ihr Elternteil sich bewegt hat, aber das Ziel bleibt innerhalb seiner Elterngrenzen fixiert. – Adam