Package com.cathive.fx.guice.fxml

Source Code of com.cathive.fx.guice.fxml.FXMLComponentMembersInjector

/*
* Copyright (C) 2013 The Cat Hive Developers.
*
* 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 com.cathive.fx.guice.fxml;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ResourceBundle;
import java.util.logging.Logger;

import javafx.application.Platform;
import javafx.fxml.FXMLLoader;

import com.cathive.fx.guice.FXMLComponent;
import com.google.inject.Injector;
import com.google.inject.MembersInjector;

/**
*
* @author Benjamin P. Jung
*
* @since 2.0.0
*
* @param <T>
*/
final class FXMLComponentMembersInjector<T> implements MembersInjector<T> {

    private final Injector injector;

    /** Logger for this class. */
    private static final Logger LOGGER = Logger.getLogger(FXMLComponentMembersInjector.class.getName());

    private final FXMLComponent annotation;

    FXMLComponentMembersInjector(final Injector injector, final FXMLComponent annotation) {
        super();
        this.injector = injector;
        this.annotation = annotation;
    }

    @Override
    public void injectMembers(final T instance) {

        String locationString = annotation.location();
        if (locationString.isEmpty()) {
            locationString = String.format("%s.fxml", instance.getClass().getSimpleName());
            LOGGER.fine(String.format("No location for FXML component has been set for class '%s'. Assuming default ('%s').", instance.getClass().getName(), locationString));
        }
        URL location;
        location = instance.getClass().getResource(locationString);
        if (location == null) {
            LOGGER.fine(String.format("Location '%s' cannot be found on the classpath. Trying to construct a new URL...", locationString));
            try {
                location = new URL(locationString);
            } catch (final MalformedURLException e) {
                throw new RuntimeException(String.format("Cannot construct URL from string '%s'.", locationString), e);
            }
        }
        final FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(location);
        final String resourcesString = annotation.resources();
        if (!resourcesString.isEmpty()) {
            fxmlLoader.setResources(ResourceBundle.getBundle(resourcesString));
        }
        fxmlLoader.setCharset(Charset.forName(annotation.charset()));
        fxmlLoader.setController(instance);
        fxmlLoader.setRoot(instance);
        fxmlLoader.setBuilderFactory(injector.getInstance(FXMLComponentBuilderFactory.class));

        // Invoke "fxmlLoader.setTemplate(true)" if we are using JavaFX 8.0 or
        // higher to improve performance on objects that are created multiple times.
        try {
            final Method setTemplateMethod = FXMLLoader.class.getMethod("setTemplate", boolean.class);
            setTemplateMethod.invoke(fxmlLoader, Boolean.TRUE);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            // We simply ignore this exception. It means that we are using
            // a JavaFX runtime prior to JavaFX 8.0.
        }

        // Actual instantiation of the component has to happen on the JavaFX thread.
        // We simply delegate the loading.
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                try {
                    final Object loaded = fxmlLoader.load();
                    if (loaded != instance) {
                        throw new IllegalStateException("Loading of FXML component went terribly wrong! :-(");
                    }
                } catch (final IOException e) {
                    throw new RuntimeException(e);
                }

            }
        });

    }

}
TOP

Related Classes of com.cathive.fx.guice.fxml.FXMLComponentMembersInjector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.