SimpleBeanEditorDriver是否支持自动装箱?

时间:2014-11-20 13:53:07

标签: gwt editor

我有一个简单的bean:

public class SimpleBean implements Serializable {
    String stringMe;
    double autoboxMe;
    // ... boilerplate ...
}

我创建了一个实现编辑器的视图。

public class View extends Component implements Editor<SimpleBean> {

    @UiField
    HasValue<String> stringMeEditor;
    @UiField
    HasValue<Double> autoboxMeEditor;

    // boilerplate uibinder blabla
}

如果我在独立或树中运行此编辑器,我只在视图中收到字符串的值,双框保持为空。

如果我负担写一个LeafValueEditor,显式设置值,在setValue()方法中,会出现双打。

那么问题出在哪里? SimpleBeanEditorDriver是否不能自动执行,并且找不到匹配的编辑器字段?

更新:已要求实际代码。

这是实际的编辑器。如果LeafValueEditor到位,则此编辑器仅起作用。如果用简单的“编辑器”替换LVE,它将不会显示任何值。

我知道如果值为null,NPE会出现问题,但可以使用验证进行管理。

package de.srs.pen.portal.widgets.metadataeditor;

import com.google.gwt.activity.shared.Activity;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.user.client.ui.IsWidget;

import de.srs.pen.api.meta.xml.PageClip;
import de.srs.pen.portal.widgets.editors.HasDeleteHandlers;
import de.srs.pen.portal.widgets.utils.HasActivity;

public interface PageClipEditor
        extends Activity
{
    public interface View
            extends IsWidget, HasActivity<PageClipEditor>, LeafValueEditor<PageClip>, HasDeleteHandlers
    {

        void removeFromParent();

    }
}

这是View界面的实现。

package de.srs.pen.portal.widgets.metadataeditor;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Widget;

import de.srs.pen.api.meta.xml.PageClip;
import de.srs.pen.portal.widgets.editors.EditorDeleteEvent;
import de.srs.pen.portal.widgets.editors.EditorDeleteEventHandler;

public class PageClipEditorView
        extends Composite
        implements PageClipEditor.View
{

    private static PageClipEditorViewUiBinder uiBinder = GWT.create( PageClipEditorViewUiBinder.class );

    interface PageClipEditorViewUiBinder
            extends UiBinder<Widget, PageClipEditorView>
    {}

    private PageClipEditor activity;

    @UiField
    HasClickHandlers btnDelete;

    @UiField
    @Path("id")
    HasValue<String> idEditor;
    @UiField
    @Path("display")
    PageDisplayEnumEditor displayEditor;
    @UiField
    @Path("xPos")
    HasValue<Double> xPosEditor;
    @UiField
    @Path("yPos")
    HasValue<Double> yPosEditor;
    @UiField
    @Path("height")
    HasValue<Double> heightEditor;
    @UiField
    @Path("width")
    HasValue<Double> widthEditor;

    public PageClipEditorView() {
        initWidget( uiBinder.createAndBindUi( this ) );
    }

    @Override
    public void setActivity(PageClipEditor activity) {
        this.activity = activity;
    }

    @Override
    public PageClipEditor getActivity() {
        return this.activity;
    }

    @Override
    public HandlerRegistration addDeleteHandler(EditorDeleteEventHandler handler) {
        return addHandler( handler, EditorDeleteEvent.TYPE );
    }

    @UiHandler("btnDelete")
    public void handleDelete(ClickEvent ev) {
        fireEvent( new EditorDeleteEvent() );
    }

    @Override
    public void setValue(PageClip value) {
        displayEditor.asEditor().setValue( value.getDisplay() );
        heightEditor.setValue( value.getHeight() );
        widthEditor.setValue( value.getWidth() );
        xPosEditor.setValue( value.getxPos() );
        yPosEditor.setValue( value.getyPos() );
        idEditor.setValue( value.getId() );
    }

    @Override
    public PageClip getValue() {
        PageClip clip = new PageClip( idEditor.getValue(),
                                      xPosEditor.getValue(), yPosEditor.getValue(),
                                      widthEditor.getValue(), heightEditor.getValue(),
                                      displayEditor.asEditor().getValue() );
        return clip;
    }
}

这是uibinder模板文件。

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:p="urn:import:de.srs.pen.portal.widgets.metadataeditor">
    <ui:with type="de.srs.pen.portal.widgets.metadataeditor.MetadataEditorText"
        field="res" />
    <ui:with type="de.srs.pen.portal.widgets.icons.WidgetIcons"
        field="icon" />

    <ui:style>

    </ui:style>
    <g:HTMLPanel>
        <g:Image ui:field="btnDelete" resource="{icon.circleCloseDeleteGlyph}"
            height="16px" width="16px" title="{res.pageclipDelete}" />
        <g:InlineLabel text="{res.pageclipName}" />
        <g:TextBox ui:field="idEditor" width="5em"/>
        <g:InlineLabel text="{res.pageclipDisplay}" />
        <p:PageDisplayEnumEditor ui:field="displayEditor" />
        <g:InlineLabel text="{res.pageclipXPos}" />
        <g:DoubleBox ui:field="xPosEditor" width="2.5em" />
        <g:InlineLabel text="{res.pageclipYPos}" />
        <g:DoubleBox ui:field="yPosEditor" width="2.5em" />
        <g:InlineLabel text="{res.pageclipHeight}" />
        <g:DoubleBox ui:field="heightEditor" width="2.5em" />
        <g:InlineLabel text="{res.pageclipWidth}" />
        <g:DoubleBox ui:field="widthEditor" width="2.5em" />
    </g:HTMLPanel>
