Vaadin ComboBox blur event gets triggered when enter pressed - java

I need to add a Enter key shortcut listener to a ComboBox. I only need the shortcut to work when the ComboBox is focused. I used the approach described in this answer.
combo.addFocusListener(new FocusListener() {
#Override
public void focus(FocusEvent event) {
combo.addShortcutListener(shortcutListener);
}
});
combo.addBlurListener(new BlurListener() {
#Override
public void blur(BlurEvent event) {
combo.removeShortcutListener(shortcutListener);
}
});
What it does is, adding the shortcut listener when the combo box got focus and removing the shortcut listener when combo box lost focus.
This works well for TextFields but does not work for ComboBox. The reason is, whenever I press enter on the ComboBox, blur event gets called instead of shortcut listener getting called. Since shortcut listener is removed when blur event gets fired, shortcut listener never gets fired.
Why does combo box trigger a blur event when enter is pressed? How can I get this fixed?

As discussed above in comments, wrap the the combobox is panel and add shortcut listener to it. This should work.
Why? When you add a shortcut listener by default the scope of this shortcut listener is added to enclosing Panel/Window/UI(basically single component containers).
Hope this helps.

Related

Java Detect MouseClick anywhere in Window doesn't work in certain areas

So I have a Java Swing program and I want to be able detect mouse clicks.
addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
update(evt); //another method in the program
}
});
The code works if I click on the window's side or places where there isn't an object, but does not work when I click on objects in the JFrame, such as my JTable or my text field.
Please help me how to have the MouseListener work on objects inside the JFrame as well.
When you click on a textfield, the textfield gains focus. That means your frame loses ownership of focus, and since your listener is most likely added to your frame, your listener stops working right when frame isnt in focus. Add your listener to all compoments, or use Key Binding

actionPerformed() for button hold down

Right now I have:
panel.getZoomButton().addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ACtionEvent e)
{
zoom();
}
}
This is called every time the zoom button is pressed. How can I change it so that zoom() will be continuously called if the zoom button is being held down?
You will need to use a MouseListener and override the mousePressed() method. There you can use a Timer or something similar to measure the time, the button has been pressed, in order to calculate your zoom.
Perhaps this question helps you with that: Java MouseEvent, check if pressed down
use Swing Action (most scallable abstraction) instead of ActionListener, there you can to set isEnabled, to switch to false value until all events are done
or add Swing Timer for reset Boolean to true value
there is possible to setMultiClickThreshhold(long threshhold), but is aplicable only for MouseEvents, this methods doesn't react to KeyBindings (ENTER and TAB) firing from Keyboard

How to remove GWT menubar on Screen click?

I am a beginner using GWT. I have a menubar which pops-up on a Label click. I need to remove it when the user clicks anywhere on screen except the Label which caused it to display (Legal) I tried various methods like hooking up this event on
RootPanel.get().addDomHandler(clickDetectHandler, ClickEvent.getType());
public void onClick(ClickEvent event) {
Object source = event.getSource();
if (!(source instanceof MenuBar))
panel.remove(menu);
I even tried using the MouseOutEvent but it doesn't detect click. I am able to remove it on a click back to the legal label. But I need it to be removed on detecting a click on the screen. Please advise.
GWT has a panel called PopupPanel which automatically handles exactly the behaviour that you want.
Quoting from the javadoc:
"PopupPanel's constructor takes 'auto-hide' as its boolean parameter.
If this is set, the panel closes itself automatically when the user clicks outside of it."
Is it possible to have the pop-up menu display inside of a PopupPanel?
http://google-web-toolkit.googlecode.com/svn/javadoc/2.5/com/google/gwt/user/client/ui/PopupPanel.html
Have a look at this GWT sample. This seems to have the behaviour you describe. It comes with source code.
Alternatively you can try handling the blur event on the menu widget.

Forcing a JPopupMenu to disable hover effects on its owner JFrame?

When i right click on a JTable in a JFrame I show a JPopupMenu. If I left this JPopupMenu shown as it is and moved with the mouse to the JTable I can still hover on its rows.
This is not the default behavior of Windows applications. In normal case if a popup menu appears in a program it blocks any hover actions on the popup owner window.
Can i do the same thing in Java ?
One way to approach this problem is to set an instance variable in one of your GUI elements to flag whether or not to enable hover events. I have shown below how this may work, but it's not in its complete form, you will also need to re-enable hover when the JPopupMenu is dismissed, and also check the state of the ENABLE_HOVER field before firing hover effects.
public MyTable extends JTable {
private boolean ENABLE_HOVER = true;
public MyTable() {
...
this.addMouseListener(new MouseListener(){
...
public void mouseClicked(MouseEvent e) {
if (isRightClick(e)) {
setHoverEnabled(false);
showJPopupMenu();
}
}
});
}
protected void setHoverEnabled(final boolean hover) {
this.ENABLE_HOVER = hover;
}
}
Another method which may be better suited to disabling multitudes of however enabled elements is to intercept the events at the glass pane. An example of how this might work is shown here. Be warned though if your interface is already built it may require significant re-jigging of your component classes.
You will need to intercept all events at the glass pane, if hover is enabled (no popup menu shown) you would pass the event to the appropriate component. Otherwise if hover is disabled and the MouseEvent occurred over the JPopupMenu is passed only to the JPopupMenu.

How to make a button deep in a nested Swing panel get the "keyboard focus"?

I have a swing frame that contains embedded panels that contain other panels, etc.
Deep down, there is a button. I want the button to get focus so that pressing the "enter" key would generate an actionPerformed event.
However, if I do myButton.requestFocus() or myButton.requestFocusInWindow() the whole window gets the focus, but nothing seems to happen in terms of keyboard.
I'm obviously missing something about the focus subsystem.
Update2: I explicitly added a KeyListener in addition to the ActionListener and now it works. This is really weird, since I thought that actionListener includes both key and mouse actions.
For the enter key to work you probably want to set the default button rather than the keyboard focus:
button.getRootPane().setDefaultButton(button);
If you really want the keyboard focus then your problem might be related to when you call requestFocus. Sometimes if it is called before a component is fully visible it can be ignored. To fix that you can delay the requestFocus call until after other events have been processed:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button.requestFocus();
}
});
Sounds like requestFocus() is failing at some level. Try testing to see if any of the parent jPanels or other components can request focus, and work your way up to find out where the problem lies.
There is a way to programatically specify the functionality of the tab ( you know when you press tab and the next widget gets selected )
By default it follows the way the components were added.
Using this custom mechanism will let you select your nested button as the first which receive the actionperformed event.
Unfortunately I don't remember what the name for this "mechanism" is, but is something like traversal or focus traversal
First, don't use requestFocus() use requestFocusInWindow(). requestFocus has platform specific issues, while requestFocusInWindow is more consistent.
Your actual problem; the component (or one of its parents) is probably not visible, or has been render non-focusable.
I want the button to get focus so that
pressing the "enter" key would
generate an actionPerformed event.
The is LAF dependents. Enter works in Windows, but not the Metal LAF. Check out Enter Key and Button for more inforation.
The requestFocusInWindow() method only works if the Component is currently visible on the frame. There are no other tricks so we are just making random guesses about what your are doing wrong. If you need further help you need to post a SSCCE demonstrating the problem.
You can get the rootPane of the frame and update the inputMap and actionMap. See the below code.
InputMap map = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "ok");
ActionMap actionMap = getRootPane().getActionMap();
actionMap.put("ok", enterAction);
Here enterAction is a AbstractAction object whose actionPerformed() will be called when user presses Enter.

Categories