GWT Header CheckBox在以编程方式更改其值后,需要两次单击才能触发设置值

时间:2013-08-01 06:59:48

标签: gwt checkbox datagrid celltable

我有一个GWT DataGrid,并在Header中有一个CheckBox来选择/取消选择网格中的所有行。

CheckBox标题的代码如下:

    private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {

    private boolean checked;
    private HandlerManager handlerManager;

    /**
     * An html string representation of a checked input box.
     */
    private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
    /**
     * An html string representation of an unchecked input box.
     */
    private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");

    @Override
    public void render(Context context, SafeHtmlBuilder sb) {
        if (Boolean.TRUE.equals(this.getValue())) {
            sb.append(INPUT_CHECKED);
        } else {
            sb.append(INPUT_UNCHECKED);
        }
    };

    public CheckboxHeader() {
        super(new CheckboxCell(true, false));
        checked = true;
    }

    // This method is invoked to pass the value to the CheckboxCell's render method
    @Override
    public Boolean getValue() {
        return checked;
    }

    @Override
    public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent) {
        int eventType = Event.as(nativeEvent).getTypeInt();
        if (eventType == Event.ONCHANGE) {
            nativeEvent.preventDefault();
            // use value setter to easily fire change event to handlers
            setValue(!checked, true);
        }
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
        return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
    }

    @Override
    public void fireEvent(GwtEvent<?> event) {
        ensureHandlerManager().fireEvent(event);
    }

    @Override
    public void setValue(Boolean value) {
        setValue(value, true);
    }

    @Override
    public void setValue(Boolean value, boolean fireEvents) {
        checked = value;
        if (fireEvents) {
            ValueChangeEvent.fire(this, value);
        }
    }

    private HandlerManager ensureHandlerManager() {
        if (handlerManager == null) {
            handlerManager = new HandlerManager(this);
        }
        return handlerManager;
    }
}

因此,我将Header添加到网格中,并向其添加ValueChangeHandler以在网格的每一行中实际选择/取消选择单个CheckBox单元格。一切正常。

每个CheckBoxCell都有一个字段更新程序,每次更新时,它都会遍历网格中的每个项目,以查看它们是否都已选中,并更新标题复选框。如果未选中至少一个,则将取消选中标题复选框。我在标题复选框上调用setValue(),然后在整个网格上调用redrawHeaders()。这也有效。

什么行不通 - 在以编程方式更改标题复选框的“状态”后,需要两次单击才能再次触发它的内部setValue,从而触发我的处理程序。什么甚至更有趣 - 第一次点击 更改复选框的状态,但它不会触发事件。

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

你是如何自己构建CheckboxCells的?我遇到了一个类似的问题,其中一列复选框“正在”点击,并且解决方案是调用CheckboxCell cell = new CheckboxCell(true,true)然后将该单元格传递到列的构造函数中。