Básicamente hay un JPanel en el que quiero saber cuando el mouse ingresa al área de JPanel y sale del área de JPanel. Así que agregué un detector de mouse, pero si hay componentes en el JPanel y el mouse pasa sobre uno de ellos, se detecta como una salida en el JPanel, aunque el componente esté en el JPanel. Me preguntaba si alguien sabe alguna forma de resolver este problema sin hacer algo como agregar oyentes en todos los componentes en el JPanel.Detectando eventos de entrada/salida de mouse en cualquier parte de JPanel
Respuesta
Si desea enviar todo el evento a una ventana de nivel superior, puede agregar un oyente al panel de cristal del JFrame. Ver: http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/RootPaneContainer.html#getGlassPane%28%29
La pregunta era sobre un JPanel, no el JFrame Puede responder la pregunta, pero solo parcialmente, por lo que la respuesta no es adecuada para un novato. PD: incluso en 2010, creo que es un mejor enlace a Java 1.6 documentos. – PhiLho
Aquí es una manera de hacerlo para un componente que puede contener otros componentes:
Añadir un detector de eventos AWT mundial para obtener todos los eventos del ratón. Por ejemplo:
Toolkit.getDefaultToolkit().addAWTEventListener( new TargetedMouseHandler(panel), AWTEvent.MOUSE_EVENT_MASK);
implementar el
TargetedMouseHandler
ignorar eventos que no son de origen por el panel o por uno de los niños del panel (que puede utilizar para probarSwingUtilities.isDescendingFrom
para esto).Mantenga un registro de si el mouse ya está dentro de los límites de su panel. Cuando obtiene un evento
MouseEvent.MOUSE_ENTERED
en su panel o uno de sus elementos secundarios, establezca un indicador en verdadero.Cuando obtiene un evento
MouseEvent.MOUSE_EXITED
, solo restablezca el indicador si el punto en elMouseEvent
está fuera de los límites de su panel de destino.SwingUtilities.convertPoint
yComponent.getBounds().contains()
serán útiles aquí.
Intenté implementar tu idea (para tener un controlador global con el botón derecho del ratón (menú contextual) en un panel con componentes), pero descubrí que es realmente global, es decir. en todo el nivel de la aplicación, lo que podría ser molesto con los marcos internos como lo tenemos, y debemos eliminar el controlador al cerrar el marco interno correspondiente. Sigue siendo una respuesta interesante e informativa, que puede ser adecuada para casos más simples. – PhiLho
Este es un código de ejemplo que implementa la solución de Ash. Para mí, el JFrame no detectó todos los eventos de salida correctamente, pero sí un JPanel interno, así que pasé dos componentes: uno para probar descendientes y otro para probar el límite.
Toolkit.getDefaultToolkit().addAWTEventListener(
new TargetedMouseHandler(this, this.jPanel),
AWTEvent.MOUSE_EVENT_MASK);
}
public class TargetedMouseHandler implements AWTEventListener
{
private Component parent;
private Component innerBound;
private boolean hasExited = true;
public TargetedMouseHandler(Component p, Component p2)
{
parent = p;
innerBound = p2;
}
@Override
public void eventDispatched(AWTEvent e)
{
if (e instanceof MouseEvent)
{
if (SwingUtilities.isDescendingFrom(
(Component) e.getSource(), parent))
{
MouseEvent m = (MouseEvent) e;
if (m.getID() == MouseEvent.MOUSE_ENTERED)
{
if (hasExited)
{
System.out.println("Entered");
hasExited = false;
}
} else if (m.getID() == MouseEvent.MOUSE_EXITED)
{
Point p = SwingUtilities.convertPoint(
(Component) e.getSource(),
m.getPoint(),
innerBound);
if (!innerBound.getBounds().contains(p))
{
System.out.println("Exited");
hasExited = true;
}
}
}
}
}
}
hay una solución muy fácil para este problema que puede trabajar:
public class MyJPanel implements MouseListener {
public void mouseExited(MouseEvent e) {
java.awt.Point p = new java.awt.Point(e.getLocationOnScreen());
SwingUtilities.convertPointFromScreen(p, e.getComponent());
if(e.getComponent().contains(p)) {return;}
...//the rest of your code
}
...
}
De esta manera usted solo ignora el evento mouseExited cuando se presenta en un elemento secundario.
- 1. MouseListener para JPanel mouse missing Eventos clonados
- 2. Evento de mouse movido dentro de JPanel
- 3. Eventos de Mouse Moved Global en Cocoa
- 4. Eventos de movimiento de mouse en NCurses
- 5. Android detectando el estado táctil desde cualquier aplicación
- 6. Ignorar eventos de mouse en cola
- 7. ¿Puedo obtener eventos de mouse en QGraphicsItem?
- 8. JavaScript mapping eventos táctiles a eventos de mouse
- 9. Detectando mouse clic en div con Javascript sin efectos secundarios
- 10. Eventos globales del mouse
- 11. Eventos de mouse Java ignorados cuando el mouse se mueve?
- 12. Manejo de eventos del mouse con cvSetMouseCallback
- 13. Detectando cuando el mouse no se mueve
- 14. Custom NSView en NSMenuItem que no recibe eventos de mouse
- 15. propagar eventos de mouse a elementos ocultos
- 16. Javascript: múltiples eventos de mouse desencadenados
- 17. Controlador global de eventos del mouse
- 18. Enviar eventos de mouse y teclado
- 19. Detectando CTRL + Clic para la celda de DataGridView en el mismo controlador de eventos
- 20. Manejo de eventos de mouse en la ventana transparente condicionalmente
- 21. Capturar eventos de mouse de cada componente en C# WInForm
- 22. mapeo de Safari de iPad de eventos de mouse para tocar eventos en image-maps
- 23. Java la propagación de eventos detenido
- 24. JPanel transparente
- 25. Mover el mouse de Java en cualquier lugar de la pantalla
- 26. Comportamiento de Gain PanningMode de ScrollViewer con eventos de mouse
- 27. Reenvío de eventos de mouse a través de layers/divs
- 28. Cargando varios videos de Vimeo con jQuery y detectando eventos
- 29. JPanel Padding en Java
- 30. ¿Cómo deshabilitar los eventos de mouse en los widgets dijit.form.NumberSpinner?
Las respuestas en esta pregunta son aplicables a su problema: http://stackoverflow.com/questions/1882055/java-swing-change-background-color-on-mouse-over – Ash