在 Vaadin 7 中清除 FieldGroup
Clear a FieldGroup in Vaadin 7
如何清除 FieldGroup
in a Vaadin 7 应用程序中的字段?
当我调用 FieldGroup::setItemDataSource
and pass null
, I get the text "null" appearing in TextField
由各种数据类型(数字,java.util.Date)支持的对象时。我可以理解将 "null" 显示为字符串表示形式的空值。但为什么那些 "null" 字符串默认不出现?默认情况下,我在所有字段中看到空的 TextField 字符串。
例如,考虑下面的示例应用程序。在下面的截图中我们:
- 启动应用程序。用户未采取任何操作。
所有字段均为空白,无字符串,无 "null" 文本。
- 用户单击 "Show Bernard" 按钮。
- 用户单击 "Show No One" 按钮。此按钮调用
FieldGroup::setItemDataSource( null )
,传递 null。
数字和日期字段都显示 "null" 文本。为什么现在而不是在发布时?
我怎样才能恢复到空白值?
应用启动
用户点击 "Show Bernard" 按钮
用户点击 "Show No One" 按钮
这是 Java 8 中完整的单文件 Vaadin 7.5.3 应用程序(使用 Lambda 语法)。
package com.example.gridexample;
import javax.servlet.annotation.WebServlet;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.PropertysetItem;
import com.vaadin.data.util.converter.StringToDateConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
/**
*
*/
@Theme ( "mytheme" )
@Widgetset ( "com.example.gridexample.MyAppWidgetset" )
public class MyUI extends UI
{
PropertysetItem itemAaron = null;
PropertysetItem itemBernard = null;
TextField nameField = null;
TextField ageField = null;
TextField dateOfBirthField = null;
FieldGroup fieldGroup = null;
ZoneId zone = ZoneId.systemDefault(); // Or ZoneId.of( "America/Montreal" ) ;
@Override
protected void init ( VaadinRequest vaadinRequest ) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin( true );
layout.setSpacing( true );
setContent( layout );
Button buttonAaron = new Button( "Show Aaron" );
buttonAaron.addClickListener( ( ClickEvent event ) -> {
showAaron();
} );
layout.addComponent( buttonAaron );
Button buttonBernard = new Button( "Show Bernard" );
buttonBernard.addClickListener( ( ClickEvent event ) -> {
showBernard();
} );
layout.addComponent( buttonBernard );
Button buttonNoOne = new Button( "Show No One" );
buttonNoOne.addClickListener( ( ClickEvent event ) -> {
showNoOne();
} );
layout.addComponent( buttonNoOne );
this.itemAaron = new PropertysetItem();
this.itemAaron.addItemProperty( "name" , new ObjectProperty<>( "Aaron" ) );
this.itemAaron.addItemProperty( "age" , new ObjectProperty<>( 42 ) );
this.itemAaron.addItemProperty( "dateOfBirth" , new ObjectProperty<>( Date.from( ZonedDateTime.now( this.zone ).minusYears( 42 ).toInstant() ) ) );
this.itemBernard = new PropertysetItem();
this.itemBernard.addItemProperty( "name" , new ObjectProperty<>( "Bernard" ) );
this.itemBernard.addItemProperty( "age" , new ObjectProperty<>( 24 ) );
this.itemBernard.addItemProperty( "dateOfBirth" , new ObjectProperty<>( Date.from( ZonedDateTime.now( this.zone ).minusYears( 24 ).toInstant() ) ) );
this.nameField = new TextField( "Name:" );
this.ageField = new TextField( "Age:" );
this.dateOfBirthField = new TextField( "Date Of Birth:" );
// Customize the Converter assigned to our date-time field. A StringToDateConverter object is assigned by default.
//this.dateOfBirthField.setConverter( new StringToDateConverter() ); // Actually the default.
// this.dateOfBirthField.setConverter( new SpecialStringToDateConverter() );
layout.addComponent( this.nameField );
layout.addComponent( this.ageField );
layout.addComponent( this.dateOfBirthField );
this.fieldGroup = new FieldGroup();
this.fieldGroup.bind( this.nameField , "name" );
this.fieldGroup.bind( this.ageField , "age" );
this.fieldGroup.bind( this.dateOfBirthField , "dateOfBirth" );
this.fieldGroup.setReadOnly( true );
}
private void showAaron () {
this.fieldGroup.setItemDataSource( this.itemAaron );
}
private void showBernard () {
this.fieldGroup.setItemDataSource( this.itemBernard );
}
private void showNoOne () {
this.fieldGroup.setItemDataSource( null );
}
@WebServlet ( urlPatterns = "/*" , name = "MyUIServlet" , asyncSupported = true )
@VaadinServletConfiguration ( ui = MyUI.class , productionMode = false )
public static class MyUIServlet extends VaadinServlet
{
}
}
在点击任何按钮(初始状态)之前,这些行被执行:
TextField nameField = null;
//...
this.nameField = new TextField( "Name:" );
文档说:
public TextField(java.lang.String caption)
Constructs an empty TextField with given caption.
所以您的应用程序中的所有文本字段都是空值。但是......之后你使用:
this.fieldGroup.bind( this.nameField , "name" );
该值应该为空吗? [bind()
](https://vaadin.com/api/com/vaadin/data/fieldgroup/FieldGroup.html#bind(com.vaadin.ui.Field, java.lang.Object)) 的文档再次说:
Binds the field with the given propertyId from the current item. If an item has not been set then the binding is postponed until the item is set using setItemDataSource(Item)
.
所以必须用这个方法才能看到bind
效果。
您问:但是为什么那些 "null" 字符串默认不出现?
我希望我的解释对您来说是清楚的,最初每个 TextField 都有 empty 值。而在调用bind()
函数之后,它只在setItemDataSource(Item)
之后影响视图,但是你在button的clickListener中调用这个函数要晚得多。所以最初很好,所有字段都有空值。
尝试添加 this.nameField.setNullRepresentation("");
并在每个字段上调用相同的方法,根据 Book of Vaadin 它应该可以解决您的问题。
如何清除 FieldGroup
in a Vaadin 7 应用程序中的字段?
当我调用 FieldGroup::setItemDataSource
and pass null
, I get the text "null" appearing in TextField
由各种数据类型(数字,java.util.Date)支持的对象时。我可以理解将 "null" 显示为字符串表示形式的空值。但为什么那些 "null" 字符串默认不出现?默认情况下,我在所有字段中看到空的 TextField 字符串。
例如,考虑下面的示例应用程序。在下面的截图中我们:
- 启动应用程序。用户未采取任何操作。
所有字段均为空白,无字符串,无 "null" 文本。 - 用户单击 "Show Bernard" 按钮。
- 用户单击 "Show No One" 按钮。此按钮调用
FieldGroup::setItemDataSource( null )
,传递 null。
数字和日期字段都显示 "null" 文本。为什么现在而不是在发布时?
我怎样才能恢复到空白值?
应用启动
用户点击 "Show Bernard" 按钮
用户点击 "Show No One" 按钮
这是 Java 8 中完整的单文件 Vaadin 7.5.3 应用程序(使用 Lambda 语法)。
package com.example.gridexample;
import javax.servlet.annotation.WebServlet;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.data.fieldgroup.FieldGroup;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.PropertysetItem;
import com.vaadin.data.util.converter.StringToDateConverter;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
/**
*
*/
@Theme ( "mytheme" )
@Widgetset ( "com.example.gridexample.MyAppWidgetset" )
public class MyUI extends UI
{
PropertysetItem itemAaron = null;
PropertysetItem itemBernard = null;
TextField nameField = null;
TextField ageField = null;
TextField dateOfBirthField = null;
FieldGroup fieldGroup = null;
ZoneId zone = ZoneId.systemDefault(); // Or ZoneId.of( "America/Montreal" ) ;
@Override
protected void init ( VaadinRequest vaadinRequest ) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin( true );
layout.setSpacing( true );
setContent( layout );
Button buttonAaron = new Button( "Show Aaron" );
buttonAaron.addClickListener( ( ClickEvent event ) -> {
showAaron();
} );
layout.addComponent( buttonAaron );
Button buttonBernard = new Button( "Show Bernard" );
buttonBernard.addClickListener( ( ClickEvent event ) -> {
showBernard();
} );
layout.addComponent( buttonBernard );
Button buttonNoOne = new Button( "Show No One" );
buttonNoOne.addClickListener( ( ClickEvent event ) -> {
showNoOne();
} );
layout.addComponent( buttonNoOne );
this.itemAaron = new PropertysetItem();
this.itemAaron.addItemProperty( "name" , new ObjectProperty<>( "Aaron" ) );
this.itemAaron.addItemProperty( "age" , new ObjectProperty<>( 42 ) );
this.itemAaron.addItemProperty( "dateOfBirth" , new ObjectProperty<>( Date.from( ZonedDateTime.now( this.zone ).minusYears( 42 ).toInstant() ) ) );
this.itemBernard = new PropertysetItem();
this.itemBernard.addItemProperty( "name" , new ObjectProperty<>( "Bernard" ) );
this.itemBernard.addItemProperty( "age" , new ObjectProperty<>( 24 ) );
this.itemBernard.addItemProperty( "dateOfBirth" , new ObjectProperty<>( Date.from( ZonedDateTime.now( this.zone ).minusYears( 24 ).toInstant() ) ) );
this.nameField = new TextField( "Name:" );
this.ageField = new TextField( "Age:" );
this.dateOfBirthField = new TextField( "Date Of Birth:" );
// Customize the Converter assigned to our date-time field. A StringToDateConverter object is assigned by default.
//this.dateOfBirthField.setConverter( new StringToDateConverter() ); // Actually the default.
// this.dateOfBirthField.setConverter( new SpecialStringToDateConverter() );
layout.addComponent( this.nameField );
layout.addComponent( this.ageField );
layout.addComponent( this.dateOfBirthField );
this.fieldGroup = new FieldGroup();
this.fieldGroup.bind( this.nameField , "name" );
this.fieldGroup.bind( this.ageField , "age" );
this.fieldGroup.bind( this.dateOfBirthField , "dateOfBirth" );
this.fieldGroup.setReadOnly( true );
}
private void showAaron () {
this.fieldGroup.setItemDataSource( this.itemAaron );
}
private void showBernard () {
this.fieldGroup.setItemDataSource( this.itemBernard );
}
private void showNoOne () {
this.fieldGroup.setItemDataSource( null );
}
@WebServlet ( urlPatterns = "/*" , name = "MyUIServlet" , asyncSupported = true )
@VaadinServletConfiguration ( ui = MyUI.class , productionMode = false )
public static class MyUIServlet extends VaadinServlet
{
}
}
在点击任何按钮(初始状态)之前,这些行被执行:
TextField nameField = null;
//...
this.nameField = new TextField( "Name:" );
文档说:
public TextField(java.lang.String caption)
Constructs an empty TextField with given caption.
所以您的应用程序中的所有文本字段都是空值。但是......之后你使用:
this.fieldGroup.bind( this.nameField , "name" );
该值应该为空吗? [bind()
](https://vaadin.com/api/com/vaadin/data/fieldgroup/FieldGroup.html#bind(com.vaadin.ui.Field, java.lang.Object)) 的文档再次说:
Binds the field with the given propertyId from the current item. If an item has not been set then the binding is postponed until the item is set using
setItemDataSource(Item)
.
所以必须用这个方法才能看到bind
效果。
您问:但是为什么那些 "null" 字符串默认不出现?
我希望我的解释对您来说是清楚的,最初每个 TextField 都有 empty 值。而在调用bind()
函数之后,它只在setItemDataSource(Item)
之后影响视图,但是你在button的clickListener中调用这个函数要晚得多。所以最初很好,所有字段都有空值。
尝试添加 this.nameField.setNullRepresentation("");
并在每个字段上调用相同的方法,根据 Book of Vaadin 它应该可以解决您的问题。