Skip to content

Section Annotations

These annotations control the structural slots of a page — named form sections, the header area, the footer area, and the toolbar strip. They let you organise fields and actions without writing any layout code.


Target: FIELD, METHOD

Groups the annotated field and all subsequent fields under a named section heading within a form. A new section begins at each @Section annotation and ends at the next one. Each section can have its own column count, giving you fine-grained layout control within a single page.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Section {
String value(); // section title (required)
int columns() default 1;
String style() default "";
}
AttributeTypeDefaultDescription
valueStringSection heading label, displayed as a visible separator (required)
columnsint1Number of form columns inside this section
styleString""Inline CSS applied to the section container
public class CustomerForm {
@Section("Personal data")
String firstName;
String lastName;
LocalDate birthDate;
@Section(value = "Contact", columns = 2)
String email;
String phone;
String address;
}

The Personal data section uses the default single-column layout. The Contact section switches to two columns. Fields belong to whichever section was declared most recently above them.


Target: FIELD

Marks a field to be rendered in the page header area, above the main form content. Use this for prominent display components such as avatars, banners, or status summaries.

No attributes.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Header {}
public class UserProfilePage {
@Header
Component profileBanner;
String username;
String email;
}

Target: FIELD

Marks a field to be rendered in the page footer area, below the main form content. Suitable for summary statistics, legal notices, or secondary action areas.

No attributes.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Footer {}
public class ReportPage {
List<ReportRow> rows;
@Footer
Component totalsSummary;
}

Target: FIELD, METHOD

Places the annotated field or method in the view toolbar, the strip displayed at the top of the page. Methods annotated with @Toolbar become toolbar buttons; fields become toolbar components.

Combine @Toolbar with @Action to add behaviour such as form validation or confirmation dialogs before the method runs.

No attributes.

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Toolbar {}
AllTypesForm.java
@UI("/all-types")
@Title("All Types Form")
public class AllTypesForm {
@NotEmpty
String text;
int count;
boolean active;
@Button
public Message save() {
return new Message("Saved: " + text);
}
@Toolbar
public Message refresh() {
return new Message("Refreshed!");
}
}

From the CreateReleaseForm demo:

@Toolbar
@Action(validationRequired = true)
Object create() {
var businessKey = UUID.randomUUID().toString();
return URI.create("/workflow/processes/" + businessKey + "?returnTo=/controlPlane/releases");
}

The Product record in the admin-panel demo places a doNothing method in the detail toolbar:

record Product(
@NotEmpty @EditableOnlyWhenCreating String id,
@NotEmpty String name,
@HiddenInList String description,
boolean certified,
ProductStatus status,
ColumnActionGroup action,
@Colspan(2) List<ProductComponent> components
) implements Identifiable {
@Toolbar
public void doNothing() {
log.info("do nothing");
}
}

The annotations compose naturally. The following OrderForm example shows sections with different column counts, toolbar actions for save and cancel, and a footer summary component:

public class OrderForm {
@Section(value = "Customer", columns = 2)
String customerId;
String customerName;
@Section(value = "Items", columns = 1)
List<OrderLine> lines;
@Section(value = "Totals", columns = 2)
double subtotal;
double vatAmount;
double total;
@Footer
Component paymentTerms;
@Toolbar
void save() { /* persist the order */ }
@Toolbar
void cancel() { /* discard and navigate back */ }
}
  • The Customer section renders customerId and customerName side-by-side in two columns.
  • The Items section stretches lines across the full width.
  • The Totals section returns to a two-column layout for the numeric fields.
  • paymentTerms appears in the footer slot below all sections.
  • save and cancel are rendered as buttons in the toolbar at the top of the page.