简体   繁体   English

在CodenameOne中,为什么没有选中复选框但是出现了选中状态?

[英]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. 我有一个奇怪的问题 - 不确定是否存在编码错误或CN1中的错误。

Basically I create a row of CheckBox objects and put them in a container that is X-Scrollable. 基本上我创建了一行CheckBox对象并将它们放在一个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 请参阅以下问题视频: 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. 请注意,在控制台输出中,单词“selected”在选择字段时大写,在取消选择时小写。 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). 焦点相同(我将焦点添加到输出以确定setFocusable()是否按预期工作,因此焦点不应归咎于选择错误)。

here's the Checkbox creation code: 这是Checkbox创建代码:

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. 更新:我已经意识到这里有两个“状态”: toggleButtons(我现在意识到它们不仅仅是CheckBoxes,因为我设置了“setToggle(true)”因为它们被拖动而被卡在“按下”状态不幸的是,“按下”和“选中”状态具有相同的外观,这意味着我的用户认为他们在拖动操作期间被“按下”时已经选择了某些东西。

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. 除非你在Display更改了一个标志或设置了一些奥术主题常量,否则这几乎总是正确的。

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. 为此,我在滚动容器上使用了addPointerReleasedListener来检测指针何时脱落(因此它的组件肯定不再被按下),然后在其Runnable ,我确保每个都被释放。

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. 现在我们只需要一个永久修复,或ToggleButtons文档中的注释,当它们在滚动容器中时,它们可能会陷入压缩状态并需要被释放。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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