Vaadin - Unable to center components - design issue
Asked Answered
F

2

0


I'm not familiar with css, and unfortunately i dont have much time to investigate this so I've choosen build-in Vaadin ValoTheme.

I have a verticallayout with two objects - label and panel, both components should be centered. This is what i'm trying to archieve:

This is what i want to archive

Unfortunately, after enumorous attempts to make simlar, i got this

enter image description here

My code:

public class SplashScreen extends VerticalLayout implements View {

private static final int PANEL_WIDTH = 320;
private static final int PANEL_HEIGHT = 140;
private static final int BUTTON_WIDTH = 270;
private static final int BUTTON_HEIGHT = 70;

private ComponentHelper componentHelper;
private Panel panel;
private VerticalLayout formLayout;
private Label welcome;
private Button toLoginPage;

public SplashScreen() {
    initComponents();
    buildSplashView();
}

protected void initComponents() {
    componentHelper = ComponentHelper.getInstance();
    panel = componentHelper.createPanel("", PANEL_WIDTH, PANEL_HEIGHT);
    welcome = componentHelper.createH3Label("Welcome");
    formLayout = componentHelper.createVerticalLayout();
    toLoginPage = componentHelper.createFriendlyButton("To Login Page", BUTTON_WIDTH, BUTTON_HEIGHT);
    toLoginPage.addClickListener(this::redirect);
}

private void buildSplashView() {
    addComponent(panel);
    addComponent(welcome);
    formLayout.addComponent(toLoginPage);
    formLayout.setComponentAlignment(toLoginPage, Alignment.MIDDLE_CENTER);
    panel.setContent(formLayout);
    panel.setStyleName(ValoTheme.PANEL_BORDERLESS);
    setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
    setHeight(100, Unit.PERCENTAGE);
}

public void redirect(Button.ClickEvent event) {
    try {
        Thread.sleep(Constants.TRANSITION_TIME_DELAY);
        getUI().getNavigator().navigateTo(ViewTokens.SIGNIN);
    } catch (InterruptedException e) {
    }
}

@Override
public void enter(ViewChangeListener.ViewChangeEvent viewChangeEvent) {

    }
}

What i'm doing wrong? I can't fully understand how to design layouts properly( Before asking this question, i read Vaadin Book)

Note: 'componentHelper' intended for object creation with some minimal ValoTheme styling.

Thanks for suggestions

UPDATE: Result of using welcome.setSizeUndefined();

welcome.setSizeUndefined();

UPDATE 2: modified @qtdzz code to reproduce an issue:

private void buildSplashView() {
    addComponent(welcome);
    addComponent(text1);
    addComponent(panel);
    setComponentAlignment(welcome, Alignment.MIDDLE_CENTER);
    setComponentAlignment(text1, Alignment.MIDDLE_CENTER);
    setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
    setSizeFull();

    panel.setSizeUndefined();
    panel.setContent(formLayout);
    welcome.setSizeUndefined();
    formLayout.addComponent(toLoginPage);
    formLayout.setComponentAlignment(toLoginPage, Alignment.MIDDLE_CENTER);
    formLayout.setSizeFull();
}
Fib answered 1/1, 2017 at 15:32 Comment(2)
welcome.setSizeUndefined() should make the alignment workKeramic
@Keramic Screenshot provided.Fib
L
1

In my opinion, it will be easier if you put the welcome label inside the formLayout and set alignment for it.

Here is my proposal, hope this help:

private void buildSplashView() {
    addComponent(panel);
    setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
    setSizeFull();

    panel.setContent(formLayout);
    panel.setStyleName(ValoTheme.PANEL_BORDERLESS);

    formLayout.addComponent(welcome);
    welcome.setSizeUndefined();
    formLayout.addComponent(toLoginPage);
    formLayout.setComponentAlignment(toLoginPage, Alignment.MIDDLE_CENTER);
    formLayout.setComponentAlignment(welcome, Alignment.MIDDLE_CENTER);
    formLayout.setSizeFull();
}

