001/*
002 * Copyright 2019-2021 M. Sean Gilligan.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package app.supernaut.fx.internal;
017
018import app.supernaut.fx.ApplicationDelegate;
019import app.supernaut.fx.FxLauncher;
020import javafx.application.Application;
021import javafx.stage.Stage;
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025
026/**
027 * Internal <b>Supernaut.fx</b> implementation of {@link Application}. As a static proxy object for
028 * {@link ApplicationDelegate}, it delegates OpenJFX {@link Application} lifecycle calls to {@link ApplicationDelegate}
029 * and makes it more independent of OpenJFX.
030 * 
031 * <p>Tagline: <q>
032 *  We subclass {@link javafx.application.Application} so you don't have to.
033 * </q></p>
034 * <p>
035 * To create a Supernaut.fx app, write a class that implements {@link ApplicationDelegate}.
036 * </p>
037 *
038 */
039public final class OpenJfxProxyApplication extends Application {
040    private static final Logger log = LoggerFactory.getLogger(OpenJfxProxyApplication.class);
041    /** Launcher must set this global before calling constructor */
042    public static FxLauncher configuredLauncher;
043    private final FxLauncher launcher;
044    private final ApplicationDelegate appDelegate;
045    
046    /**
047     * Create a JavaFX application that wraps an {@link ApplicationDelegate}
048     * Note that {@link FxLauncher#createAppDelegate(Application)} will wait
049     * on the background app initialized latch so this constructor
050     * will block until the background app is created and initialized.
051     * Constructed on the JavaFX application thread
052     */
053    public OpenJfxProxyApplication() {
054        launcher = configuredLauncher;
055        appDelegate = launcher.createAppDelegate(this);
056    }
057
058    /**
059     * Supernaut.fx implementation of {@link Application#init}.
060     * Initializes the ApplicationContext and loads and dependency injects the Application singleton.
061     * Called on the JavaFX-launcher thread
062     * @throws Exception if something goes wrong
063     */
064    @Override
065    public void init() throws Exception {
066        log.info("Initializing ApplicationDelegate");
067        appDelegate.init();
068    }
069
070    /**
071     * Supernaut.fx implementation of {@link Application#start}.
072     * Calls the application's implementation of {@link ApplicationDelegate#start}
073     *
074     * @param primaryStage The primary Stage for the application
075     * @throws Exception if something goes wrong
076     */
077    @Override
078    public void start(Stage primaryStage) throws Exception {
079        log.info("Starting ApplicationDelegate");
080        appDelegate.start(primaryStage);
081    }
082
083    /**
084     * SupernautFX implementation of Application#stop().
085     * Stops the SupernautFxApp and then stops the Micronaut ApplicationContext
086     * @throws Exception if something goes wrong
087     */
088    @Override
089    public void stop() throws Exception {
090        log.info("Stopping ApplicationDelegate");
091        appDelegate.stop();
092        // TODO: Should call a "stop" method in the launcher or the AppFactory?
093        launcher.getBackgroundApp().get().stop();
094    }
095}