se.europeanspallationsource.xaos.ui.control.NavigatorController Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xaos.ui Show documentation
Show all versions of xaos.ui Show documentation
JavaFX-based portion of the XAOS framework, containing the JavaFX-based
controls and tools suitable for other projects too.
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
* Copyright (C) 2018-2019 by European Spallation Source ERIC.
*
* 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 se.europeanspallationsource.xaos.ui.control;
import java.io.IOException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Path;
import javafx.scene.shape.Shape;
import org.kordamp.ikonli.javafx.FontIcon;
import se.europeanspallationsource.xaos.core.util.LogUtils;
import se.europeanspallationsource.xaos.core.util.ThreadPools;
import se.europeanspallationsource.xaos.core.util.ThreadUtils;
import static java.util.logging.Level.SEVERE;
import static java.util.logging.Level.WARNING;
import static javafx.scene.input.MouseButton.PRIMARY;
/**
* A JavaFX control with 9 buttons to navigate a graphical area. Zoom, pan
* and undo/redo buttons are provided and can be bound to the application
* code through the provided {@link EventHandler} methods.
*
* The navigation buttons can be activated by means of keyboard accelerators
* (Shortcut stands for Ctrl on Windows or Linux, and Command on macOS):
*
*
* Pan Down Shortcut+DOWN
* Pan Left Shortcut+LEFT
* Pan Right Shortcut+RIGHT
* Pan Up Shortcut+UP
* Redo Shift+Shortcut+Z
* Undo Shortcut+Z
* Zoom In Shift+Shortcut+UP
* Zoom Out Shift+Shortcut+DOWN
* Zoom To One Shortcut+EQUALS
*
*
* @author [email protected]
*/
public class NavigatorController extends AnchorPane {
/**
* Called when the navigator's {@code panDown} button is pressed.
*/
public static final EventType ON_PAN_DOWN = new EventType(Event.ANY, "NAVIGATOR_ON_PAN_DOWN");
/**
* Called when the navigator's {@code panLeft} button is pressed.
*/
public static final EventType ON_PAN_LEFT = new EventType(Event.ANY, "NAVIGATOR_ON_PAN_LEFT");
/**
* Called when the navigator's {@code panRight} button is pressed.
*/
public static final EventType ON_PAN_RIGHT = new EventType(Event.ANY, "NAVIGATOR_ON_PAN_RIGHT");
/**
* Called when the navigator's {@code panUp} button is pressed.
*/
public static final EventType ON_PAN_UP = new EventType(Event.ANY, "NAVIGATOR_ON_PAN_UP");
/**
* Called when the navigator's {@code redo} button is pressed.
*/
public static final EventType ON_REDO = new EventType(Event.ANY, "NAVIGATOR_ON_REDO");
/**
* Called when the navigator's {@code undo} button is pressed.
*/
public static final EventType ON_UNDO = new EventType(Event.ANY, "NAVIGATOR_ON_UNDO");
/**
* Called when the navigator's {@code zoomIn} button is pressed.
*/
public static final EventType ON_ZOOM_IN = new EventType(Event.ANY, "NAVIGATOR_ON_ZOOM_IN");
/**
* Called when the navigator's {@code zoomOut} button is pressed.
*/
public static final EventType ON_ZOOM_OUT = new EventType(Event.ANY, "NAVIGATOR_ON_ZOOM_OUT");
/**
* Called when the navigator's {@code zoomToOne} button is pressed.
*/
public static final EventType ON_ZOOM_TO_ONE = new EventType(Event.ANY, "NAVIGATOR_ON_ZOOM_TO_ONE");
public static final KeyCombination PAN_DOWN_ACCELERATOR = KeyCombination.keyCombination("Shortcut+DOWN");
public static final KeyCombination PAN_LEFT_ACCELERATOR = KeyCombination.keyCombination("Shortcut+LEFT");
public static final KeyCombination PAN_RIGHT_ACCELERATOR = KeyCombination.keyCombination("Shortcut+RIGHT");
public static final KeyCombination PAN_UP_ACCELERATOR = KeyCombination.keyCombination("Shortcut+UP");
public static final KeyCombination REDO_ACCELERATOR = KeyCombination.keyCombination("Shift+Shortcut+Z");
public static final KeyCombination UNDO_ACCELERATOR = KeyCombination.keyCombination("Shortcut+Z");
public static final KeyCombination ZOOM_IN_ACCELERATOR = KeyCombination.keyCombination("Shift+Shortcut+UP");
public static final KeyCombination ZOOM_OUT_ACCELERATOR = KeyCombination.keyCombination("Shift+Shortcut+DOWN");
public static final KeyCombination ZOOM_TO_ONE_ACCELERATOR = KeyCombination.keyCombination("Shortcut+EQUALS");
private static final Logger LOGGER = Logger.getLogger(NavigatorController.class.getName());
@FXML private Path panDown;
@FXML private FontIcon panDownIcon;
@FXML private Path panLeft;
@FXML private FontIcon panLeftIcon;
@FXML private Path panRight;
@FXML private FontIcon panRightIcon;
@FXML private Path panUp;
@FXML private FontIcon panUpIcon;
@FXML private Path redo;
@FXML private FontIcon redoIcon;
@FXML private Path undo;
@FXML private FontIcon undoIcon;
@FXML private Path zoomIn;
@FXML private FontIcon zoomInIcon;
@FXML private Path zoomOut;
@FXML private FontIcon zoomOutIcon;
@FXML private Circle zoomToOne;
@FXML private Label zoomToOneLabel;
/* *********************************************************************** *
* START OF JAVAFX PROPERTIES *
* *********************************************************************** */
/*
* ---- onPanDown ----------------------------------------------------------
*/
private final ObjectProperty> onPanDown = new SimpleObjectProperty<>(NavigatorController.this, "onPanDown") {
@Override protected void invalidated() {
setEventHandler(ON_PAN_DOWN, get());
}
};
/**
* Called when the {@code panDown} button is pressed.
*
* @return The "on pan down" property.
*/
public final ObjectProperty> onPanDownProperty() {
return onPanDown;
}
public final EventHandler getOnPanDown() {
return onPanDownProperty().get();
}
public final void setOnPanDown( EventHandler value ) {
onPanDownProperty().set(value);
}
/*
* ---- onPanLeft ----------------------------------------------------------
*/
private final ObjectProperty> onPanLeft = new SimpleObjectProperty<>(NavigatorController.this, "onPanLeft") {
@Override protected void invalidated() {
setEventHandler(ON_PAN_LEFT, get());
}
};
/**
* Called when the {@code panLeft} button is pressed.
*
* @return The "on pan left" property.
*/
public final ObjectProperty> onPanLeftProperty() {
return onPanLeft;
}
public final EventHandler getOnPanLeft() {
return onPanLeftProperty().get();
}
public final void setOnPanLeft( EventHandler value ) {
onPanLeftProperty().set(value);
}
/*
* ---- onPanRight ---------------------------------------------------------
*/
private final ObjectProperty> onPanRight = new SimpleObjectProperty<>(NavigatorController.this, "onPanRight") {
@Override protected void invalidated() {
setEventHandler(ON_PAN_RIGHT, get());
}
};
/**
* Called when the {@code panRight} button is pressed.
*
* @return The "on pan right" property.
*/
public final ObjectProperty> onPanRightProperty() {
return onPanRight;
}
public final EventHandler getOnPanRight() {
return onPanRightProperty().get();
}
public final void setOnPanRight( EventHandler value ) {
onPanRightProperty().set(value);
}
/*
* ---- onPanUp ------------------------------------------------------------
*/
private final ObjectProperty> onPanUp = new SimpleObjectProperty<>(NavigatorController.this, "onPanUp") {
@Override protected void invalidated() {
setEventHandler(ON_PAN_UP, get());
}
};
/**
* Called when the {@code panUp} button is pressed.
*
* @return The "on pan up" property.
*/
public final ObjectProperty> onPanUpProperty() {
return onPanUp;
}
public final EventHandler getOnPanUp() {
return onPanUpProperty().get();
}
public final void setOnPanUp( EventHandler value ) {
onPanUpProperty().set(value);
}
/*
* ---- onRedo -------------------------------------------------------------
*/
private final ObjectProperty> onRedo = new SimpleObjectProperty<>(NavigatorController.this, "onRedo") {
@Override protected void invalidated() {
setEventHandler(ON_REDO, get());
}
};
/**
* Called when the {@code redo} button is pressed.
*
* @return The "on redo" property.
*/
public final ObjectProperty> onRedoProperty() {
return onRedo;
}
public final EventHandler getOnRedo() {
return onRedoProperty().get();
}
public final void setOnRedo( EventHandler value ) {
onRedoProperty().set(value);
}
/*
* ---- onUndo -------------------------------------------------------------
*/
private final ObjectProperty> onUndo = new SimpleObjectProperty<>(NavigatorController.this, "onUndo") {
@Override protected void invalidated() {
setEventHandler(ON_UNDO, get());
}
};
/**
* Called when the {@code undo} button is pressed.
*
* @return The "on undo" property.
*/
public final ObjectProperty> onUndoProperty() {
return onUndo;
}
public final EventHandler getOnUndo() {
return onUndoProperty().get();
}
public final void setOnUndo( EventHandler value ) {
onUndoProperty().set(value);
}
/*
* ---- onZoomIn -----------------------------------------------------------
*/
private final ObjectProperty> onZoomIn = new SimpleObjectProperty<>(NavigatorController.this, "onZoomIn") {
@Override protected void invalidated() {
setEventHandler(ON_ZOOM_IN, get());
}
};
/**
* Called when the {@code zoomIn} button is pressed.
*
* @return The "on zoom in" property.
*/
public final ObjectProperty> onZoomInProperty() {
return onZoomIn;
}
public final EventHandler getOnZoomIn() {
return onZoomInProperty().get();
}
public final void setOnZoomIn( EventHandler value ) {
onZoomInProperty().set(value);
}
/*
* ---- onZoomOut ----------------------------------------------------------
*/
private final ObjectProperty> onZoomOut = new SimpleObjectProperty<>(NavigatorController.this, "onZoomOut") {
@Override protected void invalidated() {
setEventHandler(ON_ZOOM_OUT, get());
}
};
/**
* Called when the {@code zoomOut} button is pressed.
*
* @return The "on zoom out" property.
*/
public final ObjectProperty> onZoomOutProperty() {
return onZoomOut;
}
public final EventHandler getOnZoomOut() {
return onZoomOutProperty().get();
}
public final void setOnZoomOut( EventHandler value ) {
onZoomOutProperty().set(value);
}
/*
* ---- onZoomToOne --------------------------------------------------------
*/
private final ObjectProperty> onZoomToOne = new SimpleObjectProperty<>(NavigatorController.this, "onZoomToOne") {
@Override protected void invalidated() {
setEventHandler(ON_ZOOM_TO_ONE, get());
}
};
/**
* Called when the {@code zoomToOne} button is pressed.
*
* @return The "on zoom to one" property.
*/
public final ObjectProperty> onZoomToOneProperty() {
return onZoomToOne;
}
public final EventHandler getOnZoomToOne() {
return onZoomToOneProperty().get();
}
public final void setOnZoomToOne( EventHandler value ) {
onZoomToOneProperty().set(value);
}
/*
* ---- panDownDisabled ----------------------------------------------------
*/
private final BooleanProperty panDownDisabled = new SimpleBooleanProperty(NavigatorController.this, "panDownDisabled", false);
/**
* Indicates whether or not the {@code panDown} button is disabled.
*
* @return Whether or not the "pan down" button is disabled.
*/
public final BooleanProperty panDownDisabledProperty() {
return panDownDisabled;
}
public final boolean isPanDownDisabled() {
return panDownDisabledProperty().get();
}
public final void setPanDownDisabled( boolean disabled ) {
panDownDisabledProperty().set(disabled);
}
/*
* ---- panLeftDisabled ----------------------------------------------------
*/
private final BooleanProperty panLeftDisabled = new SimpleBooleanProperty(NavigatorController.this, "panLeftDisabled", false);
/**
* Indicates whether or not the {@code panLeft} button is disabled.
*
* @return Whether or not the "pan left" button is disabled.
*/
public final BooleanProperty panLeftDisabledProperty() {
return panLeftDisabled;
}
public final boolean isPanLeftDisabled() {
return panLeftDisabledProperty().get();
}
public final void setPanLeftDisabled( boolean disabled ) {
panLeftDisabledProperty().set(disabled);
}
/*
* ---- panRightDisabled ---------------------------------------------------
*/
private final BooleanProperty panRightDisabled = new SimpleBooleanProperty(NavigatorController.this, "panRightDisabled", false);
/**
* Indicates whether or not the {@code panRight} button is disabled.
*
* @return Whether or not the "pan right" button is disabled.
*/
public final BooleanProperty panRightDisabledProperty() {
return panRightDisabled;
}
public final boolean isPanRightDisabled() {
return panRightDisabledProperty().get();
}
public final void setPanRightDisabled( boolean disabled ) {
panRightDisabledProperty().set(disabled);
}
/*
* ---- panUpDisabled ------------------------------------------------------
*/
private final BooleanProperty panUpDisabled = new SimpleBooleanProperty(NavigatorController.this, "panUpDisabled", false);
/**
* Indicates whether or not the {@code panUp} button is disabled.
*
* @return Whether or not the "pan up" button is disabled.
*/
public final BooleanProperty panUpDisabledProperty() {
return panUpDisabled;
}
public final boolean isPanUpDisabled() {
return panUpDisabledProperty().get();
}
public final void setPanUpDisabled( boolean disabled ) {
panUpDisabledProperty().set(disabled);
}
/*
* ---- redoDisabled -------------------------------------------------------
*/
private final BooleanProperty redoDisabled = new SimpleBooleanProperty(NavigatorController.this, "redoDisabled", false);
/**
* Indicates whether or not the {@code redo} button is disabled.
*
* @return Whether or not the "redo" button is disabled.
*/
public final BooleanProperty redoDisabledProperty() {
return redoDisabled;
}
public final boolean isRedoDisabled() {
return redoDisabledProperty().get();
}
public final void setRedoDisabled( boolean disabled ) {
redoDisabledProperty().set(disabled);
}
/*
* ---- undoDisabled -------------------------------------------------------
*/
private final BooleanProperty undoDisabled = new SimpleBooleanProperty(NavigatorController.this, "undoDisabled", false);
/**
* Indicates whether or not the {@code undo} button is disabled.
*
* @return Whether or not the "undo" button is disabled.
*/
public final BooleanProperty undoDisabledProperty() {
return undoDisabled;
}
public final boolean isUndoDisabled() {
return undoDisabledProperty().get();
}
public final void setUndoDisabled( boolean disabled ) {
undoDisabledProperty().set(disabled);
}
/*
* ---- zoomInDisabled -----------------------------------------------------
*/
private final BooleanProperty zoomInDisabled = new SimpleBooleanProperty(NavigatorController.this, "zoomInDisabled", false);
/**
* Indicates whether or not the {@code zoomIn} button is disabled.
*
* @return Whether or not the "zoom in" button is disabled.
*/
public final BooleanProperty zoomInDisabledProperty() {
return zoomInDisabled;
}
public final boolean isZoomInDisabled() {
return zoomInDisabledProperty().get();
}
public final void setZoomInDisabled( boolean disabled ) {
zoomInDisabledProperty().set(disabled);
}
/*
* ---- zoomOutDisabled ----------------------------------------------------
*/
private final BooleanProperty zoomOutDisabled = new SimpleBooleanProperty(NavigatorController.this, "zoomOutDisabled", false);
/**
* Indicates whether or not the {@code zoomOut} button is disabled.
*
* @return Whether or not the "zoom out" button is disabled.
*/
public final BooleanProperty zoomOutDisabledProperty() {
return zoomOutDisabled;
}
public final boolean isZoomOutDisabled() {
return zoomOutDisabledProperty().get();
}
public final void setZoomOutDisabled( boolean disabled ) {
zoomOutDisabledProperty().set(disabled);
}
/*
* ---- zoomToOneDisabled --------------------------------------------------
*/
private final BooleanProperty zoomToOneDisabled = new SimpleBooleanProperty(NavigatorController.this, "zoomToOneDisabled", false);
/**
* Indicates whether or not the {@code zoomToOne} button is disabled.
*
* @return Whether or not the "zoom to one" button is disabled.
*/
public final BooleanProperty zoomToOneDisabledProperty() {
return zoomToOneDisabled;
}
public final boolean isZoomToOneDisabled() {
return zoomToOneDisabledProperty().get();
}
public final void setZoomToOneDisabled( boolean disabled ) {
zoomToOneDisabledProperty().set(disabled);
}
/* *********************************************************************** *
* END OF JAVAFX PROPERTIES *
* *********************************************************************** */
public NavigatorController() {
init();
initButtonListeners();
}
@SuppressWarnings( "ConvertToStringSwitch" )
private void fireNavigationEvent ( Node source ) {
String id = source.getId();
if ( "panDown".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_PAN_DOWN));
} else if ( "panLeft".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_PAN_LEFT));
} else if ( "panRight".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_PAN_RIGHT));
} else if ( "panUp".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_PAN_UP));
} else if ( "redo".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_REDO));
} else if ( "undo".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_UNDO));
} else if ( "zoomIn".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_ZOOM_IN));
} else if ( "zoomOut".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_ZOOM_OUT));
} else if ( "zoomToOne".equals(id) ) {
Event.fireEvent(source, new Event(this, source, ON_ZOOM_TO_ONE));
} else {
LogUtils.log(LOGGER, WARNING, "Unexpected identifier [{0}].", id);
}
}
private void init() {
URL resource = NavigatorController.class.getResource("impl/fxml/navigator.fxml");
try {
FXMLLoader loader = new FXMLLoader(resource);
loader.setController(this);
loader.setRoot(this);
loader.load();
} catch ( IOException ex ) {
LogUtils.log(
LOGGER,
SEVERE,
ex,
"Unable to load ''navigator.xml'' resource [{0}].",
resource.toExternalForm()
);
}
}
private void initButtonListeners() {
initButtonListeners(panDown, panDownIcon, PAN_DOWN_ACCELERATOR);
panDown.disableProperty().bind(panDownDisabledProperty());
panDownIcon.disableProperty().bind(panDownDisabledProperty());
initButtonListeners(panLeft, panLeftIcon, PAN_LEFT_ACCELERATOR);
panLeft.disableProperty().bind(panLeftDisabledProperty());
panLeftIcon.disableProperty().bind(panLeftDisabledProperty());
initButtonListeners(panRight, panRightIcon, PAN_RIGHT_ACCELERATOR);
panRight.disableProperty().bind(panRightDisabledProperty());
panRightIcon.disableProperty().bind(panRightDisabledProperty());
initButtonListeners(panUp, panUpIcon, PAN_UP_ACCELERATOR);
panUp.disableProperty().bind(panUpDisabledProperty());
panUpIcon.disableProperty().bind(panUpDisabledProperty());
initButtonListeners(redo, redoIcon, REDO_ACCELERATOR);
redo.disableProperty().bind(redoDisabledProperty());
redoIcon.disableProperty().bind(redoDisabledProperty());
initButtonListeners(undo, undoIcon, UNDO_ACCELERATOR);
undo.disableProperty().bind(undoDisabledProperty());
undoIcon.disableProperty().bind(undoDisabledProperty());
initButtonListeners(zoomIn, zoomInIcon, ZOOM_IN_ACCELERATOR);
zoomIn.disableProperty().bind(zoomInDisabledProperty());
zoomInIcon.disableProperty().bind(zoomInDisabledProperty());
initButtonListeners(zoomOut, zoomOutIcon, ZOOM_OUT_ACCELERATOR);
zoomOut.disableProperty().bind(zoomOutDisabledProperty());
zoomOutIcon.disableProperty().bind(zoomOutDisabledProperty());
initButtonListeners(zoomToOne, zoomToOneLabel, ZOOM_TO_ONE_ACCELERATOR);
zoomToOne.disableProperty().bind(zoomToOneDisabledProperty());
zoomToOneLabel.disableProperty().bind(zoomToOneDisabledProperty());
}
@SuppressWarnings( "CallToThreadYield" )
private void initButtonListeners( final Shape shape, final Node icon, KeyCombination accelerator ) {
shape.disabledProperty().addListener(( observable, wasDisabled, isDisabled ) -> {
updateStyle(shape);
icon.setOpacity(isDisabled ? 0.3 : 1.0);
});
shape.focusedProperty().addListener(( observable, hadFocus, hasFocus ) -> {
updateStyle(shape);
});
shape.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
if ( shape.isFocused() && !shape.isDisabled() ) {
switch ( event.getCode() ) {
case ENTER:
case SPACE:
updateStyle(shape, FillStyle.PRESSED, StrokeStyle.FOCUSED);
event.consume();
break;
}
}
});
shape.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if ( shape.isFocused() && !shape.isDisabled() ) {
switch ( event.getCode() ) {
case ENTER:
case SPACE:
fireNavigationEvent(shape);
updateStyle(shape);
event.consume();
break;
}
}
});
addEventHandler(KeyEvent.KEY_RELEASED, event -> {
if ( !shape.isDisabled() && accelerator.match(event) ) {
ThreadPools.fixedThreadPool().execute(() -> {
Platform.runLater(() -> {
shape.requestFocus();
shape.fireEvent(new KeyEvent(
KeyEvent.KEY_PRESSED,
KeyCode.SPACE.getChar(),
KeyCode.SPACE.getName(),
KeyCode.SPACE,
false,
false,
false,
false
));
});
ThreadUtils.sleep(100);
Platform.runLater(() -> {
shape.fireEvent(new KeyEvent(
KeyEvent.KEY_RELEASED,
KeyCode.SPACE.getChar(),
KeyCode.SPACE.getName(),
KeyCode.SPACE,
false,
false,
false,
false
));
});
});
event.consume();
}
});
}
private boolean isPanButton( Node node ) {
return ( node == panDown || node == panLeft || node == panRight || node == panUp );
}
@FXML
@SuppressWarnings( "null" )
private void mouseClicked( MouseEvent event ) {
Node source = (Node) event.getSource();
source.requestFocus();
if ( source != null && !source.isDisabled() && PRIMARY == event.getButton() ) {
fireNavigationEvent(source);
}
event.consume();
}
@FXML
private void mouseEntered( MouseEvent event ) {
updateStyle((Node) event.getSource());
event.consume();
}
@FXML
private void mouseExited( MouseEvent event ) {
updateStyle((Node) event.getSource());
event.consume();
}
@FXML
private void mousePressed( MouseEvent event ) {
updateStyle((Node) event.getSource());
event.consume();
}
@FXML
private void mouseReleased( MouseEvent event ) {
updateStyle((Node) event.getSource());
event.consume();
}
private void updateStyle( Node node ) {
updateStyle(
node,
node.isDisabled()
? FillStyle.DISABLED
: ( node.isPressed()
? FillStyle.PRESSED
: ( node.isHover()
? FillStyle.HOVER
: ( isPanButton(node)
? FillStyle.LIGHTER
: FillStyle.DEFAULT ) ) ),
node.isFocused() ? StrokeStyle.FOCUSED : StrokeStyle.DEFAULT
);
}
private void updateStyle( Node node, FillStyle fill, StrokeStyle stroke ) {
node.setStyle(MessageFormat.format("{0}; {1};", fill.getStyle(), stroke.getStyle()));
}
@SuppressWarnings( "PackageVisibleInnerClass" )
enum FillStyle {
DEFAULT("-fx-fill: -normal-color"),
LIGHTER("-fx-fill: -normal-color-lighter"),
HOVER("-fx-fill: -hover-color"),
PRESSED("-fx-fill: -pressed-color"),
DISABLED("-fx-fill: -disabled-color");
private final String style;
FillStyle( String style ) {
this.style = style;
}
String getStyle() {
return style;
}
}
@SuppressWarnings( "PackageVisibleInnerClass" )
enum StrokeStyle {
DEFAULT("-fx-stroke: -fx-outer-border"),
FOCUSED("-fx-stroke: -fx-focus-color");
private final String style;
StrokeStyle( String style ) {
this.style = style;
}
String getStyle() {
return style;
}
}
}