Java GUI Mouse Listener - java

could you guys help me out.
How do we order the process of Mouselistener?
I mean, I want my mouseEntered and mouseExited working after I click on my one of my JPanel.

If I understand your question, you want to enable a MouseMotionListener only after a component is clicked...
Basically, in your MouseListener's mousePressed method, you would simply add your MouseMotionListener
Now remember, mouse listeners consume events, that is a child component will hide mouse events that occur on it from it's parent container
Take a look at How to write mouse listeners for more details

Related

Ignore mousePressed

I have a mouseListener on my Component and I need do the action on mousePressed in any case except one: if the focus is on another window and user clicks on my Component.
How can I ignore the mousePressed for Component if the focusOwner was another window before MouseEvent was fired? The FocusListener.focusGained and checking the focusOwner at the click moment can't help.
UPD: My task is to detect the case when focusGained fired on cause of mousePressed.
Use a WindowListener and handle the windowActivated and windowDeactivated events to register/deregister your MouseListener.
You may need to place the adding of the MouseListener in a SwingUtilities.invokeLater() to make sure the listener is added after the window has focus.
I had a similar Problem.
If you implement and register FocusListener you can ask in the focusGained method FocusEvent.getOppositeComponent() and detect if the user has changed the window. After that you can register the Mouslistener and unregister it in the focusLost method.

JPanel does not generate MouseEvents when cursor is on child components

It is a bit strange for me but JPanel does not generate MouseEvents when cursor is on child components: JTextField and JToolBar but it generates MouseEvents when cursor is on JLabel. Could someone explaind me why? Is there any way to force JPanel to generate events even if mouse is on child components?
The event dispatcher will forward mouse events to the listeners registered to the component that is returned by the package-level getMouseEventTarget method in Container. This will be called on your JFrame, and, as the JavaDoc indicates, it:
Fetchs the top-most (deepest) lightweight component that is interested in receiving mouse events.
The event dispatcher then takes this top-most component (your JTextField, for example) and sends events to all of its listeners only. They do this in order to avoid having to broadcast these events to all of the components that may be layered within a Swing container. MouseEvents, as you can imagine, are very chatty, what with all of the mouseEntered, mouseDragged, and mouseMoved events that are dispatched for all of the MouseListener and MouseMotionListener implementations potentially out there. The processing to find all listeners and then fire events to all of them in the hierarchy would be time consuming.
The assumption is also that for classes like JTextField and JButton, etc., the default mouse handling is all that one would need. If you want to handle mouse actions differently (ie, changing color on a mouseEntered/mouseExited), you can add a MouseListener to these widgets as you need to.
For your processing, I would suggest simply adding your JPanel as a MouseListener to your top level components if you need to handled these events.
you may want to have the child components (JTextField, JToolBar, etc) listen for the mouse events from the jpanel and/or forward the mouse events to the child components.
Could someone explain why?
Component mouse events are handled by processMouseEvent(), which says
Mouse events are enabled when one of the following occurs:
A MouseListener object is registered via addMouseListener.
Mouse events are enabled via enableEvents.
You can use getMouseListeners() to see the difference.

How can I capture all mouse events in a JFrame/Swing?

