简体   繁体   中英

In CodenameOne, why is a checkbox not selected but appearing selected?

I Have an odd problem - not sure if there's a coding mistake or a bug in CN1.

Basically I create a row of CheckBox objects and put them in a container that is X-Scrollable. If i click on one un-selected item and drag until the "elastic" effect pulls it back, it appears to be selected, but the code does not record it as selected.

Please see the following video of the issue: https://youtu.be/EtputE1kjyo

Note that in the Console output, the word 'selected' is capitalized when the field has been selected and lowercase when it is unselected. Same for focus (I added focus to the output to determine if setFocusable() was working as desired so that focus was not to blame for the selection error).

here's the Checkbox creation code:

cb = new CheckBox(getCacheableImageMaxHeight(mod.getIconFile(),moduleImageHeight));
cb.setName(mod.getModuleID());
cb.setToggle(true);
cb.setUIID("ModuleButton");
cb.setFocusable(false);
cb.setScrollVisible(false);
cb.setTextPosition(Component.BOTTOM);
cb.setCloudDestinationProperty(cb.getName());

//actionlistener added for debugging only
final CheckBox cbFinal = cb;
final String modName = mod.getDisplayName();
cb.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        System.out.println(modName+", "+(cbFinal.isSelected()?"SELECTED":"selected") + ", " + (cbFinal.hasFocus()?"FOCUS":"focus"));
    }
});
c.addComponent(cb);

UPDATE: I've realized there are two "states" at war here: The toggleButtons (I now realize they're not just CheckBoxes since I set "setToggle(true)) are getting stuck in the "pressed" state as they are dragged and released with the "elastic" effect. Unfortunately, the "pressed" and "selected" states have the same appearance so that means my users think they have selected something when it's just stuck being "pressed" during a drag operation.

Here's some more debugging I did.
按下并选择!

  • The first button is Pressed, but not selected (the bug).
  • the second button is Selected normally and not showing the bug.
  • The Third button is interesting because I selected it, then dragged and released it to get it to be SELECTED and PRESSED!

So the question changes to: Is there an open bug for this situation already (Pressed state gets stuck on after button is released) and if so, is there a fix coming or a workaround for now?

Just style the selected state to look different from the pressed state and it should work fine.

In a touch device selected state isn't rendered when the finger is up. This is almost always true unless you changed a flag in Display or set some arcane theme constant.

So I figured out a more effective workaround that doesn't involve adding a separate pressed style (since there could be buttons selected, pressed, and selected+pressed with the bug)

I needed to capture the event that scrolling stopped and then check the state of the buttons to make sure none were still pressed. To do this, I used addPointerReleasedListener on the scrolling container to detect when the pointer came off (so its components are definitely no longer pressed), and then in its Runnable , I make sure each one is released.

scrollingContainer.addPointerReleasedListener(evt -> {
    Container cont = (Container) evt.getComponent();
    Iterator<Component> buttons = cont.iterator();
    while (buttons.hasNext()){
        Button button = (Button) buttons.next();
        if (button.getState() == Button.STATE_PRESSED) {
            button.released();
        }
    }
});

So far seems to solve the problem. Now we just need a permanent fix, or a note in the documentation of ToggleButtons that when they are in a scrolling container, they could get stuck in a pressed state and need to be released.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM