javafx.application.Platform Maven / Gradle / Ivy
/*
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javafx.application;
import com.sun.javafx.application.PlatformImpl;
import com.sun.javafx.tk.Toolkit;
import java.util.Optional;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.ObservableMap;
import javafx.scene.input.KeyCode;
import javafx.scene.paint.Color;
/**
* Application platform support class.
* @since JavaFX 2.0
*/
public final class Platform {
// To prevent instantiation
private Platform() {
}
/**
* This method starts the JavaFX runtime. The specified Runnable will then be
* called on the JavaFX Application Thread. In general it is not necessary to
* explicitly call this method, since it is invoked as a consequence of
* how most JavaFX applications are built. However there are valid use cases
* for calling this method directly. Because this method starts the JavaFX
* runtime, there is not yet any JavaFX Application Thread, so it is normal
* that this method is called directly on the main thread of the application.
*
*
* This method may or may not return to the caller before the run method
* of the specified Runnable has been called. In any case, this
* method is not blocked on the specified Runnable being executed.
* Once this method
* returns, you may call {@link #runLater(Runnable)} with additional Runnables.
* Those Runnables will be called, also on the JavaFX Application Thread,
* after the Runnable passed into this method has been called.
*
*
* As noted, it is normally the case that the JavaFX Application Thread
* is started automatically. It is important that this method only be called
* when the JavaFX runtime has not yet been initialized. Situations where
* the JavaFX runtime is started automatically include:
*
*
*
* - For standard JavaFX applications that extend {@link Application}, and
* use either the Java launcher or one of the launch methods in the
* Application class to launch the application, the FX runtime is
* initialized automatically by the launcher before the {@code Application}
* class is loaded.
* - For Swing applications that use {@link javafx.embed.swing.JFXPanel}
* to display FX content, the
* FX runtime is initialized when the first {@code JFXPanel} instance is
* constructed.
* - For SWT application that use {@code FXCanvas} to display FX content,
* the FX runtime is initialized when the first {@code FXCanvas} instance is
* constructed.
*
*
* When an application does not follow any of these common approaches,
* then it becomes the responsibility of the developer to manually start the
* JavaFX runtime by calling this startup method.
*
*
* Calling this method when the JavaFX runtime is already running will result in an
* {@link IllegalStateException} being thrown - it is only valid to request
* that the JavaFX runtime be started once.
*
*
* Note: The JavaFX classes must be loaded from a set of
* named {@code javafx.*} modules on the module path.
* Loading the JavaFX classes from the classpath is not supported.
* A warning is logged when the JavaFX runtime is started if the JavaFX
* classes are not loaded from the expected named module.
* This warning is logged regardless of whether the JavaFX runtime was
* started by calling this method or automatically as described above.
*
* @throws IllegalStateException if the JavaFX runtime is already running
*
* @param runnable the Runnable whose run method will be executed on the
* JavaFX Application Thread once it has been started
*
* @see Application
*
* @since 9
*/
public static void startup(Runnable runnable) {
PlatformImpl.startup(runnable, true);
}
/**
* Run the specified Runnable on the JavaFX Application Thread at some
* unspecified
* time in the future. This method, which may be called from any thread,
* will post the Runnable to an event queue and then return immediately to
* the caller. The Runnables are executed in the order they are posted.
* A runnable passed into the runLater method will be
* executed before any Runnable passed into a subsequent call to runLater.
* If this method is called after the JavaFX runtime has been shutdown, the
* call will be ignored: the Runnable will not be executed and no
* exception will be thrown.
*
*
* NOTE: applications should avoid flooding JavaFX with too many
* pending Runnables. Otherwise, the application may become unresponsive.
* Applications are encouraged to batch up multiple operations into fewer
* runLater calls.
* Additionally, long-running operations should be done on a background
* thread where possible, freeing up the JavaFX Application Thread for GUI
* operations.
*
*
*
* This method must not be called before the FX runtime has been
* initialized. For standard JavaFX applications that extend
* {@link Application}, and use either the Java launcher or one of the
* launch methods in the Application class to launch the application,
* the FX runtime is initialized by the launcher before the Application
* class is loaded.
* For Swing applications that use JFXPanel to display FX content, the FX
* runtime is initialized when the first JFXPanel instance is constructed.
* For SWT application that use FXCanvas to display FX content, the FX
* runtime is initialized when the first FXCanvas instance is constructed.
* For applications that do not follow any of these approaches, then it is
* necessary to manually start the JavaFX runtime by calling
* {@link #startup(Runnable)} once.
*
*
*
* Memory consistency effects: Actions in a thread prior to submitting a
* {@code runnable} to this method happen-before actions performed
* by the runnable in the JavaFX Application Thread.
*
*
* @param runnable the Runnable whose run method will be executed on the
* JavaFX Application Thread
*
* @throws IllegalStateException if the FX runtime has not been initialized
*
* @see Application
*/
public static void runLater(Runnable runnable) {
PlatformImpl.runLater(runnable);
}
// NOTE: Add the following if we decide to expose it publicly
// public static void runAndWait(Runnable runnable) {
// PlatformImpl.runAndWait(runnable);
// }
/**
* Requests the Java Runtime to perform a pulse. This will run a pulse
* even if there are no animation timers, scene graph modifications,
* or window events that would otherwise cause the pulse to run.
* If no pulse is in progress, then one will be scheduled to
* run the next time the pulse timer fires.
* If there is already a pulse running, then
* at least one more pulse after the current pulse will be scheduled.
* This method may be called on any thread.
*
* @since 9
*/
public static void requestNextPulse() {
Toolkit.getToolkit().requestNextPulse();
}
/**
* Returns true if the calling thread is the JavaFX Application Thread.
* Use this call to ensure that a given task is being executed
* (or not being executed) on the JavaFX Application Thread.
*
* @return true if running on the JavaFX Application Thread
*/
public static boolean isFxApplicationThread() {
return PlatformImpl.isFxApplicationThread();
}
/**
* Causes the JavaFX application to terminate. If this method is called
* after the Application start method is called, then the JavaFX launcher
* will call the Application stop method and terminate the JavaFX
* application thread. The launcher thread will then shutdown. If there
* are no other non-daemon threads that are running, the Java VM will exit.
* If this method is called from the Preloader or the Application init
* method, then the Application stop method may not be called.
*
* This method may be called from any thread.
*/
public static void exit() {
PlatformImpl.exit();
}
/**
* Sets the implicitExit attribute to the specified value. If this
* attribute is true, the JavaFX runtime will implicitly shutdown
* when the last window is closed; the JavaFX launcher will call the
* {@link Application#stop} method and terminate the JavaFX
* application thread.
* If this attribute is false, the application will continue to
* run normally even after the last window is closed, until the
* application calls {@link #exit}.
* The default value is true.
*
* This method may be called from any thread.
*
* @param implicitExit a flag indicating whether or not to implicitly exit
* when the last window is closed.
* @since JavaFX 2.2
*/
public static void setImplicitExit(boolean implicitExit) {
PlatformImpl.setImplicitExit(implicitExit);
}
/**
* Gets the value of the implicitExit attribute.
*
* This method may be called from any thread.
*
* @return the implicitExit attribute
* @since JavaFX 2.2
*/
public static boolean isImplicitExit() {
return PlatformImpl.isImplicitExit();
}
/**
* Queries whether a specific conditional feature is supported
* by the platform.
*
* For example:
*
* // Query whether filter effects are supported
* if (Platform.isSupported(ConditionalFeature.EFFECT)) {
* // use effects
* }
*
*
* @param feature the conditional feature in question.
* @return true if a specific conditional feature is supported by the
* platform, otherwise false
*/
public static boolean isSupported(ConditionalFeature feature) {
return PlatformImpl.isSupported(feature);
}
/**
* Enter a nested event loop and block until the corresponding
* exitNestedEventLoop call is made.
* The key passed into this method is used to
* uniquely identify the matched enter/exit pair. This method creates a
* new nested event loop and blocks until the corresponding
* exitNestedEventLoop method is called with the same key.
* The return value of this method will be the {@code rval}
* object supplied to the exitNestedEventLoop method call that unblocks it.
*
*
* This method must either be called from an input event handler or
* from the run method of a Runnable passed to
* {@link javafx.application.Platform#runLater Platform.runLater}.
* It must not be called during animation or layout processing.
*
*
* @param key the Object that identifies the nested event loop, which
* must not be null
*
* @throws IllegalArgumentException if the specified key is associated
* with a nested event loop that has not yet returned
*
* @throws NullPointerException if the key is null
*
* @throws IllegalStateException if this method is called during
* animation or layout processing.
*
* @throws IllegalStateException if this method is called on a thread
* other than the JavaFX Application Thread.
*
* @return the value passed into the corresponding call to exitEventLoop
*
* @since 9
*/
public static Object enterNestedEventLoop(Object key) {
return Toolkit.getToolkit().enterNestedEventLoop(key);
}
/**
* Exit a nested event loop and unblock the caller of the
* corresponding enterNestedEventLoop.
* The key passed into this method is used to
* uniquely identify the matched enter/exit pair. This method causes the
* nested event loop that was previously created with the key to exit and
* return control to the caller. If the specified nested event loop is not
* the inner-most loop then it will not return until all other inner loops
* also exit.
*
* @param key the Object that identifies the nested event loop, which
* must not be null
*
* @param rval an Object that is returned to the caller of the
* corresponding enterNestedEventLoop. This may be null.
*
* @throws IllegalArgumentException if the specified key is not associated
* with an active nested event loop
*
* @throws NullPointerException if the key is null
*
* @throws IllegalStateException if this method is called on a thread
* other than the FX Application thread
*
* @since 9
*/
public static void exitNestedEventLoop(Object key, Object rval) {
Toolkit.getToolkit().exitNestedEventLoop(key, rval);
}
/**
* Returns a flag indicating whether the key corresponding to {@code keyCode}
* is in the locked (or "on") state.
* {@code keyCode} must be one of: {@link KeyCode#CAPS} or
* {@link KeyCode#NUM_LOCK}.
* If the underlying system is not able to determine the state of the
* specified {@code keyCode}, an empty {@code Optional} is returned.
* If the keyboard attached to the system doesn't have the specified key,
* an {@code Optional} containing {@code false} is returned.
* This method must be called on the JavaFX Application thread.
*
* @param keyCode the {@code KeyCode} of the lock state to query
*
* @return the lock state of the key corresponding to {@code keyCode},
* or an empty {@code Optional} if the system cannot determine its state
*
* @throws IllegalArgumentException if {@code keyCode} is not one of the
* valid {@code KeyCode} values
*
* @throws IllegalStateException if this method is called on a thread
* other than the JavaFX Application Thread
*
* @since 17
*/
public static Optional isKeyLocked(KeyCode keyCode) {
Toolkit.getToolkit().checkFxUserThread();
switch (keyCode) {
case CAPS:
case NUM_LOCK:
break;
default:
throw new IllegalArgumentException("Invalid KeyCode");
}
return Toolkit.getToolkit().isKeyLocked(keyCode);
}
/**
* Checks whether a nested event loop is running, returning true to indicate
* that one is, and false if there are no nested event loops currently
* running.
* This method must be called on the JavaFX Application thread.
*
* @return true if there is a nested event loop running, and false otherwise.
*
* @throws IllegalStateException if this method is called on a thread
* other than the JavaFX Application Thread.
*
* @since 9
*/
public static boolean isNestedLoopRunning() {
return Toolkit.getToolkit().isNestedLoopRunning();
}
/**
* Indicates whether a nested event loop can be started from the current thread in the current state.
* A nested event loop can be started from an event handler or from a {@code Runnable} passed to
* {@link #runLater(Runnable)}.
* This method must be called on the JavaFX Application thread.
*
* @return {@code true} if a nested event loop can be started, and {@code false} otherwise.
*
* @throws IllegalStateException if this method is called on a thread other than the JavaFX Application Thread.
*
* @since 21
*/
public static boolean canStartNestedEventLoop() {
return Toolkit.getToolkit().canStartNestedEventLoop();
}
private static ReadOnlyBooleanWrapper accessibilityActiveProperty;
public static boolean isAccessibilityActive() {
return accessibilityActiveProperty == null ? false : accessibilityActiveProperty.get();
}
/**
* Indicates whether or not accessibility is active.
* This property is typically set to true the first time an
* assistive technology, such as a screen reader, requests
* information about any JavaFX window or its children.
*
* This method may be called from any thread.
*
* @return the read-only boolean property indicating if accessibility is active
*
* @since JavaFX 8u40
*/
public static ReadOnlyBooleanProperty accessibilityActiveProperty() {
if (accessibilityActiveProperty == null) {
accessibilityActiveProperty = new ReadOnlyBooleanWrapper(Platform.class, "accessibilityActive");
accessibilityActiveProperty.bind(PlatformImpl.accessibilityActiveProperty());
}
return accessibilityActiveProperty.getReadOnlyProperty();
}
/**
* Gets the preferences of the current platform.
*
* The map returned from this method is unmodifiable, which means that keys and values cannot
* be added, removed, or updated. Calling any mutator method on the map will always cause
* {@code UnsupportedOperationException} to be thrown. However, the mappings will be updated
* by JavaFX when the operating system reports that a platform preference has changed.
*
* @return the {@code Preferences} instance
* @see Windows preferences
* @see macOS preferences
* @see Linux preferences
* @since 22
*/
public static Preferences getPreferences() {
PlatformImpl.checkPreferencesSupport();
return PlatformImpl.getPlatformPreferences();
}
/**
* Contains UI preferences of the current platform.
*
* {@code Preferences} extends {@link ObservableMap} to expose platform preferences as key-value pairs.
* The map is unmodifiable, which means that keys and values cannot be added, removed, or updated.
* Calling any mutator method on the map will always cause {@code UnsupportedOperationException} to be thrown.
* However, the mappings will be updated by JavaFX when the operating system reports that a platform
* preference has changed.
*
* For convenience, {@link #getInteger}, {@link #getDouble}, {@link #getBoolean}, {@link #getString},
* {@link #getColor}, and {@link #getValue} are provided as typed alternatives to the untyped
* {@link #get} method.
*
* The preferences that are reported by the platform may be dependent on the operating system version
* and its current configuration, so applications should not assume that a particular preference is
* always available.
*
* The following preferences are potentially available on the specified platforms:
*
* Windows
*
* {@code Windows.SPI.HighContrast} {@link Boolean}
* {@code Windows.SPI.HighContrastColorScheme} {@link String}
* {@code Windows.SPI.ClientAreaAnimation} {@link Boolean}
* {@code Windows.SysColor.COLOR_3DFACE} {@link Color}
* {@code Windows.SysColor.COLOR_BTNTEXT} {@link Color}
* {@code Windows.SysColor.COLOR_GRAYTEXT} {@link Color}
* {@code Windows.SysColor.COLOR_HIGHLIGHT} {@link Color}
* {@code Windows.SysColor.COLOR_HIGHLIGHTTEXT} {@link Color}
* {@code Windows.SysColor.COLOR_HOTLIGHT} {@link Color}
* {@code Windows.SysColor.COLOR_WINDOW} {@link Color}
* {@code Windows.SysColor.COLOR_WINDOWTEXT} {@link Color}
* {@code Windows.UIColor.Background} {@link Color}
* {@code Windows.UIColor.Foreground} {@link Color}
* {@code Windows.UIColor.AccentDark3} {@link Color}
* {@code Windows.UIColor.AccentDark2} {@link Color}
* {@code Windows.UIColor.AccentDark1} {@link Color}
* {@code Windows.UIColor.Accent} {@link Color}
* {@code Windows.UIColor.AccentLight1} {@link Color}
* {@code Windows.UIColor.AccentLight2} {@link Color}
* {@code Windows.UIColor.AccentLight3} {@link Color}
* {@code Windows.UISettings.AdvancedEffectsEnabled} {@link Boolean}
*
*
*
*
* macOS
*
* {@code macOS.NSColor.labelColor} {@link Color}
* {@code macOS.NSColor.secondaryLabelColor} {@link Color}
* {@code macOS.NSColor.tertiaryLabelColor} {@link Color}
* {@code macOS.NSColor.quaternaryLabelColor} {@link Color}
* {@code macOS.NSColor.textColor} {@link Color}
* {@code macOS.NSColor.placeholderTextColor} {@link Color}
* {@code macOS.NSColor.selectedTextColor} {@link Color}
* {@code macOS.NSColor.textBackgroundColor} {@link Color}
* {@code macOS.NSColor.selectedTextBackgroundColor} {@link Color}
* {@code macOS.NSColor.keyboardFocusIndicatorColor} {@link Color}
* {@code macOS.NSColor.unemphasizedSelectedTextColor} {@link Color}
* {@code macOS.NSColor.unemphasizedSelectedTextBackgroundColor} {@link Color}
* {@code macOS.NSColor.linkColor} {@link Color}
* {@code macOS.NSColor.separatorColor} {@link Color}
* {@code macOS.NSColor.selectedContentBackgroundColor} {@link Color}
* {@code macOS.NSColor.unemphasizedSelectedContentBackgroundColor} {@link Color}
* {@code macOS.NSColor.selectedMenuItemTextColor} {@link Color}
* {@code macOS.NSColor.gridColor} {@link Color}
* {@code macOS.NSColor.headerTextColor} {@link Color}
* {@code macOS.NSColor.alternatingContentBackgroundColors} {@link Color}{@code []}
* {@code macOS.NSColor.controlAccentColor} {@link Color}
* {@code macOS.NSColor.controlColor} {@link Color}
* {@code macOS.NSColor.controlBackgroundColor} {@link Color}
* {@code macOS.NSColor.controlTextColor} {@link Color}
* {@code macOS.NSColor.disabledControlTextColor} {@link Color}
* {@code macOS.NSColor.selectedControlColor} {@link Color}
* {@code macOS.NSColor.selectedControlTextColor} {@link Color}
* {@code macOS.NSColor.alternateSelectedControlTextColor} {@link Color}
* {@code macOS.NSColor.currentControlTint} {@link String}
* {@code macOS.NSColor.windowBackgroundColor} {@link Color}
* {@code macOS.NSColor.windowFrameTextColor} {@link Color}
* {@code macOS.NSColor.underPageBackgroundColor} {@link Color}
* {@code macOS.NSColor.findHighlightColor} {@link Color}
* {@code macOS.NSColor.highlightColor} {@link Color}
* {@code macOS.NSColor.shadowColor} {@link Color}
* {@code macOS.NSColor.systemBlueColor} {@link Color}
* {@code macOS.NSColor.systemBrownColor} {@link Color}
* {@code macOS.NSColor.systemGrayColor} {@link Color}
* {@code macOS.NSColor.systemGreenColor} {@link Color}
* {@code macOS.NSColor.systemIndigoColor} {@link Color}
* {@code macOS.NSColor.systemOrangeColor} {@link Color}
* {@code macOS.NSColor.systemPinkColor} {@link Color}
* {@code macOS.NSColor.systemPurpleColor} {@link Color}
* {@code macOS.NSColor.systemRedColor} {@link Color}
* {@code macOS.NSColor.systemTealColor} {@link Color}
* {@code macOS.NSColor.systemYellowColor} {@link Color}
* {@code macOS.NSWorkspace.accessibilityDisplayShouldReduceMotion} {@link Boolean}
* {@code macOS.NSWorkspace.accessibilityDisplayShouldReduceTransparency} {@link Boolean}
*
*
*
*
* Linux
*
* {@code GTK.theme_name} {@link String}
* {@code GTK.theme_fg_color} {@link Color}
* {@code GTK.theme_bg_color} {@link Color}
* {@code GTK.theme_base_color} {@link Color}
* {@code GTK.theme_selected_bg_color} {@link Color}
* {@code GTK.theme_selected_fg_color} {@link Color}
* {@code GTK.theme_unfocused_fg_color} {@link Color}
* {@code GTK.theme_unfocused_bg_color} {@link Color}
* {@code GTK.theme_unfocused_base_color} {@link Color}
* {@code GTK.theme_unfocused_selected_bg_color} {@link Color}
* {@code GTK.theme_unfocused_selected_fg_color} {@link Color}
* {@code GTK.insensitive_bg_color} {@link Color}
* {@code GTK.insensitive_fg_color} {@link Color}
* {@code GTK.insensitive_base_color} {@link Color}
* {@code GTK.borders} {@link Color}
* {@code GTK.unfocused_borders} {@link Color}
* {@code GTK.warning_color} {@link Color}
* {@code GTK.error_color} {@link Color}
* {@code GTK.success_color} {@link Color}
* {@code GTK.enable_animations} {@link Boolean}
*
*
*
*
* @since 22
*/
public sealed interface Preferences extends ObservableMap
permits com.sun.javafx.application.preferences.PlatformPreferences {
/**
* Specifies whether applications should minimize the amount of non-essential animations,
* reducing discomfort for users who experience motion sickness or vertigo.
*
* If the platform does not report this preference, this property defaults to {@code false}.
*
* @return the {@code reducedMotion} property
* @defaultValue {@code false}
* @since 24
*/
ReadOnlyBooleanProperty reducedMotionProperty();
boolean isReducedMotion();
/**
* Specifies whether applications should minimize the amount of transparent or translucent
* layer effects, which can help to increase contrast and readability for some users.
*
* If the platform does not report this preference, this property defaults to {@code false}.
*
* @return the {@code reducedTransparency} property
* @defaultValue {@code false}
* @since 24
*/
ReadOnlyBooleanProperty reducedTransparencyProperty();
boolean isReducedTransparency();
/**
* The platform color scheme, which specifies whether applications should prefer light text on
* dark backgrounds, or dark text on light backgrounds.
*
* If the platform does not report color preferences, this property defaults to {@code LIGHT}.
*
* @return the {@code colorScheme} property
* @defaultValue {@link ColorScheme#LIGHT}
*/
ReadOnlyObjectProperty colorSchemeProperty();
ColorScheme getColorScheme();
/**
* The color used for background regions.
*
* If the platform does not report a background color, this property defaults to {@code WHITE}.
*
* @return the {@code backgroundColor} property
* @defaultValue {@link Color#WHITE}
*/
ReadOnlyObjectProperty backgroundColorProperty();
Color getBackgroundColor();
/**
* The color used for foreground elements like text.
*
* If the platform does not report a foreground color, this property defaults to {@code BLACK}.
*
* @return the {@code foregroundColor} property
* @defaultValue {@link Color#BLACK}
*/
ReadOnlyObjectProperty foregroundColorProperty();
Color getForegroundColor();
/**
* The accent color, which can be used to highlight the active or important part of a
* control and make it stand out from the rest of the user interface. It is usually a
* vivid color that contrasts with the foreground and background colors.
*
* If the platform does not report an accent color, this property defaults to vivid blue
* (corresponding to the hex color value {@code #157EFB}).
*
* @return the {@code accentColor} property
* @defaultValue {@code #157EFB}
*/
ReadOnlyObjectProperty accentColorProperty();
Color getAccentColor();
/**
* Returns an optional {@code Integer} to which the specified key is mapped.
*
* @param key the key
* @throws NullPointerException if {@code key} is null
* @throws IllegalArgumentException if the key is not mappable to an {@code Integer}
* @return the optional {@code Integer} to which the key is mapped
*/
Optional getInteger(String key);
/**
* Returns an optional {@code Double} to which the specified key is mapped.
*
* @param key the key
* @throws NullPointerException if {@code key} is null
* @throws IllegalArgumentException if the key is not mappable to a {@code Double}
* @return the optional {@code Double} to which the key is mapped
*/
Optional getDouble(String key);
/**
* Returns an optional {@code Boolean} to which the specified key is mapped.
*
* @param key the key
* @throws NullPointerException if {@code key} is null
* @throws IllegalArgumentException if the key is not mappable to a {@code Boolean}
* @return the optional {@code Boolean} to which the key is mapped
*/
Optional getBoolean(String key);
/**
* Returns an optional {@code String} to which the specified key is mapped.
*
* @param key the key
* @throws NullPointerException if {@code key} is null
* @throws IllegalArgumentException if the key is not mappable to a {@code String}
* @return the optional {@code String} to which the key is mapped
*/
Optional getString(String key);
/**
* Returns an optional {@code Color} to which the specified key is mapped.
*
* @param key the key
* @throws NullPointerException if {@code key} is null
* @throws IllegalArgumentException if the key is not mappable to a {@code Color}
* @return the optional {@code Color} instance to which the key is mapped
*/
Optional getColor(String key);
/**
* Returns an optional value to which the specified key is mapped.
*
* @param the type of the value
* @param key the key
* @param type the type of the value
* @throws NullPointerException if {@code key} or {@code type} is null
* @throws IllegalArgumentException if the key is not mappable to a value of type {@code T}
* @return the optional value to which the key is mapped
*/
Optional getValue(String key, Class type);
}
}