import com.sun.javafx.perf.PerformanceTracker; import java.text.DecimalFormat; import java.text.NumberFormat; import javafx.animation.AnimationTimer; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.value.ObservableValue; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.control.Slider; import javafx.scene.effect.DropShadow; import javafx.scene.effect.InnerShadow; import javafx.scene.layout.GridPane; import javafx.scene.paint.Color; import javafx.scene.text.Font; import javafx.scene.text.FontWeight; import javafx.scene.text.Text; import javafx.stage.Stage; import javafx.util.Duration; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ /** * * @author ekaterina.pavlova@oracle.com */ class PropDesc { String name; Double min; Double max; Object initialValue; ObservableValue valueModel; public PropDesc(String name, ObservableValue valueModel) { this.name = name; this.valueModel = valueModel; this.initialValue = get(valueModel); } public PropDesc(String name, DoubleProperty valueModel, Double min, Double max) { this.name = name; this.valueModel = valueModel; this.initialValue = valueModel.get(); this.min = min; this.max = max; } static public Object get(ObservableValue valueModel) { if (valueModel instanceof DoubleProperty) { return ((DoubleProperty)valueModel).get(); } else if (valueModel instanceof ObjectProperty) { return ((ObjectProperty)valueModel).get(); } return null; } static public void set(ObservableValue valueModel, Object value) { if (valueModel instanceof DoubleProperty) { ((DoubleProperty)valueModel).set((Double)value); } else if (valueModel instanceof ObjectProperty) { ((ObjectProperty)valueModel).set(value); } } } public class EffectMemTest extends Application { static double SCENE_WEIGHT = 600.0; static double SCENE_HEIGHT = 400.0; private static final NumberFormat twoDp = new DecimalFormat("0.##"); static Node innerShadow() { Group g = new Group(); InnerShadow is = new InnerShadow(); is.setOffsetX(4.0f); is.setOffsetY(4.0f); Text t = new Text(); t.setEffect(is); t.setText("InnerShadow"); t.setFill(Color.YELLOW); t.setFont(Font.font("null", FontWeight.BOLD, 80)); t.setTranslateX(10); t.setTranslateY(100); g.getChildren().add(t); g.getChildren().add(createPropertyControl(new PropDesc("Radius", is.radiusProperty(), 0d, 60d), new PropDesc("Offset X", is.offsetXProperty(), -10d, 10d), new PropDesc("Offset Y", is.offsetYProperty(), -10d, 10d), new PropDesc("Height", is.heightProperty(), 0d, 50d), new PropDesc("Width", is.widthProperty(), 0d, 50d))); return g; } static Node createPropertyControl(PropDesc...properties) { GridPane grid = new GridPane(); grid.setVgap(10); grid.setHgap(10); grid.setLayoutX(10); grid.setLayoutY(200); int row = 0; for (PropDesc property: properties) { final PropDesc prop = property; Label propName = new Label(prop.name+ ":"); propName.getStyleClass().add("sample-control-grid-prop-label"); GridPane.setConstraints(propName, 0, row); grid.getChildren().add(propName); final Label valueLabel = new Label(twoDp.format(prop.initialValue)); GridPane.setConstraints(valueLabel, 2, row); final Slider slider = new Slider(); slider.setMin(prop.min); slider.setMax(prop.max); slider.setValue(((Number) prop.initialValue).doubleValue()); GridPane.setConstraints(slider, 1, row); slider.setMaxWidth(Double.MAX_VALUE); slider.valueProperty().addListener(new InvalidationListener() { @Override public void invalidated(Observable ov) { PropDesc.set(prop.valueModel, slider.getValue()); valueLabel.setText(twoDp.format(slider.getValue())); } }); grid.getChildren().addAll(slider, valueLabel); row ++; } return grid; } static Node dropShadow() { Group g = new Group(); DropShadow ds = new DropShadow(); ds.setOffsetY(3.0f); ds.setColor(Color.color(0.4f, 0.4f, 0.4f)); Text t = new Text(); t.setEffect(ds); t.setCache(true); t.setX(10.0f); t.setY(100.0f); t.setFill(Color.RED); t.setText("JavaFX drop shadow..."); t.setFont(Font.font("null", FontWeight.BOLD, 32)); g.getChildren().add(t); /* DropShadow ds1 = new DropShadow(); ds1.setOffsetY(4.0f); Circle c = new Circle(); c.setEffect(ds1); c.setCenterX(50.0f); c.setCenterY(325.0f); c.setRadius(30.0f); c.setFill(Color.ORANGE); c.setCache(true); g.getChildren().add(c); */ g.getChildren().add(createPropertyControl(new PropDesc("Radius", ds.radiusProperty(), 0d, 60d), new PropDesc("Offset X", ds.offsetXProperty(), -10d, 10d), new PropDesc("Offset Y", ds.offsetYProperty(), -10d, 10d), new PropDesc("Height", ds.heightProperty(), 0d, 50d), new PropDesc("Width", ds.widthProperty(), 0d, 50d))); return g; } Stage stage; PerformanceTracker perfTracker; Group rootGroup; int iters=1; @Override public void start(Stage primaryStage) { stage = new Stage(); rootGroup = new Group(); Scene scene = new Scene(rootGroup, SCENE_WEIGHT, SCENE_HEIGHT); stage.setScene(scene); stage.sizeToScene(); stage.setVisible(true); perfTracker = PerformanceTracker.getSceneTracker(scene); Timeline fpsTimeline = new Timeline(); fpsTimeline.setCycleCount(Timeline.INDEFINITE); KeyFrame fpsKeyFrame = new KeyFrame(Duration.valueOf(2000), new EventHandler() { @Override public void handle(ActionEvent e) { String fpsText = String.format("FPS: %.2f", perfTracker.getInstantFPS()); System.out.println(fpsText); } }); fpsTimeline.getKeyFrames().add(fpsKeyFrame); AnimationTimer objectsAllocator = new AnimationTimer() { boolean stop = false; @Override public void handle(long l) { stage.setTitle("Iter " + iters); // rootGroup.getChildren().clear(); //rootGroup.getChildren().add(0, (iters % 2 == 0 ? dropShadow() : innerShadow())); if (iters % 2 == 0) rootGroup.getChildren().clear(); else rootGroup.getChildren().add(dropShadow()); if (iters % 100 == 0) { System.out.println("Passed " + iters + " iters"); } iters++; } }; fpsTimeline.play(); objectsAllocator.start(); } public static void main(String[] args) { Application.launch(EffectMemTest.class, args); } }