Loading...
Loading...
JavaFX threading, FXML patterns, CSS rules, and Guice DI integration for the Renamer App UI. Use when writing or reviewing any JavaFX controller, FXML file, or CSS stylesheet in app/ui/.
npx skill4agent add sanyokkua/renamer_app javafxPlatform.runLater()TasksetOnSucceededsetOnFailedfx:controllerViewLoaderServiceinjector::getInstance-fx-javafx.concurrent.Task<V>Thread.setDefaultUncaughtExceptionHandlerjavax.swing.*org.eclipse.swt.*Guice.createInjector(DIAppModule, DICoreModule, DIUIModule)Applicationua.renamer.app.RenamerApplicationua.renamer.app.LauncherViewLoaderServiceloader.setControllerFactory(injector::getInstance)fx:controllerDIUIModule.loadAndRegister()// FXML declares the controller class:
// fx:controller="ua.renamer.app.ui.controller.mode.impl.ModeAddTextController"
//
// ViewLoaderService creates the loader and wires Guice:
// loader.setControllerFactory(injector::getInstance)
// loader.setResources(resourceBundle)
//
// DIUIModule.provideModeViewRegistry() loads each mode view at startup:
// loadAndRegister(registry, viewLoaderApi, ViewNames.MODE_ADD_TEXT, addText);ModeControllerV2Api<MyModeParams>@RequiredArgsConstructor(onConstructor_ = {@Inject})fx:controller="...ModeMyModeController"bind(ModeMyModeController.class).in(Singleton.class)DIUIModule.bindViewControllers()loadAndRegister()DIUIModule.provideModeViewRegistry()ViewNamesapp/ui/src/main/resources/fxml/fx:controllerloader.setControllerFactory(injector::getInstance)@FXMLloader.load()ViewNames/fxml/...ObservableListTableViewListViewExecutorServiceDIAppModulejavafx.concurrent.Task<V>Executors.newVirtualThreadPerTaskExecutor()// Correct: update UI from background thread
Platform.runLater(() -> tableView.getItems().setAll(results));
// Correct: bind progress bar
progressBar.progressProperty().bind(task.progressProperty());
// WRONG: scene graph mutation from non-FX thread
new Thread(() -> tableView.getItems().add(item)).start(); // crashesTask<List<RenameResult>> task = new Task<>() {
@Override
protected List<RenameResult> call() {
return orchestrator.orchestrate(files, config);
}
};
task.setOnSucceeded(e -> updateTable(task.getValue()));
task.setOnFailed(e -> showError(task.getException()));
executor.execute(task);SimpleStringPropertySimpleBooleanPropertySimpleObjectPropertyFXCollections.observableArrayList()TableViewListViewObservableList-fx-| Standard CSS | JavaFX CSS |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
app/ui/src/main/resources/styles/Scene-fx-focus-color: transparentaccessibleTextImageView// In Application.start():
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
log.error("Uncaught exception on thread {}", thread.getName(), throwable);
Platform.runLater(() -> showErrorDialog(throwable));
});fx:controllernew Thread()setDaemon(true)javax.swing.*org.eclipse.swt.*-fx-