Skip to content

Releases: int4-org/FX

0.6.1

Choose a tag to compare

@hjohn hjohn released this 21 Jun 15:16

Full Changelog: 0.6...0.6.1

  • Changed ValidationMarkerPane API to make it easier to customize its markers directly

0.6

0.6

Choose a tag to compare

@hjohn hjohn released this 19 Jun 22:41

Full Changelog: 0.5...0.6

Highlights of this release:

Validation rules and UI support

Domains can now contain Rule predicates: predicates that are associated with a Template describing why a value is not part of the domain. This allows domains to provide validation feedback that can be displayed directly in the UI.

All built-in Domain factory methods now provide default validation messages, making it possible to surface meaningful feedback without additional configuration. Combined with ValidationEvent, which is emitted by controls bound to domain-aware Models, and the new ValidationMarkerPane, validation errors can now be propagated and presented with minimal effort.

image

Atomic updates and consistent multi-value observation

UpdatableValue introduces support for coordinated updates through set(...) and batch(...).

When multiple values are updated together, all values are updated before notifications are delivered. This guarantees that observers never see intermediate states and always receive a consistent view of the data.

This works particularly well with Observe.values(...).subscribe(...).

Combined with Observe.values(...).subscribe(...), it becomes straightforward to react to changes across multiple values without worrying about duplicate processing or transient invalid states. While individual value changes may generate multiple notifications internally, Observe.values(...).subscribe(...) suppresses redundant callbacks when the effective set of observed values has not changed.

UpdatableValue<String> firstName = UpdatableValue.of();
UpdatableValue<String> lastName = UpdatableValue.of();

Observe.values(firstName, lastName)
    .subscribe((fn, ln) -> updateDisplay(fn + " " + ln));

UpdatableValue.set(
    firstName, "John",
    lastName, "Smith"
);

In this example, updateDisplay(...) is invoked only once after both values have been updated, ensuring that observers never receive a partially updated state.

Java 25 baseline

FX Flow now requires Java 25. Build pipelines, CI workflows, and published artifacts have been updated accordingly.

New Features

  • Added ValidationMarkerPane and its base type AbstractMarkerPane for attaching visual markers to any JavaFX control.
  • Added ValidationEvent, a general-purpose event type primarily emitted by controls bound to domain-aware models, but also usable by external components to publish validation-related state that can be picked up by a ValidationMarkerPane or any other interested ancestor.
  • Added PaneBuilder and Panes.pane(...) for fluent construction of JavaFX Pane instances.
  • Added UpdatableValue, a value container supporting atomic multi-value updates with guaranteed end-state-only notifications to listeners.
  • Added multi-value subscription support to Observe.values(...), enabling observation of combined value tuples via a single subscribe(...) callback.

API Changes

  • Domain.where(...) instead of Domain.of(...)
  • Domain.inapplicable() instead of Domain.empty()
  • model::setDomain instead of direct domain property mutation.

0.5

0.5

Choose a tag to compare

@hjohn hjohn released this 03 Feb 19:30

Full Changelog: 0.4...0.5

This release enhances FX Flow with a more flexible, strategy-driven builder model, enabling build-time customizable resolution of text, formatting, and child nodes.

Context‑Aware Build Strategy Infrastructure

A major addition is the build context and strategies framework. This allows builder behavior to be customized and overridden without changing the builders themselves. It introduces:

  • BuildContext, BuildContexts, and BuildStrategy to represent, compose, and resolve strategy implementations.
  • Thread‑local and global root contexts for scoped strategy application.
  • Support for override of strategies such as text formatting (TextStrategy), content resolution (ContentStrategy) and children handling (ChildrenStrategy). This enables advanced use‑cases such as localization and custom node resolution.

Below is an example how text accepting builder methods can be (globally) overridden to do localization:

ChoiceModel<Locale> locales = ChoiceModel.of(Locale.ENGLISH, Locale.GERMAN);

BuildContexts.root(
    BuildContext.of(TextStrategy.class, (node, input, setter) -> {
        if (locales.get().equals(Locale.GERMAN)) {
            setter.accept(Objects.toString(input).toUpperCase());
        }
        else {
            setter.accept(Objects.toString(input));
        }
    })
);

The example:

  • Creates a new BuildContext with an overridden TextStrategy
  • Sets the newly created BuildContext as the root context for builders to use

Generalized text inputs

The text, promptText, and accessibleText builder methods now accept Object instead of String. Values are passed to the active TextStrategy, with the default behavior calling toString(). This enables richer use cases such as enum-based localization, custom formatting, and late or dynamic text resolution without changing builder APIs.

Simplified ComboBox and Spinner typing

ComboBox and Spinner builders no longer require an explicit type witness. The new raw/typed builder split allows the item type to be inferred naturally from methods that supply a type (eg. items(...), value(...), model(...), or comparator(...)), reducing boilerplate while preserving full type safety once the type is established. For example:

FX.comboBox()                       // type is ComboBoxBuilder.Raw
    .items(List.of("A", "B", "C")   // type is now ComboBoxBuilder.Typed<String>
    .comparator( ... )              // accepts Comparator<String> only now
    .build();

0.4

0.4

Choose a tag to compare

@hjohn hjohn released this 16 Jan 21:45

Full Changelog: 0.3...0.4

This release expands the fluent JavaFX builder API with better coverage of core JavaFX primitives and improved model integration.

Shapes

A new Shapes entry point adds fluent builders for JavaFX shapes such as Circle, Line, Rectangle, and Path, allowing shapes to participate fully in declarative UI composition.

Circle circle = Shapes.circle("avatar").radius(24).build();

Group

The Panes API now includes a builder for javafx.scene.Group, enabling lightweight node grouping with styling support.

Group group = Panes.group("overlay").nodes(node1, node2);

Minor changes

  • SliderBuilder now supports integer and long models.
  • AbstractRegionBuilder now provides single axis size methods such as minWidth, prefHeight, and maxWidth.
  • Added and refined Javadoc across the builders and values modules.
  • Improved module-level documentation (module-info.java) to clarify API surface and exported packages.
  • Minor API cleanups and refactorings in abstract builder base classes for consistency and maintainability.

0.3

0.3

Choose a tag to compare

@hjohn hjohn released this 04 Jan 00:11

Full Changelog: 0.2...0.3

  • Aligned ObjectModel, ChoiceModel and StringModel with each other
  • Modified builders to accept more generic models for more flexibility

0.2

0.2

Choose a tag to compare

@hjohn hjohn released this 02 Jan 15:06

Full Changelog: 0.1...0.2

  • Renamed builders methods that take a model to model
  • Introduced abstract builders for Labeled, ComboBoxBase and ButtonBase to cut down on boiler plate in derived builders

0.1

0.1

Choose a tag to compare

@hjohn hjohn released this 31 Dec 21:44
  • Initial release