com.jf.javafx.Application.java Source code

Java tutorial

Introduction

Here is the source code for com.jf.javafx.Application.java

Source

/*
 * Copyright (C) 2014 Hong
 *
 * 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 <http://www.gnu.org/licenses/>.
 */
package com.jf.javafx;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;

/**
 *
 * @author Hong
 */
public class Application extends javafx.application.Application {

    /**
     * JF_HOME
     */
    public static String JF_HOME;
    /**
     * config path
     */
    protected static String JF_CONF;
    /**
     * template path
     */
    protected static String JF_TEMPLATES;
    /**
     * resources path
     */
    protected static String JF_RESOURCES;

    /**
     * config
     */
    private Configuration config;

    private ResourceBundle rb;

    private final Dictionary<Class, Service> services = new Hashtable();

    private Stage pStage;

    private static Application sapp = null;

    /**
     * Start the application
     *
     * @param primaryStage
     * @throws java.lang.Exception
     */
    @Override
    public void start(Stage primaryStage) throws Exception {
        Application.sapp = this;
        this.pStage = primaryStage;

        // set env variables
        _initVars();
        // load properties
        _initConfigurations();

        _initStartupServices();

        // handle on closing window
        primaryStage.setOnHidden((WindowEvent event) -> {
            _commitProperties();
        });
        primaryStage.initStyle(StageStyle.TRANSPARENT);
        primaryStage.setTitle(getResourceBundle().getString("app.title"));
        primaryStage.show();
    }

    /**
     * Initialize environment variables.
     *
     * @throws Exception
     */
    private void _initVars() throws Exception {
        // set jf_home
        //        JF_HOME = (new File(Application.class.getProtectionDomain().getCodeSource().getLocation().getPath())).getParent();
        JF_HOME = System.getProperty("user.dir");
        //set jf_conf path
        JF_CONF = JF_HOME + File.separator + "conf";
        File f = new File(JF_CONF);
        if (!f.exists()) {
            f.mkdirs();
        }
        // set jf_templates path
        JF_TEMPLATES = JF_HOME + File.separator + "templates";
        f = new File(JF_TEMPLATES);
        if (!f.exists()) {
            f.mkdirs();
        }
        // set jf_resources path
        JF_RESOURCES = JF_HOME + File.separator + "resources";
        f = new File(JF_TEMPLATES);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    /**
     * Initialize configurations.
     */
    private void _initConfigurations() {
        File f = new File(_getJFPropertiesFile());
        if (f.exists()) {
            try {
                config = new XMLConfiguration(f);
            } catch (ConfigurationException ex) {
                Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            config = new XMLConfiguration();
            ((XMLConfiguration) getConfiguration()).setFileName(_getJFPropertiesFile());
        }
    }

    private void _initStartupServices() {
        for (String cls : config.getStringArray("startup_services.service")) {
            try {
                Class<?> p = Class.forName(cls);
                getService((Class<Service>) p);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * Get properties file in string
     *
     * @return properties file in string
     */
    protected String _getJFPropertiesFile() {
        return JF_CONF + File.separator + "jf.properties";
    }

    /**
     * Invoke to save changes to properties file.
     */
    private void _commitProperties() {
        try {
            ((XMLConfiguration) getConfiguration()).save(_getJFPropertiesFile());
        } catch (ConfigurationException ex) {
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public ResourceBundle getResourceBundle() throws MalformedURLException {
        if (this.rb == null) {
            String s = null;
            if ((s = config.getString("resource_bundle")) == null) {
                s = "App";
                config.setProperty("resource_bundle", s);
            }
            this.rb = getResourceBundle(s);
        }

        return this.rb;
    }

    /**
     * Get configuration object.
     *
     * @return the configuration object
     */
    public Configuration getConfiguration() {
        return config;
    }

    /**
     * Get a running service of application
     * @param <T> class extends Service
     * @param n class of T
     * @return the service object
     */
    public <T extends Service> T getService(Class<T> n) {
        Service s = this.services.get(n);
        if (s == null) {
            try {
                s = (T) n.newInstance();
                this.services.put(n, s);
                s.init(this);
            } catch (InstantiationException | IllegalAccessException ex) {
                Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        return (T) s;
    }

    public static <T extends Service> T _getService(Class<T> n) {
        return Application.sapp.getService(n);
    }

    /**
     * Get resource bundle.
     *
     * @param rs resource path
     * @return the resource
     * @throws MalformedURLException
     */
    public ResourceBundle getResourceBundle(String rs) throws MalformedURLException {
        return ResourceBundle.getBundle(rs, Locale.getDefault(),
                new URLClassLoader(new URL[] { (new File(JF_RESOURCES)).toURL() }));
    }

    /**
     * Get resource of application context.
     *
     * @param path
     * @return
     */
    public File getResource(String path) {
        return new File(JF_RESOURCES + File.separator + path);
    }

    public File getConfig(String path) {
        return new File(JF_CONF + File.separator + path);
    }

    /**
     * Get template file.
     *
     * @param path
     * @return
     */
    public File getTemplateFile(String path) {
        return new File(JF_TEMPLATES + File.separator + path);
    }

    /**
     * Load a node and its controller.
     * 
     * @param path
     * @return the node
     */
    public Pair<Node, ?> createNode(String path) {
        final Application app = this;
        File fxml = getTemplateFile(path + ".fxml");
        Node node;
        Object controller = null;
        try {
            ResourceBundle bundle;
            try {
                bundle = getResourceBundle("controllers/" + path);
            } catch (Exception ex) {
                bundle = null;
            }

            FXMLLoader loader = new FXMLLoader(fxml.toURL(), bundle, new JavaFXBuilderFactory(),
                    (Class<?> param) -> {
                        try {
                            Class cls = Controller.class;

                            if (cls.isAssignableFrom(param)) {
                                try {
                                    return param.getConstructor(Application.class).newInstance(app);
                                } catch (Exception ex) {
                                    Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
                                    return param.newInstance();
                                }
                            } else {
                                return param.newInstance();
                            }
                        } catch (IllegalAccessException | IllegalArgumentException | InstantiationException
                                | SecurityException ex) {
                            MsgBox.showException(ex);
                            return null;
                        }
                    });
            node = loader.load();
            controller = loader.getController();
        } catch (IOException ex) {
            MsgBox.showException(ex, "Error while navigate to path: " + path);

            // customize error screen
            AnchorPane p = new AnchorPane();

            //            StringWriter sw = new StringWriter();
            //            ex.printStackTrace(new PrintWriter(sw));
            //            p.getChildren().add(new Label(sw.toString()));

            node = p;
        }

        return new Pair(node, controller);
    }

    public Stage getStage() {
        return this.pStage;
    }

    public Scene getScene() {
        return pStage.getScene();
    }

    public void setScene(Scene s) {
        pStage.setScene(s);
    }

    /**
     * Start application
     *
     * @param args
     */
    public static void main(String[] args) {
        launch(args);
    }
}