Java/Vaadin - FormLayout custom hidden component implementation

我们两清 提交于 2019-12-13 17:14:22

问题


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.

Here is the current implementation

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.

Finally the question:

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.


回答1:


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:

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:

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!



来源:https://stackoverflow.com/questions/45020489/java-vaadin-formlayout-custom-hidden-component-implementation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!