Here is the screenshot for above code: enter image description here

UPDATE1: Based on your code and according to my understand, one solution could be explained in the following way. If you add "text1", "welcome" and "panel" into it, it will look like the bellow picture: enter image description here So to make them align middle center, we need to set expandRatio for "text1" and "panel" to 0.5, and 0 for "welcome". Then make "text1" to be Alignment.BOTTOM_CENTER, "welcome" to be Alignment.MIDDLE_CENTER, "panel" to be Alignment.TOP_CENTER, and the toLoginPage button to be Alignment.TOP_CENTER. Then the view will look like bellow: enter image description here Code for above picture:

private void buildSplashView() {
    addComponent(text1);
    addComponent(welcome);
    addComponent(panel);
    setComponentAlignment(welcome, Alignment.MIDDLE_CENTER);
    setComponentAlignment(text1, Alignment.BOTTOM_CENTER);
    setComponentAlignment(panel, Alignment.TOP_CENTER);
    setSizeFull();
    setExpandRatio(text1,0.5f);
    setExpandRatio(panel,0.5f);

    panel.setSizeUndefined();
    panel.setContent(formLayout);

    welcome.setSizeUndefined();
    text1.setSizeUndefined();

    formLayout.addComponent(toLoginPage);
    formLayout.setComponentAlignment(toLoginPage, Alignment.TOP_CENTER);
    formLayout.setSizeFull();
}

BTW, I feel that really hard to maintain and understand the solution above (e.g. if you want to add another text, you have to add it between text1 and welcome). My recommend solution is to have one wrapper layout (vertical layout) to wrap all component and set it to be middle_center of the base layout. The solution for this is:

 private void buildSplashView() {
    wrapperLayout.addComponent(text1);//wrapperLayout is a vertical Layout
    wrapperLayout.addComponent(welcome);
    wrapperLayout.addComponent(panel);
    wrapperLayout.setComponentAlignment(welcome, Alignment.MIDDLE_CENTER);
    wrapperLayout.setComponentAlignment(text1, Alignment.MIDDLE_CENTER);
    wrapperLayout.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);

    addComponent(wrapperLayout);
    setComponentAlignment(wrapperLayout, Alignment.MIDDLE_CENTER);
    setSizeFull();

    panel.setSizeUndefined();
    panel.setContent(formLayout);

    welcome.setSizeUndefined();
    text1.setSizeUndefined();

    formLayout.addComponent(toLoginPage);
    formLayout.setComponentAlignment(toLoginPage, Alignment.MIDDLE_CENTER);
    formLayout.setSizeFull();
}

With this approach, you can add any components into the wrapperLayout, it will be automatically align middle_center.

Lacking answered 1/1, 2017 at 17:53 Comment(4)
thank you for your suggestion, it worked perfectly. It took a while to playaround with it. Your example demonstrates how to add label onto panel. That is fine, but if i have to make one more label above the panel - how do i do that? (you see, modifying your example, layout keeps the same as it should be (centered), but after each new object added on layout, it makes huge gap between objects. Your suggestion required.Fib
please see the code marked as "Update 2:" for complete understanding my question.Fib
[@qtdzz] please join me on conversation here: chat.stackoverflow.com/rooms/132120/vaadin-layoutsFib
@Reborn I updated the answer based on your concerns. Hope it help :)Lacking
W
1
VerticalLayout outerVLayout = new VerticalLayout();
outerVLayout.setSizeFull();

VerticalLayout innerVLayout = new VerticalLayout();
innerVLayout.setSizeUndefined();
outerVLayout.addComponent(innerVLayout);
outerVLayout.setComponentAlignment(innerVLayout, Alignment.MIDDLE_CENTER);

//add components to this inner vertical layout
innerVLayout.addComponent(label);
//textfields are fine but, in case of a label, remember to do this: 
label.setSizeUndefined();

I hope it helps. :-)

Wive answered 6/1, 2017 at 4:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.