Sierra is an open-source framework for simplifying development of Java Swing applications. It is extremely lightweight (less than 60KB) and has no external dependencies. The project's name comes from the nautical S or Sierra flag, representing the first letter in "Swing":
This guide introduces the Sierra framework and provides an overview of its key features.
Sierra is distributed via Maven Central at org.httprpc:sierra. Java 17 or later is required.
Sierra provides the UIBuilder
class, whose methods can be used to declaratively establish a hierarchy of user interface elements. The methods defined by this class form a DSL, or "domain-specific language", that makes it easy to visualize the resulting output:
row()
- produces an instance ofRowPanel
, a container that automatically arranges sub-components along the x-axiscolumn()
- produces an instance ofColumnPanel
, a container that automatically arranges sub-components along the y-axisstack()
- produces an instance ofStackPanel
, a container that automatically arranges sub-components by z-order
These components offer an alternative to the standard Java layout managers, which can often be limiting or difficult to use in practice. RowPanel
optionally aligns sub-components to baseline, similar to FlowLayout
. ColumnPanel
optionally aligns sub-components to a grid, similar to an HTML table or GridBagLayout
.
Additionally, UIBuilder
provides this method for declaring a panel's contents:
public static <C extends Component> Cell<C> cell(C component) { ... }
The returned Cell
instance can be used to further customize the layout or configuration of the provided component:
weightBy()
- specifies the amount of excess space in a container that should be allocated to the component, relative to other weighted componentswith()
- accepts a callback that can be used to set properties or invoke methods on the component
A reference to the configured component can be obtained via Cell#getComponent()
.
Finally, these UIBuilder
methods can be used to declare spacer cells in column and row panels, similar to BoxLayout
:
strut()
- declares a fixed-size spacer cellglue()
- declares a flexible spacer cell
Sierra also includes the TextPane
and ImagePane
components, which provide an alternative to JLabel
for displaying basic text or image content, respectively. TextPane
supports wrapping text without requiring HTML, and ImagePane
supports scaling without requiring an intermediate BufferedImage
.
For example, the following code declares a column panel containing a graphic and a simple greeting:
setContentPane(column(4,
cell(new ImagePane(image)).with(imagePane -> imagePane.setScaleMode(ImagePane.ScaleMode.FILL_WIDTH)),
cell(new TextPane("Hello, World!")).with(textPane -> textPane.setHorizontalAlignment(HorizontalAlignment.CENTER))
).with(contentPane -> {
contentPane.setBackground(Color.WHITE);
contentPane.setOpaque(true);
contentPane.setBorder(new EmptyBorder(8, 8, 8, 8));
}).getComponent());
The resulting output is shown below:
The complete source code for this example can be found here.
When grid alignment is enabled in a ColumnPanel
, the sub-components (or "cells") of every RowPanel
in the column are vertically aligned in a grid, as in a spreadsheet or HTML table. The width of each sub-column is determined as the maximum preferred width of the cells in that column (i.e. the components having the same index in each row).
Cell contents are aligned based on the component's x and y alignment values (returned by getAlignmentX()
and getAlignmentY()
, respectively). For most components, the default is 0.5, indicating that the component should fill the entire cell along both axes. Values between 0.0 and 0.5 will align the component to the cell's leading or top edge, and values between 0.5 and 1.0 will align the component to the cell's trailing or bottom edge. In both cases, a proportional amount of the excess space will be allocated to the component. A value of 0 or 1 will result in no excess space being given to the component (i.e. it will be aligned to the appropriate edge and will be given its preferred size along that axis).
In addition to the features outlined above, Sierra also includes some common user interface elements not provided by Swing.
The MenuButton
component displays a popup menu when pressed. For example:
See MenuButtonTest.java for more information.
The DatePicker
and TimePicker
components allow a user to select a local date and time, respectively:
These classes are localized. See DateTimePickerTest.java for more information.
The ActivityIndicator
component shows indeterminate progress:
See ActivityIndicatorTest.java for more information.
The ScrollingKeyboardFocusManager
class ensures that components are automatically scrolled into view when focused (something that Swing oddly does not do by default). It can be installed at application startup as follows:
KeyboardFocusManager.setCurrentKeyboardFocusManager(new ScrollingKeyboardFocusManager());
See FormTest.java for more information.
The TaskExecutor
class performs a task in the background and and invokes a callback on the UI thread when the task is complete:
public <T> void execute(Callable<T> callable, BiConsumer<T, Exception> consumer) { ... }
For example:
taskExecutor.execute(() -> {
// Perform long-running task that may throw
return result;
}, (result, exception) -> {
if (exception == null) {
// Handle success
} else {
// Handle failure
}
});
Internally, tasks are submitted to an executor service provided to the TaskExecutor
constructor. See TaskExecutorTest.java for more information.
This section includes examples demonstrating usage of UIBuilder
with the Flat look-and-feel.
Inspired by the border layout tutorial example.
Inspired by the flow layout tutorial example.
Demonstrates baseline alignment.
Demonstrates box alignment.
Demonstrates grid alignment.
Demonstrates associating an action handler with a button.
Demonstrates a button group.
Demonstrates a custom cell renderer.
Inspired by Wikipedia's classification of the elements.
This guide introduced the Sierra framework and provided an overview of its key features. For additional information, see the source code.