
de.carne.jfx.fxml.FXMLController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-jfx Show documentation
Show all versions of java-jfx Show documentation
Common JavaFX code shared between my projects
The newest version!
/*
* Copyright (c) 2016-2020 Holger de Carne and contributors, All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package de.carne.jfx.fxml;
import java.io.IOException;
import java.util.Objects;
import java.util.ResourceBundle;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jdt.annotation.Nullable;
import de.carne.boot.logging.Log;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.stage.Window;
/**
* This class is used for setting up and controlling FXML based scenes.
*
* Controller classes must conform to the name pattern (.+)Controller and must be derived from one of this class'
* subclasses. In addition a FXML file has to be created for defining the scene content as well as a resource bundle for
* text resources. All these artifacts are bound together by their names as follows:
*
* - MyStageController (controller class)
* - MyStage.fxml (FXML resource defining the stage content)
* - MyStageI18N*.properties (resource bundle)
*
*
* @param The actual JavaFX UI type.
*/
public abstract class FXMLController {
private static final Log LOG = new Log();
private static final Pattern CONTROLLER_NAME_PATTERN = Pattern.compile("^(.*)\\.(.+)Controller$");
@Nullable
private ResourceBundle resources = null;
@Nullable
private U ui = null;
final void setResources(ResourceBundle resources) {
this.resources = resources;
}
/**
* Get the UI resource bundle.
*
* @return The UI resource bundle.
*/
protected final ResourceBundle getResources() {
return Objects.requireNonNull(this.resources);
}
final void setUI(U ui) {
this.ui = ui;
}
/**
* Get the UI object.
*
* @return The UI object.
*/
public final U getUI() {
return Objects.requireNonNull(this.ui);
}
/**
* Get the UI window.
*
* @return The UI window.
*/
public abstract Window getWindow();
/**
* Perform the basic UI setup by loading the UI resource bundle, the scene content as well as the controller class
* and bind all together.
*
* @param The JavaFX UI object type.
* @param The actual {@code FXMLController} type.
* @param owner The UI object's owner (may by {@code null}).
* @param uiFactory The factory function used to create the actual UI object by invoking it with the constructed
* controller.
* @param controllerClass The controller class to use.
* @return The constructed controller which is bound to the constructed scene and UI object.
* @throws IOException if an I/O error occurs during stage setup.
*/
protected static > C loadUI(@Nullable Window owner, Function uiFactory,
Class controllerClass) throws IOException {
String controllerName = controllerClass.getName();
LOG.debug("Loading UI for controller: {0}", controllerName);
Matcher controllerNameMatcher = CONTROLLER_NAME_PATTERN.matcher(controllerName);
if (!controllerNameMatcher.find()) {
throw new IllegalArgumentException("Invalid controller class name: " + controllerName);
}
String baseName = controllerNameMatcher.group(2);
String fxmlResourceName = baseName + ".fxml";
String packageName = controllerNameMatcher.group(1);
String bundleName = packageName + "." + baseName + "I18N";
ResourceBundle bundle = ResourceBundle.getBundle(bundleName);
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(controllerClass.getResource(fxmlResourceName)),
bundle);
Parent fxmlRoot = loader.load();
C controller = loader.getController();
controller.setResources(loader.getResources());
U ui = uiFactory.apply(controller);
controller.setUI(ui);
controller.setupUI(owner, ui, fxmlRoot);
return controller;
}
/**
* This function is called during UI initialization to perform the actual UI setup.
*
* @param owner The UI object's owner (may by {@code null}).
* @param ui The constructed UI object.
* @param fxmlRoot The scene's root node as defined by the FXML resource.
*/
protected abstract void setupUI(@Nullable Window owner, U ui, Parent fxmlRoot);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy