package hello; import javafx.animation.AnimationTimer; import javafx.animation.FillTransition; import javafx.application.Application; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.RadioButton; import javafx.scene.control.ToggleGroup; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.BackgroundImage; import javafx.scene.layout.BackgroundPosition; import javafx.scene.layout.BackgroundRepeat; import javafx.scene.layout.BackgroundSize; import javafx.scene.layout.CornerRadii; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.paint.ImagePattern; import javafx.scene.paint.Paint; import javafx.scene.shape.Circle; import javafx.scene.shape.Ellipse; import javafx.scene.shape.Rectangle; import javafx.stage.Stage; import javafx.util.Duration; import com.sun.javafx.perf.PerformanceTracker; /** */ public class Bug extends Application { final double sceneWidth = 1024; final double sceneHeight = 1280; @Override public void start(Stage stage) throws Exception { final double halfSqrt = Math.sqrt(.5); // Make sure the rectangles are smaller than the circle's dirty region final float squareLength = (float) (halfSqrt * Math.min(sceneWidth, sceneHeight)) - 4; Rectangle background = new Rectangle((sceneWidth - squareLength) / 2f, (sceneHeight - squareLength) / 2f, squareLength, squareLength); Group root = new Group(background); for (int i=0; i<400; i++) { final Rectangle rect = new Rectangle(background.getX(), background.getY(), background.getWidth(), background.getHeight()); rect.setFill(Color.color(Math.random(), Math.random(), Math.random(), .001)); root.getChildren().add(rect); } ToggleGroup toggles = new ToggleGroup(); VBox controls = new VBox(); controls.setBackground(new Background(new BackgroundFill(Color.WHITESMOKE, new CornerRadii(12), new Insets(5)))); controls.setPadding(new Insets(20)); controls.setSpacing(7); Group cover = new Group(); createRegionOption(cover, toggles, controls, "Region with solid fill", createSolidBackground(Color.BLUEVIOLET)); createRegionOption(cover, toggles, controls, "Region with solid png", createImageBackground("test-opaque.png")); createRegionOption(cover, toggles, controls, "Region with jpg", createImageBackground("test-opaque.jpg")); createRegionOption(cover, toggles, controls, "Region with transparent png", createImageBackground("test-transparent.png")); createRoundRectangleOption(cover, toggles, controls, "Rectangle with solid fill", Color.BLUEVIOLET, (int)background.getX(), (int)background.getY(), (int)(background.getWidth()+2), (int)(background.getHeight()+2), 0); createRoundRectangleOption(cover, toggles, controls, "Rectangle with solid png", new ImagePattern(createImage("test-opaque.png")), (int)background.getX(), (int)background.getY(), (int)(background.getWidth()+2), (int)(background.getHeight()+2), 0); createRoundRectangleOption(cover, toggles, controls, "Rectangle with jpg", new ImagePattern(createImage("test-opaque.jpg")), (int)background.getX(), (int)background.getY(), (int)(background.getWidth()+2), (int)(background.getHeight()+2), 0); createRoundRectangleOption(cover, toggles, controls, "Rectangle with transparent png", new ImagePattern(createImage("test-transparent.png")), (int)background.getX(), (int)background.getY(), (int)(background.getWidth()+2), (int)(background.getHeight()+2), 0); createRoundRectangleOption(cover, toggles, controls, "Wide Round Rectangle with solid fill", Color.BLUEVIOLET, background.getX()-6, background.getY()-1, background.getWidth()+12, background.getHeight()+2, 10); createRoundRectangleOption(cover, toggles, controls, "Tall Round Rectangle with solid fill", Color.BLUEVIOLET, background.getX()-1, background.getY()-6, background.getWidth()+2, background.getHeight()+12, 10); createCircleOption(cover, toggles, controls, "Circle with solid fill", new Color(0, 1, 0, 1)); createCircleOption(cover, toggles, controls, "Circle with solid png", new ImagePattern(createImage("test-opaque.png"))); createCircleOption(cover, toggles, controls, "Circle with jpg", new ImagePattern(createImage("test-opaque.jpg"))); createCircleOption(cover, toggles, controls, "Circle with transparent png", new ImagePattern(createImage("test-transparent.png"))); createEllipseOption(cover, toggles, controls, "Ellipse with solid fill", Color.BLUEVIOLET); createEllipseOption(cover, toggles, controls, "Ellipse with solid png", new ImagePattern(createImage("test-opaque.png"))); createEllipseOption(cover, toggles, controls, "Ellipse with jpg", new ImagePattern(createImage("test-opaque.jpg"))); createEllipseOption(cover, toggles, controls, "Ellipse with transparent png", new ImagePattern(createImage("test-transparent.png"))); createImageViewOption(cover, toggles, controls, "ImageView with solid png", createImage("test-opaque.png")); createImageViewOption(cover, toggles, controls, "ImageView with jpg", createImage("test-opaque.jpg")); createImageViewOption(cover, toggles, controls, "ImageView with transparent png", createImage("test-transparent.png")); createImageViewWithFitWidthOption(cover, toggles, controls, "Fitted ImageView with solid png", createImage("test-opaque.png"), background.getX() - 1, background.getY() - 1, background.getWidth() + 2, background.getHeight() + 2); createImageViewWithFitWidthOption(cover, toggles, controls, "Fitted ImageView with jpg", createImage("test-opaque.jpg"), background.getX() - 1, background.getY() - 1, background.getWidth() + 2, background.getHeight() + 2); createImageViewWithFitWidthOption(cover, toggles, controls, "Fitted ImageView with transparent png", createImage("test-transparent.png"), background.getX() - 1, background.getY() - 1, background.getWidth() + 2, background.getHeight() + 2); createImageViewWithFitWidthOption(cover, toggles, controls, "Offset ImageView with solid png", createImage("test-opaque.png"), 0, 0, background.getWidth() + 2, background.getHeight() + 2); createImageViewWithFitWidthOption(cover, toggles, controls, "Offset ImageView with jpg", createImage("test-opaque.jpg"), 0, 0, background.getWidth() + 2, background.getHeight() + 2); createImageViewWithFitWidthOption(cover, toggles, controls, "Small ImageView with solid png", createImage("test-opaque.png"), 0, 0, -1, -1); createImageViewWithFitWidthOption(cover, toggles, controls, "Small ImageView with jpg", createImage("test-opaque.jpg"), 0, 0, -1, -1); createImageViewWithFitWidthOption(cover, toggles, controls, "ProperRatio ImageView with solid png", createImage("test-opaque.png"), background.getX() - 1, background.getY() - 1, background.getWidth() + 2, background.getHeight() + 2, true); createImageViewWithFitWidthOption(cover, toggles, controls, "ProperRatio ImageView with jpg", createImage("test-opaque.jpg"), background.getX() - 1, background.getY() - 1, background.getWidth() + 2, background.getHeight() + 2, true); root.getChildren().addAll(cover, controls); Scene scene = new Scene(root, sceneWidth, sceneHeight); stage.setScene(scene); stage.show(); FillTransition tx = new FillTransition(Duration.seconds(5), background, Color.BLACK, Color.RED); tx.setCycleCount(FillTransition.INDEFINITE); tx.setAutoReverse(true); tx.play(); final PerformanceTracker tracker = PerformanceTracker.getSceneTracker(scene); AnimationTimer trackerTimer = new AnimationTimer() { long ticks = 0; @Override public void handle(long now) { ticks++; if (ticks % 60 == 0) { System.out.println(tracker.getInstantFPS()); } } }; trackerTimer.start(); } private RadioButton createRegionOption(Group root, ToggleGroup toggles, VBox controls, String title, Background background) { final Region cover = new Region(); cover.setPrefWidth(sceneWidth); cover.setPrefHeight(sceneHeight); cover.setBackground(background); return createRadioButton(root, title, toggles, controls, cover); } private RadioButton createRoundRectangleOption(Group root, ToggleGroup toggles, VBox controls, String title, Paint paint, double x, double y, double w, double h, double arc) { Rectangle cover = new Rectangle(w, h, paint); cover.setArcHeight(arc); cover.setArcWidth(arc); cover.setX(x); cover.setY(y); return createRadioButton(root, title, toggles, controls, cover); } private RadioButton createCircleOption(Group root, ToggleGroup toggles, VBox controls, String title, Paint paint) { Circle cover = new Circle(sceneWidth/2f, sceneHeight/2f, Math.min(sceneHeight, sceneWidth) / 2f, paint); return createRadioButton(root, title, toggles, controls, cover); } private RadioButton createEllipseOption(Group root, ToggleGroup toggles, VBox controls, String title, Paint paint) { Ellipse cover = new Ellipse(sceneWidth/2f, sceneHeight/2f, sceneWidth/2f, sceneHeight/2f); cover.setFill(paint); return createRadioButton(root, title, toggles, controls, cover); } private RadioButton createImageViewOption(Group root, ToggleGroup toggles, VBox controls, String title, Image image) { return createImageViewWithFitWidthOption(root, toggles, controls, title, image, 0, 0, sceneWidth, sceneHeight); } private RadioButton createImageViewWithFitWidthOption(Group root, ToggleGroup toggles, VBox controls, String title, Image image, double x, double y, double fitWidth, double fitHeight) { return createImageViewWithFitWidthOption(root, toggles, controls, title, image, x, y, fitWidth, fitHeight, false); } private RadioButton createImageViewWithFitWidthOption(Group root, ToggleGroup toggles, VBox controls, String title, Image image, double x, double y, double fitWidth, double fitHeight, boolean preserveRatio) { ImageView cover = new ImageView(image); cover.setPreserveRatio(preserveRatio); cover.setX(x); cover.setY(y); cover.setFitWidth(fitWidth); cover.setFitHeight(fitHeight); return createRadioButton(root, title, toggles, controls, cover); } private RadioButton createRadioButton(Group root, String title, ToggleGroup toggles, VBox controls, Node node) { final RadioButton rad = new RadioButton(title); rad.selectedProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) { if (newValue) { root.getChildren().add(node); } else { root.getChildren().remove(node); } } }); toggles.getToggles().add(rad); controls.getChildren().add(rad); return rad; } private Background createSolidBackground(Color color) { return new Background(new BackgroundFill(color, null, null)); } private Background createImageBackground(String imageName) { return new Background( new BackgroundImage( new Image(Bug.class.getResource(imageName).toExternalForm()), BackgroundRepeat.REPEAT, BackgroundRepeat.REPEAT, BackgroundPosition.DEFAULT, BackgroundSize.DEFAULT)); } private Image createImage(String imageName) { return new Image(Bug.class.getResource(imageName).toExternalForm()); } public static void main(String[] args) { launch(args); } }