Problem to center buttons into Form footer

Hi Everybody,

I have a problem to center buttons into Form footer.

Here my code :

public static AbstractLayout createProposalFormByState(Proposal proposal, ProposalStepStates states) throws ProposalException {
		
		// Item pour la proposition
		BeanItem<Proposal> proposalItem = new BeanItem<Proposal>(proposal);

		final VerticalLayout vLayout = new VerticalLayout();
		vLayout.setMargin(true);
		vLayout.setWidth("100%");
		vLayout.setHeight(null);
		
		final Form proposalForm = new Form();
		proposalForm.setCaption(null);
		proposalForm.setWidth(null);
		proposalForm.getLayout().setWidth(null);
		
		proposalForm.setWriteThrough(false); // Il faut valider pour enregistrer via "Appliquer"
		proposalForm.setInvalidCommitted(false); // On interdit le commit des valeurs invalides

		// On renseigne la factory qui doit générer les champs du formulaire
		proposalForm.setFormFieldFactory(new ProposalFieldFactory());
		proposalForm.setItemDataSource(proposalItem); // on bind les champs sur notre Entity "Proposal"

		// Affichage des champs en fonction de l'état de la "Proposition"
		switch (states) {
		case PROPOSAL:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
					"name", "shortDescription", "chiefProjectName", "source",
					"businessObjectives", "expiries" }));
			break;
		case VAL_PROPOSAL:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
			"proposalComments"}));
			break;
		case CRITERIA:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
					"strategySupport", "extraordinary", "risk", "highWorkload", 
					"highCost", "unitBudgeted", "criteriaComments" }));
			break;
		case VAL_CRITERIA:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
			"acceptanceComments"}));
			break;
		case SPECIFICATION:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
					"specifications", "initialResources", "keyObjectives", "dependencies",
					"deliverablesTable", "userWorkload", "itWorkload", "initialBudget",
					"financialTable", "riskTable", "successCriteria", "macroPlanning"}));
			break;
		case VAL_SPECIFICATION:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
			"specificationsComments"}));
			break;
		case EVALUATION:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
					"strategySupportVal", "extraordinaryVal", "riskVal", "highWorkloadVal", 
					"highCostVal", "unitBudgetedVal", "criteriaValComments" }));
			break;
		case VAL_EVALUATION:
			proposalForm.setVisibleItemProperties(Arrays.asList(new String[] {
			"evaluationComments"}));
			break;
		default:
			new ProposalException("L'état " + states + " est inconnu. Impossible de générer le formulaire.");
		}		
		
		// Boutons appliquer/annuler
        HorizontalLayout buttons = new HorizontalLayout();
        
        Button apply = new Button("Appliquer", new Button.ClickListener() {

			public void buttonClick(ClickEvent event) {
                try {
                	// Validation du formulaire
                	proposalForm.commit();
                	
                	// Persistence de l'entité
                	Proposal p = ((BeanItem<Proposal>) proposalForm.getItemDataSource()).getBean();
                	FacadeFactory.getFacade().store(p);
                	event.getButton().getWindow().showNotification("Enregistré");
                }
                catch (OptimisticLockException e) {
                	event.getButton().getApplication().getMainWindow().showNotification(
						                	         "Oops, someone else modified the data "
						                	         + "simultaneously, refreshing data",
						                	         Notification.TYPE_ERROR_MESSAGE);
				}
                catch (Exception e) {
                    // Ignored, we'll let the Form handle the errors
                }
            }
        });
        buttons.addComponent(apply);
        
        Button discardChanges = new Button("Annuler",
                new Button.ClickListener() {
                    public void buttonClick(ClickEvent event) {
                    	proposalForm.discard();
                    	
                    	// Refresh de l'entité
                    	Proposal p = ((BeanItem<Proposal>) proposalForm.getItemDataSource()).getBean();
                    	if (p.getId()!=null)
                    		FacadeFactory.getFacade().refresh(p);
                    }
                });
        discardChanges.setStyleName(BaseTheme.BUTTON_LINK);        
        buttons.addComponent(discardChanges);
                
        HorizontalLayout footerLayout = new HorizontalLayout();   
        footerLayout.setWidth("100%"); // <- My Problem
        footerLayout.addComponent(buttons);
        footerLayout.setComponentAlignment(buttons, Alignment.TOP_CENTER);       
        
        proposalForm.setFooter(footerLayout);
        
		vLayout.addComponent(proposalForm);
		vLayout.setComponentAlignment(proposalForm, Alignment.MIDDLE_CENTER);
		
		return vLayout;
	}

As you can see, I have a static function that’s return a VerticalLayout with my Form. But when I add the line 109 “footerLayout.setWidth(“100%”);” (like the thread
https://vaadin.com/forum/-/message_boards/message/18553
) my buttons disappear and their HorizontalLayout container have “width=0px;”.
The “Analyse Layout” debug action return :

If I force the width of the HorizontalLayout of my buttons in pixel (setWidth(“250px” for example)) it works. How can I fix that?

Thank you :slight_smile:

Reading
chapter 6.12, Layout formatting
it says[quote]
A layout that contains components with percentual size must have a defined size!
[/quote] I think this might apply here, as you have an undefined width form with a percentual width footer layout.

Thank you for your answer.

Yes if I change the line 13 “proposalForm.setWidth(null);” and set the width with 650px for example it works.
But in the thread
https://vaadin.com/forum/-/message_boards/message/18553
he does not need to specify a defined size.

And I forgot to say that my Form is in a VerticalLayout that is itself in a Tab of an Accordion which has a defined size. Strange…

I’m not quite sure of your use case, but could you set eg. 100% width to the form and its layout? That would probably fix the problem as then you would have defined widths all the way.

Ok it works and no error with the debug Layouts Analyzer.

But now my Form is not centered in my VerticalLayout (“vLayout” instanced line 6 and the form is centered line 116) because the form size is 100%.

My goal is : have a Form centered in a Tab of Accodion and have 2 buttons (apply/cancel) in the footer of the Form centered in the Tab.