I have read that that a event created by a component(like a button) is handled by a action listener(for a button) but one of my teacher says that every event is handled by the operating system so I am confused to as who actually handles the event, is it the operating system or does java do that work.
I think the two instances of the word handle here mean quite different things.
Your code handles events that are raised. So imagine the button says "Oh I've been clicked!" and you go "Right, I'll handle it!" and you do this by doing something like this:
button.addActionListener(e -> {...});
The OS handles the raising of events. Your mouse pointer is not part of your program, right? So the OS will detect where your mouse pointer is when a "The left mouse button has been clicked" signal is sent to the OS. The OS will say "The mouse pointer is located at this position on the screen, and there is a button there. That means that the button should be clicked. Hey! that button over there! The user clicked on you at (someX, someY)!". And then the JButton class will first try to animate a click animation and raise the "action performed" event.
Certain types of events occur as a direct result of user input. When the user types a key or moves the mouse, for example, a KeyEvent or MouseEvent is generated. Similarly, when the user resizes a window or transfers keyboard focus to a new component, a FocusEvent or ComponentEvent is generated. These types of events represent event notifications generated by the underlying native windowing system or operating system. Other types of events, such as ActionEvent and PopupMenuEvent, do not originate in the native windowing system. Instead, these events are generated directly by AWT and Swing components
Related
I'm having trouble understanding the difference between the 2 methods in the SWT SelectionListener. The javadoc is as follows:
void
org.eclipse.swt.events.SelectionListener.widgetSelected(SelectionEvent
e)
Sent when selection occurs in the control.
For example, selection occurs in a List when the user selects an item
or items with the keyboard or mouse. On some platforms, the event
occurs when a mouse button or key is pressed. On others, it happens
when the mouse or key is released. The exact key or mouse gesture that
causes this event is platform specific.
void
org.eclipse.swt.events.SelectionListener.widgetDefaultSelected(SelectionEvent
e)
Sent when default selection occurs in the control.
For example, on some platforms default selection occurs in a List when
the user double-clicks an item or types return in a Text. On some
platforms, the event occurs when a mouse button or key is pressed. On
others, it happens when the mouse or key is released. The exact key or
mouse gesture that causes this event is platform specific.
It sounds to me like widgetSelected() is called when the user selects a widget in any way. The widgetDefaultSelected() is called when the user is finished interacting with the widget. For a Text widget, that would be pressing Enter; for a List, that would be double clicking on a list item; and for a Date, that would be pressing Enter.
Is this understanding correct?
Your general understanding is correct, though the term 'finished' might not be 100% accurate in all situations.
Widgets that send (default) selection events document the particular details in the JavaDoc of their respective addSelectionListener method. There you can read if and when widgetSelected and/or widgetDefaultSelected is sent.
If you look into the Link::addSelectionListener JavaDoc for example, you will see that widgetDefaultSelected() is never called.
Is there a Mouse equivalent class for KeyStroke? I'm looking for some kind of wrapper around a a MouseEvent to describe which button was pushed (I can get this through SwingUtilities), and any modifiers used as well. The idea is I'm already catch AWT mouse events through a listener, but then taking that event and processing it for 3D picking in a virtual world. I'd like to try and map mouse bindings in such a way (similar to InputMap and ActionMap with swing controls). KeyStroke has been a god-send, anyone know of a MouseStroke or similar?
A "mouse" is traditionally defined as having a maximum of three buttons. That is also what Java supports by MouseEvent.getButton().
More advanced mice with multiple buttons are usually installed as multiple HID devices. Meaning they install two drivers, for a mouse AND for a keyboard. For these mice, you can set what other buttons mean, and usually it's something like a key press (for example, shift) or double click. Those are events that Java can catch, either as MouseEvent of KeyEvent.
More advanced functionality, such as "Open an application" or "change DPI", is implemented in the driver. Being device-specific, there is nothing Java can do to catch those events (you would have to write your own native listener for these events, provided the driver support that).
I have an application in which you can do a right mouse button press and drag (as well as a left press and drag for different operations). However, when running this on linux, it seems that popup menus are triggered by a mousePressed and not a mouseReleased. This is resulting in every time I press the right mouse button to perform a drag, the popup menus are triggered (unlike windows, where it is mouseReleased).
Any thoughts on how to work around this?
thanks.
EDIT: Posting code
Code for popup menu
// this is called from mousePressed and mouseReleased
if (e.isPopupTrigger() && !e.isConsumed()) {
// show the popup menu
}
This code is what is called on the right mouse press/drag (this is 3rd party code, but it is open source so I can change as needed)
// this is called on all mouse events
if (buttonAction.mouseButton != 0)
{
// handle the event
}
Yes, use isPopupTrigger(), as shown here.
Addendum:
it appears isPopupTrigger is triggered on mousePressed in linux.
Yes, it's the same on Mac OS X. You have to call isPopupTrigger() from both mousePressed() and mouseReleased(). There's a related example in GraphPanel.
MouseEvent.isPopupTrigger(). Returns whether or not this mouse event is the popup menu trigger event for the platform.
edit - : You need to make the check in both mousePressed for linux, and mouseReleased for windows.
I think the correct procedure in your case should be to unify where and when to show the popup. As a drag event, if exist, follows a press event you should avoid writting logic for showing the popup in the press event (and then also write logic in the press event for showing the popup). Some users feel good navigating the popup while holding the popup button, and some other users just don't care or don't know. But in your case, you won't be able to navigate the popup menu while dragging without adding extra code.
My way would we to manage the logic to always show the popup on the release event. Entering a release event after a drag should be enough information to know that the popup shouldn't be visible. And of course, always if you can change and modify the source.
I writing an application which controls another application by using the keyboard only. To more concrete, the application simulates key presses and mouse clicks when a certain key is pressed on the keyboard. For example, pressing on the 'x' key simulates a mouse click on the [X] in the rop right corner, followed by a little sleep of 2 seconds and an 'enter' to confirm the exit dialog. Pretty easy. I am developing this application in Java.
Sending a key press or a mouse click is very easy with java.awt.Robot. I am facing one little problem. Say I have configured a key which will click somewhere on the screen. The problem is that consecutive key presses aren't catched anymore, as my application lost its focus caused by the mouse click outside it's window.
My question now is: what is the best way to be sure that my main application keeps the focus? Is there a way to focus my application again after the key presses and mouse clicks are sent out? Is there a better way?
Thanks in advance.
If your application lost the focus. because you or your Robot clicked to somwhere else, the Robot must click on the application again before sending a new key. In c/c++ you could force the focus to the application (a non-trivial task), not in Java!
You might want to take a look at Component.requestFocus() to see if can do what you want.
Be aware however that window focusing has very platform dependent behaviour, so you will probably need to do quite a bit of testing to ensure that your code does what you want in all circumstances.
I managed a way to prevent applications from losing all focus in Java.
By placing a WindowFocusListener on the frame (or dialog) and calling setVisible(false) followed by setVisible(true) in windowLostFocus the component will re-appear as soon as it is dissapears (not the prettiest solution but it does work).
By then calling component.requestFocus() your robot should be able to continue where it left off
I'm experiencing some strange behaviour when using a stylus with swing.
I am interpreting pressing the button on the side of the stylus(RIGHT) and pressing the stylus down(LEFT) as a "Grab" event, but occasionally (more often than 0), events are just being dropped.
The JavaDocs for MouseEvent are pretty explicit about how multibutton presses are handled if executed one at a time (left down, right down, right up, left up) but say nothing about simultaneous button presses.
I'm left to wonder, would they be emitted as two mousePressed events, or as one with the button mask set for both buttons, or something else entirely?
Thanks.
I'd interpret the API doc as simultaneous button presses being simply not possible:
When multiple mouse buttons are pressed, each press, release, and click results in a separate event.
So there should be separate events. The problems you observe could be due to errors in your code, the stylus' driver, the hardware, or Swing (this is in decreasing order of likelihood as I see it :)
I'd try to diagnose the problem by logging events at different levels, if possible.
Simultaneous button presses are processed as two separate mousePressed events. Run the Mouse Events Demo to see them processed separately.
As I recall, there's no way to handle simultaneous button presses. What I used to do to ensure that multiple buttons being pressed at once were treated as such was I would have a boolean variable for each button and when it was pressed, I would set it to true and when it was released, I would set the boolean to false. Then when it came time to perform an action, I would check for the boolean variables (sometimes I would have the actionlistener redirect to the method call for determining what action was to happen next after setting the booleans). This doesn't work if the only thing you want to do is them being pressed at the exact same time, but if you're just trying to get combinations to work, then that's how I did it. This was about 4 years ago, before Java 5, so I may be wrong about that.