Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActionPerformed Fired when setSelection method called in WebSwitch #400

Closed
iamchathu opened this issue Jul 16, 2016 · 5 comments
Closed

Comments

@iamchathu
Copy link
Contributor

I need to use two WebSwitchs in a Window where only one can selected at a time. So I have written a toggle method to invert the selection and called in two switchs actionPerformed event in a actionListener.

Problem is setSelection method runs actionPerformed event and StackOverFlow is happening since both of them toggling their states recursively

@mgarin
Copy link
Owner

mgarin commented Jul 19, 2016

If you look at any Swing component - they all fire appropriate events even if you set the value through the code, otherwise it is impossible to track changes made in the component settings or data anyhow. Here is an actual example - JComboBox.setSelectedItem:

    public void setSelectedItem(Object anObject) {
        Object oldSelection = selectedItemReminder;
        Object objectToSelect = anObject;
        if (oldSelection == null || !oldSelection.equals(anObject)) {

            if (anObject != null && !isEditable()) {
                // For non editable combo boxes, an invalid selection
                // will be rejected.
                boolean found = false;
                for (int i = 0; i < dataModel.getSize(); i++) {
                    E element = dataModel.getElementAt(i);
                    if (anObject.equals(element)) {
                        found = true;
                        objectToSelect = element;
                        break;
                    }
                }
                if (!found) {
                    return;
                }
            }

            // Must toggle the state of this flag since this method
            // call may result in ListDataEvents being fired.
            selectingItem = true;
            dataModel.setSelectedItem(objectToSelect);
            selectingItem = false;

            if (selectedItemReminder != dataModel.getSelectedItem()) {
                // in case a users implementation of ComboBoxModel
                // doesn't fire a ListDataEvent when the selection
                // changes.
                selectedItemChanged();
            }
        }
        fireActionEvent();
    }

As you can see it fires both events on the JComboBox. You can find similar code pieces in many other basic Swing components.

If you want to do what you mentioned in the topic - you need to ensure that second action event is ignored while first one is being handled and vice versa. I have a lot of similar workarounds for some file chooser events for example.

That said, I will be doing some adjustments to WebSwitch component later to enable styling on it and along with those changes I might add a separate kind of events to be fired only when changes are made from the UI - usually that would be an action event. And then you will have another kind of event - change event for example - that will always notify you, doesn't matter where changes came from. That is not something I will do before other important tasks though, so it might take some time.

@mgarin mgarin self-assigned this Jul 19, 2016
@mgarin mgarin added this to the v1.2.9 milestone Aug 26, 2016
@mgarin
Copy link
Owner

mgarin commented Aug 5, 2019

WebSwitch changes didn't make it into v1.2.9 update, but will become available in one of the next smaller updates.

@mgarin mgarin modified the milestones: v1.2.9, v1.3.0 Aug 5, 2019
@mgarin mgarin modified the milestones: v1.3.0, v1.2.11 Sep 20, 2019
@mgarin
Copy link
Owner

mgarin commented Sep 20, 2019

I'll move WebSwitch revamp to v1.2.11 for now as it is a fairy small component with just some basic functonality, should fit into the scope.

mgarin added a commit that referenced this issue Nov 29, 2019
- WebSwitch.java - `ActionListener` will not fire upon selection change from the code anymore, it will only fire evens when user is interacting with the component
- WebSwitch.java - `ItemListener` can be used to detect all selection change events instead of `ActionListener`

Overlay
- WebLookAndFeel.java - Separated font used for `overlay` component

General
- Fixed typos across a few classes
@mgarin
Copy link
Owner

mgarin commented Nov 29, 2019

I've re-checked how some other Swing components solve this problem and seems I was wrong before. I've added a solution similar to JToggleButton - ActionListener will not fire events anymore when selection is changed from the code, but newly added ItemListener will if you need to.

I've pushed the change into git and it will be available with v1.2.11 release soon.
It should also be available in SNAPSHOT repository in a few minutes.

@mgarin mgarin closed this as completed Nov 29, 2019
@mgarin
Copy link
Owner

mgarin commented Nov 29, 2019

Also since this is solved - less critical WebSwitch revamp ( #582 ) will be moved to v1.2.12.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants