the problem
I wanted one of my Vaadin-Components to use a FormLayout. To do this the component extends FormLayout (com.vaadin.flow.component.formlayout.FormLayout). The component extends the class indirectly over an other class (should not really break the behaviour). Strangely it is not working as expected. It shows all the elements in the layout closely side by side, even though the number of columns is defined.
import com.example.application.model.Memory;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.html.Span;
// AbstractPcPartCard extends FormLayout
@Tag("memory-component")
public class MemoryCard extends AbstractPcPartCard {
private static final long serialVersionUID = -8954098740536795286L;
Memory pcPart;
public MemoryCard(Memory pcPart) {
this.pcPart = pcPart;
Span name = new Span(pcPart.getName());
Span price = new Span(this.getPrice());
Span stock = new Span(this.getStock());
Span config = new Span(this.getConfiguration());
Span form = new Span(this.getFormFactor());
Span frequency = new Span(this.getFrequency());
setResponsiveSteps(
new ResponsiveStep("0", 3),
new ResponsiveStep("1200px", 6));
add(name, price, stock, config, form, frequency);
// we should not need to add a layout, because the component itself is the layout.
}
// getters
}
Here is what it looks like: everything side by side
hacky solution
It works correctly if I create a new FormLayout in the Component and add it to the Component. So in a way, I now have a FormLayout in a Formlayout. The Component itself does not need to extend FormLayout in this case. Extending Component (com.vaadin.flow.component.formlayout.FormLayout) would be sufficient.
import com.example.application.model.GraphicsCard;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.html.Span;
import java.util.stream.Collectors;
@Tag("graphics-card-component")
public class GraphicsCardCard extends AbstractPcPartCard {
private static final long serialVersionUID = -5813124388374902829L;
GraphicsCard pcPart;
public GraphicsCardCard(GraphicsCard pcPart) {
this.pcPart = pcPart;
FormLayout layout = new FormLayout();
Span name = new Span(pcPart.getName());
Span price = new Span(this.getPrice());
Span stock = new Span(this.getStock());
Span model = new Span(this.getCardModel());
Span connections = new Span(this.getConnections());
Span pci = new Span(this.getPciExpressVersion());
Span cooling = new Span(this.getCoolingSystem());
layout.add(name, price, stock, model, connections, pci, cooling);
layout.setColspan(connections, 2);
layout.setResponsiveSteps(
new FormLayout.ResponsiveStep("0", 3),
new FormLayout.ResponsiveStep("1200px", 6));
// here we add the FormLayout to the FormLayout
add(layout);
}
// getters
}
This should look like this: inserted form layout
my wish
I think the Component being a FormLayout itself is much more elegant, than creating a component that contains a FormLayout. How can I fix my FormLayout to display the data in columns?
source code
The full source code of an example project can be found on github. github example project The relevant view and components can be found in package: com.example.application.ui.views.partsComponent
the source code contains other views, some of them are problematic too, for example the view using dom-if, to use different template renderers. But this is another question on stack overflow. link to other question