I have a working JPanel extended class that handles all the mouse and keyboard events. I put that panel into a JSplitPane with another JPanel. Now none of my mouse and keyboard events are firing off in my original JPanel.
My theory is that the JPSplitPane now takes the events. Is there a way to easily make it so those events are passed down to my JPanel just like before?
Upon my research I found out that the mouse events are handled by the first possible MouseListener (in this case the JSplitPane) so all I had to do was this...
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftColumn, analyzerPanel);
splitPane.addMouseListener(analyzerPanel);
splitPane.addMouseMotionListener(analyzerPanel);
splitPane.addMouseWheelListener(analyzerPanel);
splitPane.addKeyListener(analyzerPanel);
Related
I made a JPanel with a mouse listener, a mouse motion listener and a scroll listener. And I have a JFrame that switches between JPanels like so:
//tile is a JPanel
//"this" is a JFrame
tile.removeAll();
tile=tree.getCurrentNode().getContent().panel;
this.add(tile);
this.revalidate();
tile.requestFocus();
Now when I switch out the old JPanel for the one with mouse listeners some weird things start to happen. The mouse listener and the scroll listener still work but the mouse motion listener doesn't get called anymore. I even get a nullpointer exception when I try getMousePosition() from within the JPanel.
I have a GUI.
This GUI class extends JFrame.
In top of the screen there is a JLabel with some text.
In the center of the screen there is a JPanel, and n x n JButtons were added to this JPanel.
I need a KeyListener to react if I press a key.
For what component (JFrame, JLabel, JPanel, JButtons) should I add the KeyListener to work my program normally?
The JFrame would be the smartest choice given that it is a top level ancestor you would be able to avoid focus problems. However, if you say you were to implement a JTextField it would then be necessary to add the keylistener to the JTextField because focus is drawn away from parallel components in order to consume the ability to type into the field.
For what component should I add KeyListener?
you can to use Keylistener for (is designated)
prehistoric AWT Component (Swing based on AWT)
for more than 3 keyPressed in the same time or to determine the order
but then is for Swing JComponents
better to use KeyEventDispatcher or AWTEventListener (both react to singnals from keyboard)
otherwise use KeyBindings (e.g. Swing JComponents uses KeyBindings internally)
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.
I want to be notified of mouse events (specifically the mouse entered and exited events) on my JFrame. But when i add a mouselistener to it i get the events on the borders of the frame not the entire frame with it's contents.
Any ideas as to why?
EDIT : Or at least do you have an alternative? I want a "gloabal" way to catch mouse events on the JFrame. Maybe a mouselistener is not the answer.
You can get all events and check if their source is a component in the JFrame.
See Toolkit.addAWTEventListener
There is an invisible component that overlays the whole GUI, the "glass pane". You can attach your listeners to that. Example:
JFrame frame = new JFrame();
Component glassPane = frame.getGlassPane();
glassPane.addMouseListener(myListener);
If you want your intercepted events to pass through to the underlying components, you can redispatch them. For example:
public void mouseMoved(MouseEvent e) {
redispatchMouseEvent(e, false);
}
Because the contents ( probably a JPanel ) are "shadowing" and consuming the events and they don't reach the JFrame.
What you can do is to add the same listener to all the children. There should be a better way though.
An alternative to AWTEventListener is to push an EventQueue. This has the advantage that applets and WebStart application can do this.
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.