我有一个简单的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;
}
}
答案 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进行通信,以及它应该具有哪些子字段(以及这些子编辑器)。