de.micromata.mgc.javafx.ControllerService.java Source code

Java tutorial

Introduction

Here is the source code for de.micromata.mgc.javafx.ControllerService.java

Source

//
// Copyright (C) 2010-2016 Micromata GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package de.micromata.mgc.javafx;

import java.io.IOException;
import java.io.InputStream;
import java.util.ResourceBundle;

import org.apache.commons.lang3.Validate;

import de.micromata.genome.util.bean.PrivateBeanUtils;
import de.micromata.genome.util.i18n.I18NTranslations;
import de.micromata.genome.util.runtime.RuntimeIOException;
import de.micromata.genome.util.types.Pair;
import de.micromata.mgc.javafx.launcher.MgcLauncher;
import de.micromata.mgc.javafx.launcher.gui.AbstractConfigDialog;
import de.micromata.mgc.javafx.launcher.gui.AbstractMainWindow;
import de.micromata.mgc.javafx.launcher.gui.AbstractModelController;
import de.micromata.mgc.javafx.launcher.gui.Controller;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

/**
 * This class provides basic methods for loading FXMLs that are defined with {@link FXMLFile}. Load your FXMLs if you
 * need extra functionality like sending messages to Nodes of controllers or if you need access to the stage where the
 * controller is part of.
 * 
 * @author Daniel (d.ludwig@micromata.de)
 *
 */
public class ControllerService {

    /**
     * Singleton instance.
     */
    private static ControllerService INSTANCE;

    /**
     * Private constructor because singleton.
     */
    private ControllerService() {
        // NOOP
    }

    /**
     * Instance getter.
     * 
     * @return the singleton instance.
     */
    public static synchronized ControllerService get() {
        if (INSTANCE == null) {
            INSTANCE = new ControllerService();
        }

        return INSTANCE;
    }

    public void runInToolkitThread(final Runnable runnable) {

        if (Platform.isFxApplicationThread() == true) {
            runnable.run();
            return;
        }

        Platform.runLater(runnable);
    }

    public <W extends Node, C> Pair<W, C> loadControl(Class<C> controlToLoad, Class<W> widget) {
        String file;
        FXMLFile fxml = controlToLoad.getAnnotation(FXMLFile.class);
        if (fxml != null) {
            file = fxml.file();
        } else {
            file = "/fxml/" + controlToLoad.getSimpleName() + ".fxml";

        }
        Pair<W, C> load = loadScene(file, widget, controlToLoad);

        return load;
    }

    public <W extends Node, C extends Controller> Pair<W, C> loadControllerControl(Class<C> controlToLoad,
            Class<W> widget, Controller parentController) {
        return loadControllerControl(controlToLoad, widget, parentController, null);
    }

    public <W extends Node, C extends Controller> Pair<W, C> loadControllerControl(Class<C> controlToLoad,
            Class<W> widget, Controller parentController, String id) {
        Pair<W, C> ret = loadControl(controlToLoad, widget);
        C controller = ret.getSecond();
        controller.setThisNode(ret.getFirst());
        controller.setParent((Parent) parentController.getThisNode());
        ret.getSecond().setScene(parentController.getScene());
        ret.getSecond().setStage(parentController.getStage());
        ret.getSecond().setId(id);
        return ret;
    }

    public <M, W extends Parent, C extends ModelController<M>> Pair<W, C> loadControlWithModelNewScene(
            Class<C> controlToLoad, Class<W> widget, M model, Controller parentController) {
        Pair<W, C> ret = loadControlWithModel(controlToLoad, widget, model, parentController);
        C controller = ret.getSecond();
        W wig = ret.getFirst();
        Stage stage = new Stage();
        //    controller.setOwningStage(stage);
        Scene s = new Scene(wig, AbstractConfigDialog.PREF_WIDTH, AbstractConfigDialog.PREF_HEIGHT);
        controller.setScene(s);
        controller.setStage(stage);
        stage.setScene(s);
        s.getStylesheets().add(FXCssUtil.CSS);
        return ret;
    }

    public <M, W extends Node, C extends ModelController<M>> Pair<W, C> loadControlWithModel(Class<C> controlToLoad,
            Class<W> widget, M model, Controller parentController) {
        Pair<W, C> ret = loadControllerControl(controlToLoad, widget, parentController);
        C controller = ret.getSecond();
        controller.setModel(model);
        controller.initializeWithModel();
        controller.registerValMessageReceivers();
        return ret;
    }

    public static <T extends Node, C> Pair<T, C> loadScene(String path, Class<T> nodeClass,
            Class<C> controlerClass) {
        try (InputStream is = ControllerService.class.getResourceAsStream(path)) {
            if (is == null) {
                throw new IllegalArgumentException("Canot find fxml file: " + path);
            }
        } catch (IOException ex) {
            throw new IllegalArgumentException("Canot find fxml file: " + path);
        }
        ResourceBundle resbundle = I18NTranslations
                .asResourceBundle(MgcLauncher.get().getApplication().getTranslateService());
        FXMLLoader fxmlLoader = new FXMLLoader(ControllerService.class.getResource(path), resbundle, null,
                clazz -> {
                    if (clazz.isAssignableFrom(controlerClass) == true) {
                        return PrivateBeanUtils.createInstance(controlerClass);
                    } else {
                        return PrivateBeanUtils.createInstance(clazz);
                    }

                });
        try {
            Object loaded = fxmlLoader.load();
            Object controler = fxmlLoader.getController();
            Validate.notNull(loaded);
            Validate.notNull(controler);
            return Pair.make((T) loaded, (C) controler);

        } catch (IOException ex) {
            throw new RuntimeIOException(ex);
        }
    }

    public <M, C extends AbstractModelController<M>> C loadAsDialog(AbstractMainWindow<?> mainWindow,
            Class<C> controllerClass, String dialogTitle) {
        Pair<Pane, C> pair = loadControllerControl(controllerClass, Pane.class, mainWindow);
        Stage stage = new Stage();
        stage.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, e -> {
            stage.hide();
            e.consume();
        });
        Pane root = pair.getFirst();
        C controller = pair.getSecond();
        Scene s = new Scene(root);//, AbstractConfigDialog.PREF_WIDTH, AbstractConfigDialog.PREF_HEIGHT
        controller.setParent(root);
        controller.setScene(s);
        controller.setStage(stage);
        stage.setScene(s);
        stage.initModality(Modality.APPLICATION_MODAL);
        //stage.setResizable(false);
        stage.setTitle(dialogTitle);
        return controller;
    }

    public <M, C extends AbstractModelController<M>> C loadAsWindow(AbstractMainWindow<?> mainWindow,
            Class<C> controllerClass, M model, String dialogTitle) {
        Pair<Pane, C> pair = loadControlWithModel(controllerClass, Pane.class, model, mainWindow);
        Stage stage = new Stage();
        stage.addEventHandler(WindowEvent.WINDOW_CLOSE_REQUEST, e -> {
            stage.hide();
            e.consume();
        });
        Pane root = pair.getFirst();
        C controller = pair.getSecond();
        Scene s = new Scene(root);//, AbstractConfigDialog.PREF_WIDTH, AbstractConfigDialog.PREF_HEIGHT
        controller.setParent(root);
        controller.setScene(s);
        controller.setStage(stage);
        stage.setScene(s);
        //stage.setResizable(false);
        stage.setTitle(dialogTitle);
        return controller;
    }

}