吞噬了CellTable

时间:2016-01-28 16:45:33

标签: gwt celltable gwt-celltable

我有一个组合框,它由一个文本字段和一个带有显示建议项目的CellTable的弹出窗口组成。文本字段有一个更改处理程序,用于更新CellTable的选择。

键入字符并单击已选择的建议时,会吞下第一次单击。第二次单击工作并通过CellTable.addDomHandler(...)触发选择。

知道为什么第一次点击被吞下了?

示例代码:

private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
        private final TextField mText;
        private CellTable<Handle<String>> mTable;
        private SingleSelectionModel<Handle<String>> mTableSelection;
        private SingleSelectionModel<Handle<String>> mSelection;
        private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
        private PopupPanel mPopup;
        private List<Handle<String>> mData;

        public SuggestFieldTextAndPopupSandbox() {
            mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
            mSelection = new SingleSelectionModel<Handle<String>>();

            mText = new TextField();
            mText.addKeyPressHandler(new KeyPressHandler() {
                @Override
                public void onKeyPress(KeyPressEvent pEvent) {
                    mPopup.showRelativeTo(mText);
                }
            });
            mText.addBlurHandler(new BlurHandler() {
                @Override
                public void onBlur(BlurEvent pEvent) {
                    mTableSelection.setSelected(startsWith(mText.getValue()), true);
                }
            });
            mText.addChangeHandler(new ChangeHandler() {

                @Override
                public void onChange(ChangeEvent pEvent) {
                    mText.setText(mText.getText().toUpperCase());
                }
            });

            mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));

            mTable.setTableLayoutFixed(false);
            mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
            mTable.setSelectionModel(mTableSelection);
            mTable.addDomHandler(new ClickHandler() {
                @Override
                public void onClick(final ClickEvent pEvent) {
                    Scheduler.get().scheduleFinally(new ScheduledCommand() {

                        @Override
                        public void execute() {
                            mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                            mText.setFocus(true);
                            mPopup.hide();
                        }
                    });
                 }
            }, ClickEvent.getType());
            mTable.addColumn(new TextColumn<Handle<String>>() {
                @Override
                public String getValue(Handle<String> pObject) {
                    return pObject.get();
                }
            });
            mTable.setRowData(mData);

            mPopup = new PopupPanel();
            mPopup.setAutoHideEnabled(true);
            mPopup.setWidget(mTable);
            mPopup.setWidth("200px");
            mPopup.setHeight("200px");

            VerticalPanel p = new VerticalPanel();
            p.add(mText);
            setWidget(p);
        }

        private Handle<String> startsWith(final String pValue) {
            final String val = nullToEmpty(pValue).toLowerCase();
            int i = 0;
            for (Handle<String> item : mData) {
                String value = item.get();
                if (value != null && value.toLowerCase().startsWith(val)) {
                    return item;
                }
                i++;
            }
            return null;
        }

    }

2 个答案:

答案 0 :(得分:1)

我转载了您的问题,问题在于: 当您点击建议时,会发生以下情况:

  • 文本字段失去焦点,导致相应的ChangeEvent被处理,然后是BlurEvent。
  • 点击会使弹出窗口立即获得焦点,这就是吞下它的原因。

如果删除文本字段的ChangeHandler和BlurHandler,问题就会消失。但我想我找到了另一个解决方案 尝试使用相对于mTableSelection的选择处理程序替换mTable的DOM处理程序,如下所示:

mTableSelection.addSelectionChangeHandler(new Handler(){

            @Override
            public void onSelectionChange(SelectionChangeEvent event) {
                Scheduler.get().scheduleFinally(new ScheduledCommand() {

                    @Override
                    public void execute() {
                        mSelection.setSelected(mTableSelection.getSelectedObject(), true);
                        mText.setFocus(true);
                        mPopup.hide();
                    }
                });
            }

        });

答案 1 :(得分:0)

找到了解决这个问题的方法。

当用户悬停建议列表区域时跳过模糊处理程序似乎解决了这个问题,至少从已完成的测试中看不到任何其他问题。

这是必要的,因为在用户点击建议项之前,文本会模糊并触发选择更改。这反过来取消了用户点击项目时所做的选择。