I read that a JButton implements ItemSelectable and into documentation it has the method addItemListener so I can argue that it can generate an ItemEvent... but when I register with a JButton (but also for a JMenuItem) that interface the event is not rised?
Why?
I understand that if into docs is reported that a component has an add....Listener it means that it support that event... but for experience isn't often so...
What's the truth?
There is a difference between a button being "pressed" (which fires an ActionEvent) and a button being "selected" (which fires the ItemEvent). By default a JButton is backed by a javax.swing.DefaultButtonModel. If you look at the setPressed and setSelected methods in default button model you'll see the code that fires the different events.
So if you programmically call JButton.setSelected, your item listener will be fired. If you click the button, you'll only get the action event.
Note also that with a JButton (unlike, say, a JToggleButton) you probably won't see much visually when it is selected.
Related
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.
What is the difference between ChangeListener and ItemListener for JCheckBox and JRadioButton? Both of them work fine when they are selected/deselected.
I know that some components doesn't support ChangeListener like the JComboBox. Other than the reason that ChangeListener or ItemListener work for only some components. Is there any difference between them like when are they generated?
Any answer is appreciated. Thanks in advance.
both listeners for JCheckBox work similarly in that both will fire event upon change in state, whether by clicking or toggle by spacebar or programmatically through doClick() method (Similar to mouse click). One major difference though is that JCheckBox’s itemListener can be fired through setSelected(boolean) method which allows one to fire the event based on desired state whereas others will act only after the state is altered. So why is it important ? Consider when application startup, the GUI needed to configure for defined state, and using setSelected will trigger ItemListener. Note that setSelected is exclusive to ItemListener and has no effect on ActionListener. Do not register both ActionListener and ItemListener as both will be fired, landing the component in a random state
ChangeListener is notyfied when there's any change to the button state. ChangeListener is not notified of what has changed, only that the object has changed. Item listener is only notyfied when an item is selected; by user or setSelected method. It's also not true that ChangeListener is not notyfied when setSelected method is invoked. It is the change of the object state.
I have created a Jframe with a JButton for a specific action.
Now please I want a situation whereby anytime I hit my enter key on my keyboard it will perform the action I have coded in my Jbutton.
My Jframe was designed with Netbeans 7.3.
Now please I want a situation whereby anytime I hit my enter key on my keyboard it will perform the action I have coded in my Jbutton.
Make your JButton the default button of the JRootPane.
You do this by calling setDefaultButton(myJButton) on the root pane.
And you can get the JRootPane by calling getRootPane() on your JFrame.
Note that if you want this action when a JTextField has focus, then the solution is different; here you'll want to add the same ActionListener given to the JButton to the JTextField.
Implement ActionListener Interface
The listener interface for receiving action events. The class that is
interested in processing an action event implements this interface,
and the object created with that class is registered with a component,
using the component's addActionListener method. When the action event
occurs, that object's actionPerformed method is invoked.
I would like to check whether a certain javax.swing.JButton (regular push-button) is pressed down (before it was released). Is there any option at all to check whether a button is down?
The most trivial solution is to add a MouseListener that will respond to the mouse click and release events. But, this does not cover the case where the button was activated by the Enter key, or any other way. I don't want to disable activating the mouse by keyboards or other ways - I just want to know when is it pressed down without restricting it's behaviour.
I tried listening to all the different events, and the only two that do respond to button press are the ActionPreformed (ActionEvent) and the StateChanged (ChangedEvent) events. ActionPreformed is executed once per click, meaning only after the button was pressed and released, so it's not good. StateChanged is indeed invoked several times when I click a button, and several times when I release it. But, the event object only includes information about the source widget (the button) and no information about the state change itself. This prevents from distiguishing which of the events we want to catch.
Thanks in advance!
ButtonModel can do that, more here or here or maybe off-topic JMenuItem & ChangeListener by #kleopatra
Can you disable a JButton without graying out the button itself?
When you use setEnbaled(false), the button disables and turns to gray. Is it possible to disable the button but make the appearance of the button still the same?
You could ignore the button press in your ActionListener if a flag is set; however, you should not disable the button without showing it as disabled: it will only confuse the users of your application.
I suggest setting a ButtonModel with overridden setArmed and setPressed. Exactly how you override it depends on exactly what you want it to do - should it appear to be pressed when pressed, for instance? Only set the ButtonModel once for a JButton. Add or repurpose state on the ButtonModel to indicate how you want it o behave at any given moment.
Clearly, GUIs with non-standard behaviour are likely to confuse users.