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");
}
// Each child fills its cell's width, so a JTextField(20)'s preferred width yields.
public Map<String,String> childCss(Container parent, Component child) {
return CssEmittingLayoutManager.sizingCss(true, false);
}
}
// 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), with
sizingCss(boolean, boolean) building the pair. This is the rule a CSS stretch alone
cannot express: a cell's justify-self: stretch grows only an auto-sized child,
so a child carrying its preferred width keeps it until the layout says otherwise. 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) sizingCss(boolean layoutSizesWidth, boolean layoutSizesHeight) The per-child sizing pair forchildCss(Container, Component): which axes of the child this layout sizes itself, and which it leaves to the child's preferred size.Methods inherited from interface LayoutManager
addLayoutComponent, minimumLayoutSize, preferredLayoutSize, removeLayoutComponent
-
Method Details
-
containerCss
-
childCss
-
sizingCss
The per-child sizing pair forchildCss(Container, Component): which axes of the child this layout sizes itself, and which it leaves to the child's preferred size. Saytruefor an axis the layout sizes (the pref is ignored, asBorderLayoutNORTH ignores the pref width, or aGridBagLayoutcell whosefillcovers the axis),falseto let the pref stand.- Returns:
- a new map holding both variables; merge it into the child's CSS
-
cssLayoutName
Name used in the non-Div ERROR log forcontainerCss(Container)writes. -
layoutContainer
- Specified by:
layoutContainerin interfaceLayoutManager
-