Java/Vaadin-FormLayout自定义隐藏组件实现 [英] Java/Vaadin - FormLayout custom hidden component implementation

查看:85
本文介绍了Java/Vaadin-FormLayout自定义隐藏组件实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用vaadin开发Web应用程序,当前正在尝试实现通讯簿.我查看了github以外的官方实现,并尝试以此为基础.

I am working on a web application in vaadin and am currently trying to implement an address book. I viewed the official implementations off github and tried to build off that.

我遇到的问题与联系表格有关.我希望能够单击网格中的一行并打开一个包含该信息的表单. (类似于他们的示例中的操作)

The issue I am experiencing is with the contact form. I want to be able to click a row in the grid and open up a form containing the information. (Similar to how it is done on their example)

该组件未按预期反应.如果我将组件直接添加到主布局中,并尝试切换可见性,则会使视图混乱.使它起作用的唯一方法是根据需要添加和删除该组件,尽管我不喜欢这种解决方案,也不是很优雅.

The component doesn't react as intended however. If I added the component directly to the main layout and try to toggle visibility it messes up the view. The only way I have gotten it to work is by adding and removing the component as its needed, though I do not like this solution, nor is it elegant.

这是当前的实现方式

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);
    }
  }
}

第一张图显示了将表单添加到布局并将其设置为隐藏时视图的反应.

The first image shows how the view reacts when adding the form to the layout and setting it to hidden.

第二张和第三张图片显示了视图应该如何反应.虽然要获得理想的结果,但我必须进行草率的编码.

The second and third images show how the view SHOULD react. Though to achieve the desired results I had to do sloppy coding.

最后一个问题:

如何解决此问题?我尝试使用内部类的形式并将其创建为自己的类.我唯一的猜测是,在github实现中,他们正在将UI传递给这种形式,地址簿扩展了UI,而不是将其作为组件.

How can I fix this issue? I have tried using an inner class for the form and creating it as its own class. My only guess is that in the github implementations they are passing the UI to this form where the address book extends UI instead of being a component.

推荐答案

发生的事情是,您拥有的组合会离开视图(水平布局),且其大小未定义并且将大小设置为full并隐藏表单一个奇怪的结果.这样,如果使用某些开发人员工具检查结果元素,您将看到视图(水平布局)的高度为147px,网格表包装器的高度为24px:

What happens, is that the combination you have wile leaving your view (which is a horizontal layout) with size undefined and setting sizes to full plus hiding the form has a weird result. As such, if you inspect the resulting elements using some developer tools, you'll see that your view (horizontal layout) will have a height of 147px and grid table wrapper will have a height of 24px:

如果将视图高度设置为100%,则它将扩展为占据所有可用空间,这可能不是您想要的:

If you were to set your view height to 100%, then it would expand to occupy all the available space, which is probably not what you want:

因此,只需保留未定义的left大小,并丢失mainLayout(您的视图已经扩展了HorizontalLayout,因此只需使用它),然后再回到使用contactForm.setVisible(true/false).这样,left布局将扩展以适应为操作栏+网格计算的任何大小:

So, just leave the left size undefined, and lose the mainLayout (your view already extends HorizontalLayout so just use that) and go back to using contactForm.setVisible(true/false). This way the left layout will expand to accommodate whatever size is calculated for the action bar + grid:

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();
    left.setExpandRatio(contactList, 1);

    addComponents(left, contactForm);
    contactForm.setVisible(false);
}

建议.如果有人可以通过提供有关此情况下尺寸计算方式的更多见解来改善此答案,请务必编辑此答案!

P.S. if anyone can improve this answer by providing more insight regarding how the sizes are calculated in this case, please do edit this answer!

这篇关于Java/Vaadin-FormLayout自定义隐藏组件实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