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

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.

Related

ItemListener vs ChangeListener vs ActionListener

I've seen many Java Swing programs that use ActionListener, ChangeListener, or ItemListener. What are the differences between these and when should I use each one?
ActionListener
They are used with buttons or menu. So that whenever you click them it notifies the ActionEvent which in turn invokes the actionPreformed(ActionEvent e) function to perform the specified task.
ItemListeners
These are used with checkboxes, radio buttons, combo boxes kinds of stuff.
See what happens when you use ActionListener with combo box instead of item listener in this link https://coderanch.com/t/331788/java/add-listener-combo-drop-list.
ChangeListener
This is used with components like sliders, color choosers and spinners where you want the action to be performed according to the change in that component (https://docs.oracle.com/javase/tutorial/uiswing/events/changelistener.html). Focus on the word "change". Then you might think it should work with buttons too. You can see for yourself on this website http://www.java2s.com/Tutorial/Java/0240__Swing/AddchangelistenertoButtonmodel.htm
For a JMenuItem, instead of a listener, you should use an Action (which is a more capable form of ActionListener):
Action saveAction = new AbstractAction("Save") {
#Override
public void actionPerformed(ActionEvent event) {
saveDocument();
}
};
saveAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
saveAction.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("control S"));
saveMenuItem = new JMenuItem(saveAction);
For JCheckBoxMenuItems and JRadioButtonMenuItems, just as with regular JMenuItems, the Action’s actionPerformed method is called when the user activates the menu item. You can check the new state from within your Action:
Action showStatusAction = new AbstractAction("Show Status") {
#Override
public void actionPerformed(ActionEvent event) {
boolean selected = (Boolean) getValue(SELECTED_KEY);
statusBar.setVisible(selected);
}
};
showStatusAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_W);
showStatusAction.putValue(Action.SELECTED_KEY, true);
showStatusMenuItem = new JCheckBoxMenuItem(showStatusAction);
Note that Action.SELECTED_KEY only works if you set it to true or false before you install the Action. From the documentation:
Components that honor this property only use the value if it is non-null. For example, if you set an Action that has a null value for SELECTED_KEY on a JToggleButton, the JToggleButton will not update its selected state in any way. Similarly, any time the JToggleButton's selected state changes it will only set the value back on the Action if the Action has a non-null value for SELECTED_KEY.
If you insist on using listeners directly, ItemListener indicates selection state, so it can be used to monitor the state of JCheckBoxMenuItems and JRadioButtonMenuItems. For all other JMenuItems, use ActionListener.
The above actually applies to all descendants of AbstractButton as well as JMenuItem and its descendant classes:
For JButtons, use an Action.
For JToggleButtons, JCheckBoxes, and JRadioButtons, use an Action and check its SELECTED_KEY value.
If you aren’t willing to use Actions, use ActionListener for JButtons, and use ItemListener for JToggleButtons, JCheckBoxes, and JRadioButtons.
My understanding is that there is no reason to use a ChangeListener with a standard JMenuItem or button, as a ChangeEvent is mainly intended to indicate to renderers that the component needs to be repainted.

How to detect if user clicks on window title bar or any other part of window border in Java

I have implemented a pop-up numeric keypad using the Swing Popup class. I have a button associated with a JTextField that opens the numeric keypad when the user clicks on it, and then when/if the JTextField loses focus the Popup closes. It generally works well, except that occasionally I get artifacts that are "left over" from a Popup after it has been hidden. Sometimes the artifact is an image of the Components that were shown in the Popup, but more often it is a "black hole" of sorts that obscures anything else displayed in the same area of the screen in which the Popup had been, which can only be remedied by shutting down the application and the JVM.
The problem is difficult to reproduce, but it seems to manifest when the user manipulates the base Window while the Popup is open, such as by moving or resizing it. My thought is to simply hide the Popup when anything like that happens, which I can do with a combination of a WindowListener and a ComponentListener. However, I'd like to take it one step further and hide the Popup as soon as the user so much as clicks on the window title bar or another portion of its frame, even before they move, resize or iconify it. JComboBox popups in fact work this way. However, I have been unable to find any kind of mechanism by which I can be notified that a user has clicked on the window title bar. I've looked at the JComboBox and related code and can't figure out from that how it's working this magic, either. Is there any other kind of listener I could use to get this kind of notification?
I have implemented a pop-up numeric keypad using the Swing Popup class.
Well post your code demonstrating the implementation and problem when you post a question.
I don't know exactly what you are doing but you might be able to use a JPopupMenu. This will close when you click on the frame title bar with no FocusListener or any additional logic.
will be deleted, just code for testing,
private boolean _myWindowFocusLost = false;
.
_xxXxx.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {//Invoked when a component gains the keyboard focus.
if (e.getOppositeComponent() != null) {
if (e.getOppositeComponent() instanceof JComponent) {
JComponent opposite = (JComponent) e.getOppositeComponent();
if ((opposite.getTopLevelAncestor() != _myPopupWindow) && (!_myWindowFocusLost)) {
_myWindowFocusLost = false;
}
}
}
}
});

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

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.

JWindow alway on top not getting focus events

I have a jwindow(set to be always on top) that you can click to get a pop menu. If the user right clicks the window it shows the pop menu but then if the user clicks any other window(such as firefox) pop menu does not disappear.
I tried to fix it by adding FocusListener on the jwindow, i implemented FocusListener and override
public void focusGained(FocusEvent e) {
System.out.println("gain" );
}
public void focusLost(FocusEvent e) {
System.out.println("lost" );
}
but there event never get called. i also tried the following,
addWindowFocusListener(new WindowAdapter() {
public void windowGainedFocus(WindowEvent e) {
System.out.println("gain 2" );
}
});
this event also not called.
All this jwindows has is a single JLabel with a picture on it.
From memory JWindow's do not receive focus/window events.
You are suppose to call setFocusableWindowState(true) on a JWindow to allow it to be focusable. But that "still" is not enough. The JWindow must also have focusable Components and I'm still not able to get it to work.
Using JFrame setUndecorated() seems the best choice.
To be focusable, a JWindow needs to be created with a parent Frame, like new JWindow(parentFrame). Do that and I think you should find it will automatically get the focus when you set it to visible.
Not really sure what you are trying to do. If you are trying to hide the popup manually then you should probably use a WindowListener and handle the windowDeactivated event.
If you really want to display a popup menu, you should be using JPopupMenu, not implementing it yourself.

Categories