I have a JFrame that has a large number of changing child components. (Many layers) Is there any way to add a listener for all mouse events? Something like KeyEventDispatcher?
Use an AWTEventListener to filter out the MouseEvents:
long eventMask = AWTEvent.MOUSE_MOTION_EVENT_MASK + AWTEvent.MOUSE_EVENT_MASK;
Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener()
{
public void eventDispatched(AWTEvent e)
{
System.out.println(e);
}
}, eventMask);
You could add a GlassPane over your entire JFrame, add a MouseInputAdapter to it to grab all possible mouse events, and then use [SwingUtilities.getDeepestComponentAt()][3] to get the actual component and [SwingUtilities.convertMouseEvent()][4] to delegate the mouse event from the glass pane to the actual component.
However, I'm not sure of the performance impact of this - unlike KeyEventDispatcher, which just needs to fire an event whenever a key is pressed, multiple events are generated as the user moves the mouse - and unlike KeyEventDispatcher, you need to re-send the event to the lower component for it to handle it.
(Sorry - stackoverflow isn't handling the links to the SwingUtilities methods correctly... links are showing below rather than in the text.)
[3]: http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SwingUtilities.html#getDeepestComponentAt(java.awt.Component, int, int)
[4]: http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SwingUtilities.html#convertMouseEvent(java.awt.Component, java.awt.event.MouseEvent, java.awt.Component)
You have to use JFrame's glassPane:
http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JFrame.html#getGlassPane()
Just get the glass pane of a JFrame with frm.getGlassPane() and use addMouseListener() on it to capture all mouse event inside the window.
Implement all mouse-related listeners in a class, and register that class as the handler for all mouse related events
Mouse Related interfaces would be
MouseListener
MouseMotionListener
MouseWheelListener
You might want to implement a subclass of MouseAdapter, an abstract class that provides empty implementations of all of the methods defined in the Mouse*Listener Interfaces. Once you do that, you can register it with your child components as a MouseListener when they are created. As you indicate that your components are 'changing,' you will want to make sure the you also unregister your listener if you hope to release your components during the lifecycle of your JFrame.

Swing: Adding listener to a component and ALL its decoration?

Can I add a listener (let's say MouseAdapter) to a Swing component
and all it's internal decoration components?
So that when a JInternalFrame is moved by the mouse
(by dragging its window title bar), it would give me following events:
mousePressed event,
mouseDragged event,
mouseReleased event.
Currently, I receive none of the above events when dragging
JInternalFrame.
I hope there is some standardized solution, but I couldn't find any.
EDIT:
Some people suggest using ComponentListener, but that wouldn't do for
me. I need to know, when the user stops dragging (mouseReleasedEvent),
not when the component moves.
Yes, you can add a listener to all a container's components. getComponents and add the listener. You should be able to manage to do this recursively. You can also use ContainerListener to check for adding and removing components.
However, MouseListener and MouseMotionListener behave strangely in that the event normally bubbles up to the parent, but does not do so if a listener is present (how is that for hopeless design?).
Your choices are:
Recursively adding listeners (bad, see above)
Adding listeners to specific components (fragile)
Adding a "glass pane" (a messy hack)
Adding an AWTEventListener to Toolkit (requires permissions)
Pushing an EventQueue and checking through events (doesn't work of Opera and Safari apparently; stops system copy-and-paste and applet dragging from working)
Use ComponentListener?
I found out how it could be done, but something tells me, it's a dirty hack ;)
Well, it works, but who can give me the guarantee that it works everywhere?
// ctor goes here {
InternalFrameUI thisUI = getUI();
((BasicInternalFrameUI) thisUI).getNorthPane()
.addMouseMotionListener(new MyMouseListener());
// }
NorthPane turns out to be the window title bar.
You should probably use a MouseMotionListener instead of a MouseListener.
In the JInternalFrame API documentation, it says:
Generally, you add JInternalFrames to
a JDesktopPane. The UI delegates the
look-and-feel-specific actions to the
DesktopManager object maintained by
the JDesktopPane.
Maybe you should add your listener to the JDesktopPane.
MouseListener/MouseMotionListener wont detect when dragging a JInternalFrame. Your best bet here to detect movement is using a ComponentListener on the JInternalFrame itself.

Detect Mouse Move Event On JPanel

I have a JPanel, which I would like to detect the following events
(1) When the mouse move in
(2) When the mouse move out
The (1) is quick easy. (2) is a bit tricky. Currently, I have to register event at all the components around JPanel. If the neighbor around JPanel detected a mouse move in event, this also means that JPanel is having (2) situation. However, this is a rather dirty away, as I add in new components in the future, this dirty workaround will break.
Another method is to have a timer to monitor the JPanel. If the mouse position is not within JPanel within x seconds, I can consider JPanel is having mouse move out event.
However, this seem a dirty way to me too, as having a separate timer to perform such common task is overkill.
Is there any better way, which Java platform may provide?
Have your class implement MouseListener and add it as a mouse listener on the outermost panel. You should get a mouse-entered event when the mouse moves over the panel, and mouse-exited when it leaves; regardless of whatever components the panel contains.
From the JavaDoc:
void mouseEntered(MouseEvent e)
Invoked when the mouse enters a component.
void mouseExited(MouseEvent e)
Invoked when the mouse exits a component.

Categories