I have a JComboBox with multiple values in it. I need to be able to detect when the user clicks the JComboBox but does not change the currently selected item.
Neither itemStateChanged nor actionPerformed fire when this happens.
What event should I be using?
How about recording the combo box's state when the mouse button is pressed, and comparing it to the value the box has when the mouse button is released?
attach a MouseListener to the JComboBox
override the mousePressed() method to record the box's state to a temp variable
override the mouseReleased() method to compare the box's value to the temp variable's value
At this point, it's a simple equality check.
Add a MouseListener to the JComboBox using its addMouseListener method. You will want to extend MouseAdapter and override only the mouseClicked method.
What if the user users the keyboard to open the popup and then uses the escape key to close the popup?
I would use a PopupMenuListener. This should handle both mouse and keyboard actions. The concept would be the same as other suggestions. When the popup is displayed you save the selected index. When is closes you compare the selected index to see it it has changed.
I was looking specifically at right mouse click on items, so it's a slightly different problem.
But the solution for me was to
Subclass JComboBox substituting getCellRenderer() with a subclassed DefaultListCellRenderer.
In the cell renderer intercept getListCellRendererComponent() which has boolean isSelected, boolean cellHasFocus parameters and can be used to watch for mouse events and do list.setToolTipText().
I'm sure the non-final selection change will get there, where it can be intercepted.
Related
I would like to make a custom component that is much like a JList, except there is a little "x" button on the right side of each cell that removes that cell from the list (and triggers an event). I know that you would have to extend JList, but looking at the code for JList I have no idea where to go from there. For reference, I would like the list to be like on the macOS Messages app (except the "x" button can always be visible, not just when the mouse is over the cell).
I would like to make a custom component
I suggest you do that by extending JPanel and adding real components to your panel. Then you can actually add JButton with the "x" that can respond to the mouse event.
A JList does not display real components, only rendered images of the component and therefore is does not respond to events if you try to click on the "x".
The other option is to use a JTable. A JTable does allow you to display values in a column format. In this case it does support the concept of editors, which would allow you to add a button to a column. For example check out Table Button Column.
I would like to know if there is a way to detect if changes in the selection of a item in a swing JCombobox is done by a user (actively) or is causes by repopulating the Jcombobox.
I have to dynamically repopulate the items of the combobox based on other selection, this also invokes the actionPerformed event
so actionPerformed is invoked by:
selection changed by user
repopulating the jcombobox items.
how to tell the difference?
Thanks of helping !
No, not really.
A possible solution is to disable event notification while the combo box is updated. This can be done in (at least) one of two ways...
Firstly, you could physically remove the listener from the combo box, if you have a reference to it.
Secondly, you set a boolean flag, which when true, the listener would ignore the event.
For example...
I want my program to behave diffrently when the user presses a component, and when a user drags the mouse over a component, the problem is that on mouse click both of these methods are being called (and it seems like mouseDragged is called after mousePressed), so how will i know if the user dragged his mouse or just pressed it?
The correct answer is to use mouseClicked instead of combination of mousePressed+mouseReleased in case you want to distinguish between a click and a drag.
I have a JTable with a custom cell editor. The editor implements FocusListener so I can check if the cell's contents is valid if the user clicks away from the cell.
I'd like to use a JOptionPane within focusLost (in the EventDispatchThread) to allow the user to select whether to revert to an old value or accept an adjusted value.
Here's the problem; if the user is editing a cell, then clicks a button away from the table, the button's actionlisteners are alerted before JOptionPane has returned.
This is what I'd like to happen:
User edits cell
User clicks button
Cell detects focus lost
JOptionPane displayed and user selects action
JOptionPane closes and cell's value set
Button's actionListeners called
Instead, this is happening:
User edits cell
User clicks button
Cell detects focus lost
JOptionPane displayed and user selects action
Button's actionListeners called
JOptionPane closes and cell's value set
Is it possible to postpone the button's action events until after the JOptionPane has closed?
From other threads, I've read that JDialog does some magic to ensure event dispatching continues so the Dialog itself can handle events.
From what I gather, you don't want the button's action-listener to activate at all, until AFTER the user selects the correct value from the JOptionPane.
To me it seems like the solution would be to set up a 'disabled' flag which goes up once the focusLost is triggered. Once the selection is made, the disabled flag goes down. When the button action is triggered, it checks if the form is disabled; if it is, it does nothing. If it isn't it continues as normal.
Notice the button event won't go automatically once the user selected something in the JOptionPane, but instead he will have to click the button again. To me this seems like better functionality then having the button 'clicked' again for him after he is required to change the form.
Put your validation logic inside TableCellEditor#stopCellEditing(), showing your dialog and returning false if the value is not valid.
To automatically stop table editing on focus lost, use table.putClientProperty("terminateEditOnFocusLost", true);, but I don't think that will stop the buttons action listener from running. Instead I usually stop the table edit in the actionPerformed and do nothing when false is returned (or cancel editing when appropriate, for example if the action is to delete that table row).
Here is the scenario. I have an swing applet with tons of checkboxes. some of them are disabled/unchecked when checking another. Each ItemStateChange() event executes a method to parse the entire form for changes. Is there a way to tell if an ItemStateChange() event was triggered due to a mouse click or from a setSelected() call?
The ItemStateChange() for each checkbox has the standard parameter java.awt.event.ItemEvent evt
I'd like to only call the processOrder() method once when a box is clicked. Right now it fires for each change thats made, regardless of whether the change happened from setSelected(). Sometimes there are 10+ parseForm(); calls from a single click.
You can't tell whether the source of the event is a mouse click or a setSelected call from the ItemEvent.
It sounds like you have a loop in your check box logic. You might want to add a controller that handles the events and sets each checkbox yet ignores events that occur due to calling setSelected on other check boxes.
Is there a way to tell if an ItemStateChange() event was triggered due to a mouse click or from a setSelected() call?
If your application manually invokes the setSelected() method then you can use code like:
checkBox.removeItemListener(...);
checkBox.setSelected(...);
checkBox.addItemListener(...);
If you are able to change to use a MouseListener instead of an ItemListener and respond to the mouseClicked() event you will only receive the events for the checkbox selected by the user.