Interface CssEmittingLayoutManager
- All Superinterfaces:
LayoutManager
- All Known Implementing Classes:
BorderLayout, BoxLayout, FlowLayout, GridBagLayout, GridLayout, GroupLayout
LayoutManager that positions children by emitting CSS onto the
container's peer <div> (and optionally onto each child) instead of the pixel
setBounds arithmetic a desktop LayoutManager does — there is no
synchronous child-size measurement in the browser to drive that arithmetic. This is
the seam a migrator implements to teach the emulator a custom Swing layout; every
built-in (FlowLayout, BorderLayout, BoxLayout,
GridLayout, GridBagLayout, GroupLayout) is one of these.
Implement containerCss(Container); add childCss(Container, Component) only when children need
per-item CSS. The framework drives layoutContainer(Container) for you — you never touch
EHelper or a Vaadin Element:
// A two-column form: labels hug their content, fields absorb the rest.
public class TwoColumnLayout implements CssEmittingLayoutManager {
public Map<String,String> containerCss(Container parent) {
return Map.of("display", "grid",
"grid-template-columns", "auto 1fr",
"gap", "4px 8px");
}
}
// parent.setLayout(new TwoColumnLayout()); // children flow into the grid
A container whose installed layout is not a CssEmittingLayoutManager
— a hand-rolled pixel LayoutManager — can't be translated: Container.doLayout()
WARNs once and falls back to a readable vertical stack (M1D_custom_layoutmanager).
Implementation details
Call order (contract). Within one layoutContainer(Container) pass
containerCss(Container) runs exactly once, before any childCss(Container, Component) call. A layout
whose per-child CSS is a byproduct of a whole-container analysis (GridBag track
weights, GroupLayout bands) may compute in containerCss, stash the result, and
read it back in childCss — GridBagLayout and GroupLayout do
exactly this. A layout whose per-child CSS is already known at add time can instead
write it eagerly from addLayoutComponent and skip childCss entirely —
BorderLayout does that with grid-area.
Child sizing (D_layout_owns_child_sizing). A child's
Component.setPreferredSize(Dimension) does not write width / height
outright — it writes width: var(--emul-layout-w, Npx), and the parent layout
rules on each axis by writing that variable from childCss(Container, Component):
com.vaadin.swingbridge.surrogates.util.LayoutCss.sizingCss(layoutSizesWidth, layoutSizesHeight)
builds the pair. Say true for an axis this layout sizes itself (the pref is
ignored, as BorderLayout NORTH ignores the pref width), false to let
the pref stand. A layout that returns neither variable leaves whatever the last layout
wrote in place, so emit both for every child — sizingCss always does.
Map semantics. A returned map applies key-by-key: a value sets the property,
null removes it, an absent key is left untouched — so a layout can clear a
sibling layout's leftover keys without clobbering co-owned ones (a field surrogate's
inline width). containerCss(Container) writes gate on the peer being a
<div> (a non-Div peer gets an ERROR and no write); childCss(Container, Component) writes do
not gate — a child is any element.
-
Method Summary
Modifier and TypeMethodDescriptionPer-child CSS for onechildofparent;null(the default) means the child needs none.containerCss(Container parent) Container-wide CSS forparent's peer content element (its<div>).default StringName used in the non-Div ERROR log forcontainerCss(Container)writes.default voidlayoutContainer(Container parent) Methods inherited from interface LayoutManager
addLayoutComponent, minimumLayoutSize, preferredLayoutSize, removeLayoutComponent
-
Method Details
-
containerCss
-
childCss
-
cssLayoutName
Name used in the non-Div ERROR log forcontainerCss(Container)writes. -
layoutContainer
- Specified by:
layoutContainerin interfaceLayoutManager
-