package com.athaydes.logfx.ui; import com.athaydes.logfx.concurrency.TaskRunner; import com.athaydes.logfx.config.Properties; import com.athaydes.logfx.file.FileChangeWatcher; import javafx.application.Platform; import javafx.collections.ObservableList; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.CornerRadii; import javafx.scene.paint.Paint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.util.HashMap; import java.util.Map; /** * Utility functions for JavaFX-related functionality. */ public class FxUtils { private static final Logger log = LoggerFactory.getLogger( FxUtils.class ); private static final Map<Paint, Background> bkgByPaint = new HashMap<>(); /** * Creates and caches a simple {@link Background} for the given {@link Paint}. * * @param paint of the background * @return simple background */ public static Background simpleBackground( Paint paint ) { return bkgByPaint.computeIfAbsent( paint, ignored -> new Background( new BackgroundFill( paint, CornerRadii.EMPTY, Insets.EMPTY ) ) ); } /** * Setup the stylesheet for the given Scene. * * @param scene to setup stylesheet for */ public static void setupStylesheet( Scene scene ) { String stylesheet = Properties.getCustomStylesheet() .map( FxUtils::toAbsoluteFileUri ) .orElse( "css/LogFX.css" ); String iconsStylesheet = "css/icons.css"; Runnable resetStylesheet = () -> Platform.runLater( () -> { scene.getStylesheets().clear(); scene.getStylesheets().addAll( stylesheet, iconsStylesheet ); } ); if ( Properties.getCustomStylesheet().isPresent() ) { log.info( "Using custom stylesheet for Scene: {}", stylesheet ); if ( Properties.isRefreshStylesheet() ) { FileChangeWatcher stylesheetWatcher = new FileChangeWatcher( Properties.getCustomStylesheet().get(), TaskRunner.getGlobalInstance(), resetStylesheet ); scene.getWindow().setOnCloseRequest( event -> stylesheetWatcher.close() ); } else { log.info( "Custom stylesheet will not be refreshed" ); resetStylesheet.run(); } } else { log.debug( "Using default stylesheet for new Scene" ); resetStylesheet.run(); } } /** * @return true if running on Mac OS. */ public static boolean isMac() { return System.getProperty( "os.name", "" ).contains( "Mac" ); } private static String toAbsoluteFileUri( File file ) { String absolutePath = file.getAbsolutePath(); if ( File.separatorChar == '\\' ) { // windows stuff return "file:///" + absolutePath.replace( "\\", "/" ); } else { return "file:" + absolutePath; } } public static void addIfNotPresent( ObservableList<String> styleClasses, String... cssClasses ) { for ( String cssClass : cssClasses ) { if ( !styleClasses.contains( cssClass ) ) { styleClasses.add( cssClass ); } } } }