How are multi-button presses handled in swing? - java

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.

Related

Who handles a event created by a component in java

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

Same Jbutton selected state across multiple instances of same JPanel?

I have a toggle JButton that, when clicked, either installs or uninstalls some listeners elsewhere (but that's somewhat irrelevant I believe, as it could be just about any code that you don't want executed any number of times in a row, hence, the toggle, you click it once, it does something, you click it again, it undoes that something or whatever). My problem is that I have several instances of this button (or more specifically, several instances of its parent JPanel). This restriction is not my doing and I cannot prevent this. Basically, I'm left with a situation where the user can toggle the button "on" a bunch of times in succession, and needless to say, this screws things up for me.
The buttons themselves are not all visible to the user at once, only one can be seen at any given time. I tried using a component listener, but componentHidden() and componentShown() are never called.
I tried making the button a singleton, but that just had this weird effect of only displaying the button on the last panel it was added to.
I'm kinda stumped. The behaviour I want is simple: Multiple instances of this toggle button that sync their selected state. Ideas?
P.S. I suppose I could construct a list of the instances and update all the other's state when one of them is clicked, but I wonder if there's something simpler out there.
Thanks
Yes, the buttons must all be distinct, but they can either share the same ButtonModel or the same Action. Usually, I try to have them share Actions by creating a single Action that extends AbstractAction, and use it to set the Actions of all the same buttons.
No big reveal here. I solved my problem using my own suggestion, that is, I simply kept a list of all the instances of the button and set their states when any one of them was clicked in an action they all share.

Understanding the widgetSelected event and the widgetDefaultSelected event in the swt SelectionListener?

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.

toggle button vs image changing button

When to use this functionality and when to use the other? I personally thing that to switch between two different modes one should use a toggle button but i need to convince some people at work. any formal UI literature on the subject? thanks
I don't have references for you, but as a user I can tell you what I would expect.
I would expect the button to change images when you substitute one action for another because you entered a different mode. This is really relevant to save real estate in your toolbars, etc. For example you could have a dedicated play button and stop button with one always being disabled. Using one button saves space since at no point will both be enabled.
I would expect a normal depressed/unpressed toggle button when there is one mode that you either enable or disable. An example of this is "Toggle Mark Occurrences" in Eclipse. Unpressing that toggle button does not constitute a new action, but rather disabling an active mode.
I’m inclined to go with toggling buttons (buttons that “stick” depressed when “on”) rather than swapping images or label for a command button. I can’t cite any formal literature, but my impression is that it makes it easier both to anticipate the action produced by activation and to read the current state. The appearance and behavior of a toggle button is consistent with physical toggle button switches (like the Play buttons on older physical tape recorders). It’s also consistent with option buttons, check boxes, and state menu items, which all indicate their affirmative states through peripheral graphic design rather than labels. When the control looks like a command button (raised appearance), it’s labeled like a command button, the label indicating the action committed like any command button (e.g., “Connect”). When it looks like a state indicator (sunken, like a text box), its labeled suggest its current state (connected).
A single toggle button should only be used when there are simple True and False states to the process (e.g., Connected or not). Otherwise you need two or more “segmented controls” (abutting toggling buttons) to ambiguously indicate the alternatives (e.g., Forward vs. Reverse). This is analogous to using two option buttons in place of a check box.
Swapping labels to indicate changes in a button’s action can work if you use text labels that unambiguously indicate the action committed on activation, e.g., (“Connect” and “Disconnect”). While the Play/Pause button is a defacto standard, I’d otherwise avoid using an icon or image because it may confuse users on whether the label is indicating the current state or the state they’d get on activation (i.e., the opposite). There have been buttons that do one or the other, so the user can’t rely on experience. An image it not clearly a verb or adjective, so labeling with an image is tantamount to using text labels like “Online” and “Offline.” Even if done right, swapping labels has the disadvantage that the user needs to do a weird mental transformation to read the affirmative state (“It says I can disconnect, therefore I must be online now”). It can also mean you need a wordier label.

regain focus after java.awt.Robot.keyPress()/mousePress()

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

Categories

Resources