我正在 vaadin 开发一个 Web 应用程序,目前正在尝试实现一个地址簿。我查看了 github 上的官方实现,并试图以此为基础。
我遇到的问题是联系表格。我希望能够单击网格中的一行并打开一个包含信息的表单。(类似于在他们的示例中如何完成)
但是,该组件没有按预期做出反应。如果我将组件直接添加到主布局并尝试切换可见性,它会弄乱视图。我让它工作的唯一方法是根据需要添加和删除组件,尽管我不喜欢这个解决方案,也不优雅。
这是当前的实现
package com.example.ecenter.view;
import com.vaadin.data.Binder;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.Button;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import io.valhala.ecenter.temp.Client;
import java.util.Arrays;
import java.util.List;
@SpringView(name = AddressBookView.VIEW_NAME)
@SpringComponent
public class AddressBookView extends HorizontalLayout implements View
{
public static final String VIEW_NAME = "Address Book";
Grid<Client> contactList = new Grid<>(Client.class);
private List<Client> clients = Arrays.asList(
new Client("Sernie", "A", "123 Test St.", "test@gmail.gov", "555-555-5554"),
new Client("Ernie", "B", "123 Test St.", "test@gmail.com", "555-555-5555"),
new Client("Bernie", "C", "123 Test St.", "test@gmail.net", "555-555-5556"),
new Client("Ayy", "Lmao", "123 Test St.", "test@gmail.org", "555-555-5557"),
new Client("Dax", "E", "123 Test St.", "test@gmail.net", "555-555-5558"),
new Client("Avorion", "F", "123 Test St.", "test@gmail.net", "555-555-5559"),
new Client("Xanion", "G", "123 Test St.", "test@gmail.net", "555-555-5560"),
new Client("Trinium", "H", "123 Test St.", "test@gmail.net", "555-555-5561"),
new Client("Naonite", "I", "123 Test St.", "test@gmail.net", "555-555-5562"),
new Client("Squillium", "J", "123 Test St.", "test@gmail.net", "555-555-5563"),
new Client("Picard", "K", "123 Test St.", "test@gmail.net", "555-555-5564"),
new Client("Richard", "L", "123 Test St.", "test@gmail.net", "555-555-5565"),
new Client("Rickard", "M", "123 Test St.", "test@gmail.net", "555-555-5566"),
new Client("Bobby", "N", "123 Test St.", "test@gmail.net", "555-555-5567"),
new Client("Bob", "O", "123 Test St.", "test@gmail.net", "555-555-5568"),
new Client("Ron", "P", "123 Test St.", "test@gmail.net", "555-555-5569"),
new Client("Bill", "Q", "123 Test St.", "test@gmail.net", "555-555-5570"),
new Client("Greg", "R", "123 Test St.", "test@gmail.net", "555-555-5571"),
new Client("Juan", "S", "123 Test St.", "test@gmail.net", "555-555-5572"),
new Client("Squidward", "T", "123 Test St.", "test@gmail.net", "555-555-5573"));
private ContactForm contactForm = new ContactForm();
private TextField filter = new TextField();
private Button addContact = new Button("New Client");
public AddressBookView()
{
initConfig();
buildLayout();
}
private void buildLayout()
{
HorizontalLayout actionBar = new HorizontalLayout(filter, addContact);
actionBar.setWidth("100%");
filter.setWidth("100%");
actionBar.setExpandRatio(filter, 1);
VerticalLayout left = new VerticalLayout(actionBar, contactList);
left.setSizeFull();
contactList.setSizeFull();
left.setExpandRatio(contactList, 1);
HorizontalLayout mainLayout = new HorizontalLayout(left);
mainLayout.setSizeFull();
mainLayout.setExpandRatio(left, 1);
//HorizontalLayout test = new HorizontalLayout(contactForm);
addComponent(mainLayout);
//addComponent(test);
/*
* even using a different layout still messes it up
*/
//contactForm.setVisible(false);
}
private void initConfig()
{
addContact.addClickListener(event ->
{
addComponent(contactForm);
contactForm.setClient(new Client());
});
filter.setPlaceholder("Search clients...");
addContact.addStyleName(ValoTheme.BUTTON_PRIMARY);
//filter.addValueChangeListener(e -> refreshContacts(e.getText()));
contactList.setSelectionMode(Grid.SelectionMode.SINGLE);
contactList.setColumns("firstName", "lastName");
contactList.setItems(clients);
contactList.asSingleSelect().addValueChangeListener(event ->
{
if(event.getValue() == null)
{
removeComponent(contactForm); //quick and dirty workaround
}
else
{
addComponent(contactForm); //quick and dirty workaround
/* contactForm.setVisible(true); messes up the entire view */
contactForm.setClient(event.getValue());
}
});
}
@Override
public void enter(ViewChangeEvent event) {
}
private class ContactForm extends FormLayout
{
private Client client;
private Button save, delete, cancel;
private TextField firstName, lastName, email, address, phoneNumber;
private Binder<Client> binder = new Binder<>(Client.class);
public ContactForm()
{
initConf();
initLayout();
setSizeUndefined();
binder.bindInstanceFields(this);
}
public void initConf()
{
save = new Button("Save");
cancel = new Button("Cancel");
firstName = new TextField();
firstName.setPlaceholder("First Name");
lastName = new TextField();
lastName.setPlaceholder("Last Name");
email = new TextField();
email.setPlaceholder("Email Address");
address = new TextField();
address.setPlaceholder("Address");
phoneNumber = new TextField();
phoneNumber.setPlaceholder("Phone Number");
}
public void initLayout()
{
HorizontalLayout actions = new HorizontalLayout(save, cancel);
actions.setSpacing(true);
addComponents(actions, firstName, lastName, email, address, phoneNumber);
}
public void setClient(Client client)
{
//setVisible(true);
this.client = client;
binder.setBean(client);
}
}
}
第一张图片显示了在将表单添加到布局并将其设置为隐藏时视图的反应。
第二张和第三张图片显示了视图应该如何反应。虽然为了达到预期的结果,我不得不做草率的编码。
最后的问题:
我该如何解决这个问题?我尝试过为表单使用内部类并将其创建为自己的类。我唯一的猜测是,在 github 实现中,他们将 UI 传递给地址簿扩展 UI 而不是组件的表单。