</ui:UiBinder> 

最后,这是PageClip对象本身。

package de.srs.pen.api.meta.xml;

import java.io.Serializable;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "clip", namespace = "urn:srs.pdx.metadata")
public class PageClip implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 5556156665068106790L;

    @XmlAttribute(required=true)
    protected String id;

    @XmlAttribute(name = "xPos", required = true)
    protected double xPos;

    @XmlAttribute(name = "yPos", required = true)
    protected double yPos;

    @XmlAttribute(name = "width", required = true)
    protected double width;

    @XmlAttribute(name = "height", required = true)
    protected double height;

    @XmlAttribute(name ="display", required = false)
    protected String display;

    public PageClip() {
    }

    public PageClip( String id, double xPos, double yPos, double width, double height ) {
        super();
        this.id = id;
        this.xPos = xPos;
        this.yPos = yPos;
        this.width = width;
        this.height = height;
    }

    public PageClip( String id, double xPos, double yPos, double width, double height, String display ) {
        this(id, xPos, yPos, width, height);
        this.display = display;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public double getxPos() {
        return xPos;
    }

    public void setxPos(double xPos) {
        this.xPos = xPos;
    }

    public double getyPos() {
        return yPos;
    }

    public void setyPos(double yPos) {
        this.yPos = yPos;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public String getDisplay() {
        return display;
    }

    public void setDisplay(String display) {
        this.display = display;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "PageClip [id=" )
            .append( id )
            .append( ", xPos=" )
            .append( xPos )
            .append( ", yPos=" )
            .append( yPos )
            .append( ", width=" )
            .append( width )
            .append( ", height=" )
            .append( height )
            .append( ", display=" )
            .append( display )
            .append( "]" );
        return builder.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((display == null) ? 0 : display.hashCode());
        long temp;
        temp = Double.doubleToLongBits( height );
        result = prime * result + (int)(temp ^ (temp >>> 32));
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        temp = Double.doubleToLongBits( width );
        result = prime * result + (int)(temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits( xPos );
        result = prime * result + (int)(temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits( yPos );
        result = prime * result + (int)(temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if( this == obj ) {
            return true;
        }
        if( obj == null ) {
            return false;
        }
        if( !(obj instanceof PageClip) ) {
            return false;
        }
        PageClip other = (PageClip)obj;
        if( display == null ) {
            if( other.display != null ) {
                return false;
            }
        }
        else if( !display.equals( other.display ) ) {
            return false;
        }
        if( Double.doubleToLongBits( height ) != Double.doubleToLongBits( other.height ) ) {
            return false;
        }
        if( id == null ) {
            if( other.id != null ) {
                return false;
            }
        }
        else if( !id.equals( other.id ) ) {
            return false;
        }
        if( Double.doubleToLongBits( width ) != Double.doubleToLongBits( other.width ) ) {
            return false;
        }
        if( Double.doubleToLongBits( xPos ) != Double.doubleToLongBits( other.xPos ) ) {
            return false;
        }
        if( Double.doubleToLongBits( yPos ) != Double.doubleToLongBits( other.yPos ) ) {
            return false;
        }
        return true;
    }


}

1 个答案:

答案 0 :(得分:1)

是的,支持自动装箱,但您应该非常小心它实际上是您想要的 - 如果autoBoxMeEditor.getValue()返回null,则在您拨打NullPointerException时会有driver.flush() {1}}。

话虽如此,HasValue不是编辑器,你的'bean'没有getter和setter - 这两个事实应该意味着你的编辑器都不应该工作,而不仅仅是字符串。如果您使用真实代码更新问题,我会稍后再回来查看。


从你的编辑:

  

这是实际的编辑器。如果LeafValueEditor到位,则此编辑器仅起作用。如果用简单的“编辑器”替换LVE,它将不会显示任何值。

这就是问题所在,这就是出现的原因,而实际上并没有说你的子编辑是编辑:

@Override
public void setValue(PageClip value) {
    displayEditor.asEditor().setValue( value.getDisplay() );
    heightEditor.setValue( value.getHeight() );
    widthEditor.setValue( value.getWidth() );
    xPosEditor.setValue( value.getxPos() );
    yPosEditor.setValue( value.getyPos() );
    idEditor.setValue( value.getId() );
}

您不应该编写该方法,但是因为a)您没有将您的编辑器称为Editor s,而b)您正在将父级设为LeafValueEditor,您必须这样做。

首先,LeafValueEditor是什么意思?简而言之,你的类型是“我在编辑树中代表一些叶子 - 不要费心去看我的孩子(即字段)来弄清楚如何绑定子编辑器。”如果你实际上已经实现了{{1}编辑器系统会查看该类,并试图找到任何编辑器字段。

接下来,由于您没有任何编辑器字段,因此转移到Editor<PageClip>无济于事!不是将您的字段称为HasValue,而是按其真实类型引用它们。这包括接口LeafValueEditor(从上面记得这个?),所以String和double将被正确绑定。


您将要遇到的一个未来可能的问题,因为您没有共享驱动程序设置的代码:确保在驱动程序声明中引用编辑器实现,而不是视图接口。您必须这样做,以便驱动程序知道它正在与哪个impl进行通信,以及它应该具有哪些子字段(以及这些子编辑器)。