LayoutClickListener fires multiple times

Hi,

I implemented a simple toggle button, using a CustomComponent and a LayoutClickListener.

However it seems that if you click fast (quick button-down and button-up) the event is fired two times.

In my case this means that the toggle button is turned on and off on a single click. Can anyone help me how to solve this issue?

Here’s my code:

public class OnOffButton extends CustomComponent {

    private boolean isOn;
    private String captionOff;
    private String captionOn;
    private Label button;
    private VerticalLayout layout;

    public OnOffButton(String captionOff, String captionOn, boolean isOn) {
        this.captionOff = captionOff;
        this.captionOn = captionOn;
        this.isOn = isOn;

        initUI();
    }

    /**
     * Returns true if button is on, else false
     *
     * @return
     */
    public boolean isOn() {
        return isOn;
    }

    private void initUI() {
        layout = new VerticalLayout();
        layout.setImmediate(true);
        layout.setSizeFull();

        if (isOn) {
            button = new Label(captionOn);
        } else {
            button = new Label(captionOff);
        }

        button.setWidth(null);
        button.setImmediate(true);
        layout.addComponent(button);

        // Toggle
        layout.addLayoutClickListener(new LayoutClickListener() {

            @Override
            public void layoutClick(LayoutClickEvent event) {
                if (isOn) {
                    layout.removeComponent(button);
                    button = new Label(captionOff);
                    button.setWidth(null);
                    layout.addComponent(button);
                } else {
                    layout.removeComponent(button);
                    button = new Label(captionOn);
                    button.setWidth(null);
                    layout.addComponent(button);
                }
                button.setImmediate(true);
                isOn = !isOn; // revert status
            }
        });

        setCompositionRoot(layout);
        this.setImmediate(true);
    }

    public void addClickListener(LayoutClickListener listener) {
        layout.addLayoutClickListener(listener);
    }
}

Hi Colin, maybe the Server Roundtrip is a problem - i.e. if you click faster (or slower) than the server roundtrip takes you get weired solutions. Even when the roundtrip is fast enough: I’d say from above code that clicking twice means exactly that: on and off again.
Anyway: a real safe way would be checking on the client side already (and e.g. using a grace period of some milliseconds before a 2nd click does anything). Doing that on the server might be a solution but a brittle one as it depends on roundtrips again.
Good luck!
Sebastian

Hi Colin,

When you say fast maybe you are meaning “double clicking” instead of clicking.

Regarding double clicking and layoutclickevent (correct me if i am wrong):

  • If you doubleclick your right mouse button, two single LayoutClickEvents are fired. There is no doubleclick LayoutClickEvent.
  • If you doubleclick your left mouse button two single LayoutClickEvents are fired, plus a doubleclick LayoutClickEvent.

Ie, for each “double-click” on the layout, layoutClick(event) method in your LayoutClickListener would be called 3 times whether the left button is doubleclicked, or twice whether the right one is.

What happens in the browser?
This
could help:

Other considerations about your code,
cause there is always a label (called button) in your component layout, once instantiated try changing its value, to display the new component status. You wouldnt have to instantiate, init and remove old components.

For instance,

public void layoutClick(LayoutClickEvent event) {
// revert status
isOn = !isOn;

        // Display new status label
        String newValue = isOn ? captionOn: captionOff;
        button.setValue(newValue);

}

:wink:

Best regards

That improved the situation a bit but in the long term I will implement a widget. Thank you both for your help.