Document Designer workflows and qualify the real library example

This commit is contained in:
2026-11-13 23:04:20 +01:00
parent e865d7b4df
commit 83b9e4013d
13 changed files with 960 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
# Connect an application
Start with an application that builds and runs without the editor. The [Person desk quick start](quick-start.md) is the complete executable example. For a new JavaFX application, use NeitzelLib's library quick start first; add Designer integration afterward. Neither a host dependency nor the Scene Builder Kit belongs on the application's runtime path.
## Shared project configuration
Commit `neitzel-fx-designer.json` at the Maven reactor root. This example selects a test-source preview provider:
```json
{
"schemaVersion": "1.0",
"contexts": {
"person-desk": {
"applicationModule": "fx-example",
"mavenProfiles": ["designer-preview"],
"launchMode": "classpath",
"buildRuntime": "java21",
"targetRuntime": "java21",
"preview": {
"sourceSet": "test",
"provider": "de.neitzel.fx.example.preview.DeskPreviewProvider",
"defaultExample": "desk"
}
}
}
}
```
A context identifies one application module, profile set, launch mode and runtime pair. Select explicitly when the file contains multiple contexts. Paths and module selections must stay inside the reactor. Unknown properties and unsupported schema versions are errors, not ignored settings. The authoritative [configuration schema](../../designer-contracts/src/main/resources/schema/configuration-1.0.json) lists limits and required fields.
| Setting | Meaning |
| --- | --- |
| `applicationModule` | Application module relative to the reactor root |
| `mavenProfiles` | Explicit Maven profiles used for this snapshot |
| `launchMode` | `classpath` or `module-path` |
| `buildRuntime`, `targetRuntime` | Logical names resolved from local settings |
| `buildJava`, `targetJava` | Optional required Java feature versions |
| `requiredCapabilities` | Explicit worker/runtime capabilities required by the context |
| `preview.sourceSet` | `test`, or `module` with a required `preview.module` |
| `preview.provider` | Qualified provider class; general example discovery is filtered to it |
| `preview.defaultExample`, `preview.examples` | Default/sample selection constraints |
| `preview.requestTimeoutSeconds` | Request timeout, 1–300 seconds |
| `preview.readinessTimeoutSeconds` | Asynchronous readiness timeout, 1–300 seconds |
| `modulePath` | Required only for module-path mode: `entryModule`, optional `addReads` and `addOpens` |
Named-module applications need their ordinary FXMLLoader/injection reflective access as well as explicit preview access. Use the real module names from your dependencies. The Designer does not automatically add broad `--add-opens` workarounds. Consult the [qualified classpath/module-path fixtures](../preview-target-fixtures.md) and existing `designer-target-tools/src/test` examples before adapting a JPMS application.
## Local runtime settings
Keep machine paths out of the committed context. An ignored `.neitzel-fx-designer/runtimes.json` maps names independently for build and target roles:
```json
{
"schemaVersion": "1.0",
"runtimes": {
"java21": {
"build": "/absolute/path/to/jdk-21",
"target": "/absolute/path/to/jdk-21"
}
}
}
```
The [local settings schema](../../designer-contracts/src/main/resources/schema/local-settings-1.0.json) is authoritative. Both entries refer to full JDK installations. The host's bundled Java runtime is a separate role. Configure local `host.properties` with `configuration`, `context`, `settings`, `maven` and `tools`; paths resolve relative to that properties file. `tools` contains the target-tools, contracts and preview-api JARs separated by the platform path separator. The [quick-start helper](quick-start.md#4-create-local-runtime-and-launch-settings) writes these files for the reference example. There is no graphical project-setup wizard.
## Typed sample providers
Add `de.neitzel.fxdesigner:designer-preview-api:0.1.0-SNAPSHOT` with test scope, preferably in an opt-in profile. A provider implements `PreviewProvider<Model, ApplicationContext>`; its public no-argument constructor and `open(exampleId)` execute only in the target JVM, after selection. `modelType()` declares the Model contract.
The following is an illustrative fragment: `Person`, `MyApplication` and `createSamplePerson()` belong to your application. Import `PreviewProvider` and `PreviewSession` from `de.neitzel.fxdesigner.preview` and `ApplicationContext` from `de.neitzel.injection`. The complete compiling providers are in NeitzelLib’s `fx-example/src/designer/java/de/neitzel/fx/example/preview`.
```java
public final class PersonPreview implements PreviewProvider<Person, ApplicationContext> {
public Class<Person> modelType() { return Person.class; }
public PreviewSession<Person, ApplicationContext> open(String id) {
if (!id.equals("person")) throw new IllegalArgumentException(id);
Person model = createSamplePerson();
ApplicationContext context = new ApplicationContext(MyApplication.class);
return new PreviewSession<>() {
public Person model() { return model; }
public ApplicationContext context() { return context; }
public void close() { /* release resources owned by this sample */ }
};
}
}
```
Use fresh Models and services on every call. Do not reuse production singletons, real accounts or external data unintentionally. `open` must clean partial allocations if it throws. `ready()` is called after View load/CSS/layout on the FX thread; return a completion stage for asynchronous work and never block that thread. `close()` runs once on FX after normal close or load/readiness failure. Forced process death cannot guarantee cooperative cleanup.
The actual example uses `DeskPreviewProvider`, `AddressPreviewProvider` and `NotePreviewProvider`. Independent Row previews prepare their parent Controller state explicitly; a Row cannot assume that a separately edited parent View has already run. Sample setup avoids the application's message popup.
Register non-executing descriptors in `META-INF/neitzel-fx-designer/examples.properties`:
```properties
format=1
count=1
example.0.id=person
example.0.label=Person sample
example.0.modelType=com.example.Person
example.0.providerClass=com.example.PersonPreview
example.0.viewResource=com/example/Person.fxml
example.0.componentPackage=com.example
```
Descriptors are discovered without constructing providers. Per-document selection matches the FXML resource, including independent Components. Inspect the reference example's real five-entry descriptor when adding another View; a new generated FXML file needs its own descriptor before it has an interactive sample.
## Declare the View's Model
Use a processing instruction, ignored by normal FXMLLoader:
```xml
<?neitzel-model com.example.Person?>
```
This is the editor's explicit Model declaration; it does not create a Model or replace the runtime Controller/ViewModel selection. Use `xmlns:fx="http://javafx.com/fxml/1"`. Discovery reads compiled signatures or optional generated metadata, follows nested Attributes and collection element types, and selects the explicit Controller/Component ViewModel contract. Rebuild after Java/configuration changes. See [generation](generation.md) for processor setup.