2016-12-22 1 views
0

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)); 
     } 
    } 
} 
+0

Haben Sie einen 'AncestorListener' versucht? –

+0

@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

Antwort

0

In Ermangelung anderer Vorschläge, kleben mit aktuellen vorgeschlagenen Lösung.

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)); 
    } 
} 
Verwandte Themen