Vaadin 8 and private BeanContainer

Im my app I use:

private BeanContainer<Long,TbPedido> pedidoContainer = new BeanContainer<Long,TbPedido>(TbPedido.class);

so, how I replace to new in vaadin8?

tks

There’s no replacement for Containers. Grids and select components are parameterized with the bean type and you can add the beans directly. For example:


List persons = Backend.getPersons();
Grid grid = new Grid<>(Person.class);
grid.setItems(persons);

Alejandro in my sample I use one ID in this case a Long value, so when I need to get one bean in my container I only need to use container.getItem(id), So I have this same behavior in grid with vaadin8?

This feature is no longer present in V8 Grid, since it doesn’t store any of the beans and the data provider might be lazy.

But since you’re using an in-memory ListDataProvider (because you use grid.setItems(Collection), you can get the DataProvider from Grid, and cast it to a ListDataProvider, then iterate through the items to find the item with the corresponding ID.

how to replace Item in vaadin 8

Puja Kuamri:
how to replace Item in vaadin 8

There’s no replacement for it. The Item interface has been removed completly in Vaadin 8. Now you can use your own types (domain) without having to worry about Property, Item, and Container.

This is what I confused. I want to build a Grid with some data in a Product bean and a extral String column. I found out I can use IndexedContainer or other container to customize a grid in old version. But V8 doesn’t support it any more. It makes customize grid so difficult. More works.

Hey Yong Liu !

As i understand, you want to add some collumns that are dependding from the Bean model, and a column that is depending on something else ?

there are numeriuous ways to do it, to find the best solution for you, i need more data :slight_smile:

you could use a suplier, which fetchs the right data for the custom column for example

Or you could use a Wrapper Object, which has the Bean as parameter, and also data for the custom Column.

If you would post the old way for that one column, maybe it is easyer to help you then :slight_smile:

You can do that in addColumn(…) method by giving lambda expression for value provider, e.g. the one below sets all cells in the column “String” to have value “My string”.

addColumn(myString -> "My string").setCaption("String");

And you can have a method that depends from some inputs to produce the value as well, something like.

addColumn(myString -> getString(..)).setCaption("String");

Thank you,guys. It’s really help. Finially I wrapped my bean with some columns.
@Vilius. Do you know any sample or demo about how to use supplier?

Do you guys know how to binding CheckBox with a boolean property?

CheckBox residential = new CheckBox("Residential");
recipientAddressBinder.bind(residential, Address::getResidential,Address::setResidential);

My residential in Address is a boolean.
The binder match the string with checkbox’s caption, not the value.
Do you have any ideas? Thank you.

I guess I can use withConverter to solve it. But I don’t know how.

Can you share how you’re defining your Binder?

private Binder<Address> recipientAddressBinder;
recipientAddressBinder = new Binder<>(Address.class);

I also binded other components with Address. They are working well.

TextField country = new TextField("Country");
		TextField contactName = new TextField("Contact Name");
		TextField companyName = new TextField("Company Name");
		companyName.setWidth("100%");
		TextField add1 = new TextField("Address Line 1");
		TextField add2 = new TextField("Address Line 2");
		TextField add3 = new TextField("Address Line 3");
		TextField postalCode = new TextField("Postal Code");
		TextField stateNprovinceCode = new TextField("State/Province");
		TextField city = new TextField("City");
		TextField telephone = new TextField("Telephone");
		CheckBox residential = new CheckBox("Residential");
		residential.addStyleName("");
		recipientContactBinder = new Binder<>(Contact.class);
		recipientAddressBinder = new Binder<>(Address.class);
		recipientContactBinder.bind(contactName, Contact::getPersonName, Contact::setPersonName);
		recipientContactBinder.bind(companyName, Contact::getCompanyName, Contact::setCompanyName);
		recipientContactBinder.bind(telephone, Contact::getPhoneNumber, Contact::setPhoneNumber);
		recipientAddressBinder.bind(country, Address::getCountryCode, Address::setCountryCode);
		//recipientAddressBinder.bind(add1,Address::getStreetLine1,Address::setStreetLine1);
		//recipientAddressBinder.bind(add2,Address::getStreetLine2,Address::setStreetLine2);
		//recipientAddressBinder.bind(add3,Address::getStreetLine3,Address::setStreetLine3);
		recipientAddressBinder.bind(postalCode, Address::getPostalCode, Address::setPostalCode);
		recipientAddressBinder.bind(stateNprovinceCode, Address::getStateOrProvinceCode,
				Address::setStateOrProvinceCode);
		recipientAddressBinder.bind(city, Address::getCity, Address::setCity);
		//recipientAddressBinder.bind(residential, Address::getResidential,Address::setResidential);

		GridLayout recipientLayout = new GridLayout(3,6);
		recipientLayout.setSizeFull();
		recipientLayout.setSpacing(false);
		recipientLayout.setMargin(false);
		recipientLayout.addComponent(country,0,0);
		recipientLayout.addComponent(residential,2,0);
		recipientLayout.addComponent(contactName,0,1);
		recipientLayout.addComponent(companyName,1,1,2,1);
		recipientLayout.addComponent(add1,1,2,2,2);
		recipientLayout.addComponent(add2,1,3,2,3);
		recipientLayout.addComponent(add3,1,4,2,4);
		recipientLayout.addComponent(postalCode,0,4);
		recipientLayout.addComponent(stateNprovinceCode,0,3);
		recipientLayout.addComponent(city,0,2);
		recipientLayout.addComponent(telephone,1,0);
		Panel recipientPanel = new Panel("<h3><strong>Recipient Information</strong></h3>");
		recipientPanel.setSizeFull();
		recipientPanel.setHeight("50%");
		recipientPanel.setContent(recipientLayout);

@Yong Liu about Supplier.

As i understood, you wanted to add some Columns, which represent something, that is not in the bean.
(maybe i also totaly misunderstood you, sorry if this is the case, it is late :slight_smile:

As the Supplier gives you a at that moment when you are “asking” him to, withou you giving anything as request, i was thinking of it as possible Solution.

Example for Grid.

simple bean class

public class Pojo {

    private Long id;
    private String name;

    public Pojo(final Long id, final String name) {
        this.id = id;
        this.name = name;
    }
	//getter setter
}

a minimalistic grid that shell show the name of pojo, and also completely undependent column, something completely random :slight_smile:

		Random rn = new Random();
        Supplier<Integer> supplier = () -> rn.nextInt(1000);
 
		Grid<Pojo> grid = new Grid<>();

        grid.addColumn(Pojo::getName)
                .setCaption("Name");
				
		 grid.addColumn(p -> supplier.get())
                .setCaption("TimeStamp");
		
		Collection<Pojo> pojos = new ArrayList<>();
        LongStream.range(0, 100)
                .forEach(i -> pojos.add(new Pojo(i, "Pojo Nr.:" + String.valueOf(i))));

        grid.setItems(pojos);
	as a result, i got this grid

I dont know if it is fitting for you, just wanted to show a way of adding columns, that have nothing to do with the actual bean. If you want something like this but to give Bean as a Parameter, try “Function<T, R>”

Represents a function that accepts one argument and produces a result.

about the recipientAddressBinder.

just a quick hope, you wrote

CheckBox residential = new CheckBox("Residential");
recipientAddressBinder.bind(residential, Address::getResidential,Address::setResidential);

residential is boolean, the default getter should be isResidential not getResidential

maybe that was the issue ?

Thank you @Vilius. That’s what I want. Thank you very much.

I’m not sure the binder can use as recipientAddressBinder.bind(residential,Address::isResidential). I looked up javadoc. But can’t find any infomation about it. And it can’t use as recipientAddressBinder.bind(residential,Address::isResidential,Address::setResidential).The binder will validate getter and setter.

<Boolean> Binding<Address, Boolean> com.vaadin.data.Binder.bind(HasValue<Boolean> field, ValueProvider<Address, Boolean> getter, Setter<Address, Boolean> setter)

You are very welcome Yong Liu.

Can you check what the boolean getter and setter Methods in your model class are?

[if you use lomebock, it is dependent if its Boolean or boolean.]
(https://projectlombok.org/features/GetterSetter)

if they are “human written” there can be mutants like “setIsResidential” and stuff like that :slight_smile:

I tried your lines at an simple example at home yesterday, and it worked with my example model class, which had “is” at begin :slight_smile:

Thank you for reminding me. I tracked down every step in my project. The problem is rs.getString("RESIDENTL")=="Y"?true:false not working. I changed to rs.getString("RESIDENTL").equals("Y")?true:false. The CheckBox is working well now.

btw, you can simply change the code to

return (“Y”).equals.(rs.getString(“RESIDENTL”));

without ?true:false; Its shorter, and wont throw an Null Pointer if rs.getString(“RESIDENTL”) == null :slight_smile:

Thanks.@Vilius.
I have a question about execute server-side funcation in a ButtonClickEvent.
My code kind like below.

public class FedexShipView extends CssLayout implements View{
	private static ContentBean cb = new ContentBean();
	private Binder<Address> addressBinder;
	public FedexShipView(){
		TextField add = new TextField();
		addressBinder.bind(add,Address::getAddress,Address::setAddress);
		Button clear = new Button("clear",new ClickListener(){
			@Override
			public void buttonClick(ClickEvent event) {
				
				clearForm();
				**How to execute server-side function at here?**
				
				}
			}
		});
		CssLayout cly = new CssLayout();
		cly.addComponents(clear,add);
	}
	public void setContent(ContentBean cb){
		this.cb = cb;
		addressBinder.readBean(cb.getAddress());
	}
	public void clearForm(){
		addressBinder.removerBean();
	}
}

I understand addressBinder is a server-side object and ButtonClickEvent comes from client-side. But how to make it work?