
wallettemplate.utils.GuiUtils Maven / Gradle / Ivy
package wallettemplate.utils;
import com.google.common.base.Throwables;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.Pane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Duration;
import wallettemplate.MainController;
import java.io.IOException;
import java.net.URL;
import java.util.function.BiConsumer;
import static com.google.common.base.Preconditions.checkState;
import static wallettemplate.utils.WTUtils.unchecked;
public class GuiUtils {
public static void runAlert(BiConsumer setup) {
try {
// JavaFX2 doesn't actually have a standard alert template. Instead the Scene Builder app will create FXML
// files for an alert window for you, and then you customise it as you see fit. I guess it makes sense in
// an odd sort of way.
Stage dialogStage = new Stage();
dialogStage.initModality(Modality.APPLICATION_MODAL);
FXMLLoader loader = new FXMLLoader(GuiUtils.class.getResource("alert.fxml"));
Pane pane = loader.load();
AlertWindowController controller = loader.getController();
setup.accept(dialogStage, controller);
dialogStage.setScene(new Scene(pane));
dialogStage.showAndWait();
} catch (IOException e) {
// We crashed whilst trying to show the alert dialog (this should never happen). Give up!
throw new RuntimeException(e);
}
}
public static void crashAlert(Throwable t) {
t.printStackTrace();
Throwable rootCause = Throwables.getRootCause(t);
Runnable r = () -> {
runAlert((stage, controller) -> controller.crashAlert(stage, rootCause.toString()));
Platform.exit();
};
if (Platform.isFxApplicationThread())
r.run();
else
Platform.runLater(r);
}
/** Show a GUI alert box for any unhandled exceptions that propagate out of this thread. */
public static void handleCrashesOnThisThread() {
Thread.currentThread().setUncaughtExceptionHandler((thread, exception) -> {
GuiUtils.crashAlert(Throwables.getRootCause(exception));
});
}
public static void informationalAlert(String message, String details, Object... args) {
String formattedDetails = String.format(details, args);
Runnable r = () -> runAlert((stage, controller) -> controller.informational(stage, message, formattedDetails));
if (Platform.isFxApplicationThread())
r.run();
else
Platform.runLater(r);
}
public static final int UI_ANIMATION_TIME_MSEC = 600;
public static final Duration UI_ANIMATION_TIME = Duration.millis(UI_ANIMATION_TIME_MSEC);
public static Animation fadeIn(Node ui) {
return fadeIn(ui, 0);
}
public static Animation fadeIn(Node ui, int delayMillis) {
ui.setCache(true);
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME_MSEC), ui);
ft.setFromValue(0.0);
ft.setToValue(1.0);
ft.setOnFinished(ev -> ui.setCache(false));
ft.setDelay(Duration.millis(delayMillis));
ft.play();
return ft;
}
public static Animation fadeOut(Node ui) {
FadeTransition ft = new FadeTransition(Duration.millis(UI_ANIMATION_TIME_MSEC), ui);
ft.setFromValue(ui.getOpacity());
ft.setToValue(0.0);
ft.play();
return ft;
}
public static Animation fadeOutAndRemove(Pane parentPane, Node... nodes) {
Animation animation = fadeOut(nodes[0]);
animation.setOnFinished(actionEvent -> parentPane.getChildren().removeAll(nodes));
return animation;
}
public static Animation fadeOutAndRemove(Duration duration, Pane parentPane, Node... nodes) {
nodes[0].setCache(true);
FadeTransition ft = new FadeTransition(duration, nodes[0]);
ft.setFromValue(nodes[0].getOpacity());
ft.setToValue(0.0);
ft.setOnFinished(actionEvent -> parentPane.getChildren().removeAll(nodes));
ft.play();
return ft;
}
public static void blurOut(Node node) {
GaussianBlur blur = new GaussianBlur(0.0);
node.setEffect(blur);
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 10.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME_MSEC), kv);
timeline.getKeyFrames().add(kf);
timeline.play();
}
public static void blurIn(Node node) {
GaussianBlur blur = (GaussianBlur) node.getEffect();
Timeline timeline = new Timeline();
KeyValue kv = new KeyValue(blur.radiusProperty(), 0.0);
KeyFrame kf = new KeyFrame(Duration.millis(UI_ANIMATION_TIME_MSEC), kv);
timeline.getKeyFrames().add(kf);
timeline.setOnFinished(actionEvent -> node.setEffect(null));
timeline.play();
}
public static ScaleTransition zoomIn(Node node) {
return zoomIn(node, 0);
}
public static ScaleTransition zoomIn(Node node, int delayMillis) {
return scaleFromTo(node, 0.95, 1.0, delayMillis);
}
public static ScaleTransition explodeOut(Node node) {
return scaleFromTo(node, 1.0, 1.05, 0);
}
private static ScaleTransition scaleFromTo(Node node, double from, double to, int delayMillis) {
ScaleTransition scale = new ScaleTransition(Duration.millis(UI_ANIMATION_TIME_MSEC / 2), node);
scale.setFromX(from);
scale.setFromY(from);
scale.setToX(to);
scale.setToY(to);
scale.setDelay(Duration.millis(delayMillis));
scale.play();
return scale;
}
/**
* A useful helper for development purposes. Used as a switch for loading files from local disk, allowing live
* editing whilst the app runs without rebuilds.
*/
public static URL getResource(String name) {
if (false)
return unchecked(() -> new URL("file:///your/path/here/src/main/wallettemplate/" + name));
else
return MainController.class.getResource(name);
}
public static void checkGuiThread() {
checkState(Platform.isFxApplicationThread());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy