de.mirkosertic.desktopsearch.DesktopSearch.java Source code

Java tutorial

Introduction

Here is the source code for de.mirkosertic.desktopsearch.DesktopSearch.java

Source

/**
 * FreeDesktopSearch - A Search Engine for your Desktop
 * Copyright (C) 2013 Mirko Sertic
 *
 * 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 de.mirkosertic.desktopsearch;

import insidefx.undecorator.Undecorator;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.apache.commons.lang3.SystemUtils;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.LockReleaseFailedException;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.net.BindException;
import java.net.URL;

public class DesktopSearch extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    private FrontendEmbeddedWebServer embeddedWebServer;
    private Backend backend;
    private Stage stage;
    private ConfigurationManager configurationManager;

    @Override
    public void start(Stage aStage) throws Exception {

        // This is our base directory
        File theBaseDirectory = new File(SystemUtils.getUserHome(), "FreeSearchIndexDir");
        theBaseDirectory.mkdirs();

        configurationManager = new ConfigurationManager(theBaseDirectory);

        Notifier theNotifier = new Notifier();

        stage = aStage;

        // Create the known preview processors
        PreviewProcessor thePreviewProcessor = new PreviewProcessor();

        try {
            // Boot the search backend and set it up for listening to configuration changes
            backend = new Backend(theNotifier, configurationManager.getConfiguration(), thePreviewProcessor);
            configurationManager.addChangeListener(backend);

            // Boot embedded JSP container
            embeddedWebServer = new FrontendEmbeddedWebServer(aStage, backend, thePreviewProcessor,
                    configurationManager);

            embeddedWebServer.start();
        } catch (BindException | LockReleaseFailedException | LockObtainFailedException e) {
            // In this case, there is already an instance of DesktopSearch running
            // Inform the instance to bring it to front end terminate the current process.
            URL theURL = new URL(FrontendEmbeddedWebServer.getBringToFrontUrl());
            // Retrieve the content, but it can be safely ignored
            // There must only be the get request
            Object theContent = theURL.getContent();

            // Terminate the JVM. The window of the running instance is visible now.
            System.exit(0);
        }

        aStage.setTitle("Free Desktop Search");
        aStage.setWidth(800);
        aStage.setHeight(600);
        aStage.initStyle(StageStyle.TRANSPARENT);

        FXMLLoader theLoader = new FXMLLoader(getClass().getResource("/scenes/mainscreen.fxml"));
        AnchorPane theMainScene = theLoader.load();

        final DesktopSearchController theController = theLoader.getController();
        theController.configure(this, backend, FrontendEmbeddedWebServer.getSearchUrl(), stage.getOwner());

        Undecorator theUndecorator = new Undecorator(stage, theMainScene);
        theUndecorator.getStylesheets().add("/skin/undecorator.css");

        Scene theScene = new Scene(theUndecorator);

        // Hacky, but works...
        theUndecorator.setStyle("-fx-background-color: rgba(0, 0, 0, 0);");

        theScene.setFill(Color.TRANSPARENT);
        aStage.setScene(theScene);

        aStage.getIcons().add(new Image(getClass().getResourceAsStream("/fds.png")));

        if (SystemTray.isSupported()) {
            Platform.setImplicitExit(false);
            SystemTray theTray = SystemTray.getSystemTray();

            // We need to reformat the icon according to the current tray icon dimensions
            // this depends on the underlying OS
            java.awt.Image theTrayIconImage = Toolkit.getDefaultToolkit()
                    .getImage(getClass().getResource("/fds_small.png"));
            int trayIconWidth = new TrayIcon(theTrayIconImage).getSize().width;
            TrayIcon theTrayIcon = new TrayIcon(
                    theTrayIconImage.getScaledInstance(trayIconWidth, -1, java.awt.Image.SCALE_SMOOTH),
                    "Free Desktop Search");
            theTrayIcon.setImageAutoSize(true);
            theTrayIcon.setToolTip("FXDesktopSearch");
            theTrayIcon.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 1) {
                        Platform.runLater(() -> {
                            if (stage.isIconified()) {
                                stage.setIconified(false);
                            }
                            stage.show();
                            stage.toFront();
                        });
                    }
                }
            });
            theTray.add(theTrayIcon);

            aStage.setOnCloseRequest(aEvent -> stage.hide());
        } else {

            aStage.setOnCloseRequest(aEvent -> shutdown());
        }

        aStage.setMaximized(true);
        aStage.show();
    }

    public void shutdown() {

        embeddedWebServer.stop();
        backend.shutdown();
        stage.hide();

        // Raw shutdown of all threads
        System.exit(0);
    }

    public ConfigurationManager getConfigurationManager() {
        return configurationManager;
    }

    public Stage getStage() {
        return stage;
    }
}