{"id":2263,"date":"2012-12-16T14:08:07","date_gmt":"2012-12-16T13:08:07","guid":{"rendered":"http:\/\/sahits.ch\/blog\/?p=2263"},"modified":"2012-12-16T14:08:07","modified_gmt":"2012-12-16T13:08:07","slug":"overlay-with-anchorlayout","status":"publish","type":"post","link":"http:\/\/sahits.ch\/blog\/blog\/2012\/12\/16\/overlay-with-anchorlayout\/","title":{"rendered":"Overlay with AnchorLayout"},"content":{"rendered":"<p>Aim of this post is to show how multiple animations or other nodes can be placed side by side in an efficient way on a single layer on the stack<\/p>\n<p><!--more--><\/p>\n<p>The basic example is still the same as in the <a href=\"http:\/\/sahits.ch\/blog\/?p=2261\">last post<\/a>. However this time the ImageView is put into an AnchorPane which is added on the stack.<\/p>\n<pre class=\"brush:java\">package javafxtest;\r\n\r\nimport java.io.File;\r\nimport java.io.FileInputStream;\r\nimport java.io.FileNotFoundException;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\nimport java.util.Random;\r\nimport javafx.animation.KeyFrame;\r\nimport javafx.animation.KeyValue;\r\nimport javafx.animation.Timeline;\r\nimport javafx.application.Application;\r\nimport javafx.event.ActionEvent;\r\nimport javafx.event.EventHandler;\r\nimport javafx.scene.Scene;\r\nimport javafx.scene.canvas.Canvas;\r\nimport javafx.scene.canvas.GraphicsContext;\r\nimport javafx.scene.image.Image;\r\nimport javafx.scene.image.ImageView;\r\nimport javafx.scene.layout.AnchorPane;\r\nimport javafx.scene.layout.StackPane;\r\nimport javafx.stage.Stage;\r\nimport javafx.util.Duration;\r\n\r\n\/**\r\n *\r\n * @author andi\r\n *\/\r\npublic class OverlayLayoutTest extends Application {\r\n\r\n    private Timeline timeLine;\r\n    private List images;\r\n    private Random rnd = new Random(System.nanoTime());\r\n    \/\/private ImageView animation = null;\r\n    private AnchorPane animationPane = null;\r\n\r\n    @Override\r\n    public void start(Stage stage) throws FileNotFoundException {\r\n        final StackPane root = new StackPane();\r\n        File f = new File(\"\/home\/andi\/Pictures\/Adam.jpg\");\r\n        Image image = new Image(new FileInputStream(f));\r\n        final double width = image.getWidth();\r\n        final double height = image.getHeight();\r\n        Canvas background = new Canvas(width, height);\r\n        GraphicsContext context = background.getGraphicsContext2D();\r\n        context.drawImage(image, 0, 0);\r\n\r\n        root.getChildren().add(background);\r\n\r\n        images = new ArrayList&lt;&gt;();\r\n        images.add(new Image(new FileInputStream(new File(\"\/home\/andi\/Pictures\/kajak1.png\"))));\r\n        images.add(new Image(new FileInputStream(new File(\"\/home\/andi\/Pictures\/kajak2.png\"))));\r\n        images.add(new Image(new FileInputStream(new File(\"\/home\/andi\/Pictures\/kajak3.png\"))));\r\n        images.add(new Image(new FileInputStream(new File(\"\/home\/andi\/Pictures\/kajak4.png\"))));\r\n        images.add(new Image(new FileInputStream(new File(\"\/home\/andi\/Pictures\/kajak5.png\"))));\r\n\r\n        final int xRange = (int) (width - images.get(0).getWidth());\r\n        final int yRange = (int) (height - images.get(0).getHeight());\r\n\r\n       \/\/ final Canvas animation = new Canvas(width, height);\r\n        \/\/final GraphicsContext context2 = animation.getGraphicsContext2D();\r\n\r\n        timeLine = new Timeline();\r\n        timeLine.setCycleCount(Timeline.INDEFINITE);\r\n        timeLine.getKeyFrames().add(\r\n                new KeyFrame(Duration.millis(500), \r\n                    new EventHandler() {\r\n\r\n                        @Override\r\n                        public void handle(ActionEvent t) {\r\n                            final int nextIndex = rnd.nextInt(images.size());\r\n                            Image kajak = images.get(nextIndex);\r\n                            final AnchorPane previous = animationPane;\r\n                            ImageView animation = new ImageView(kajak);\r\n                            System.out.println(\"Draw image with index \"+nextIndex);\r\n                            int rndX = rnd.nextInt(xRange);\r\n                            int rndY = rnd.nextInt(yRange);\r\n                            animationPane = new AnchorPane();\r\n                            AnchorPane.setTopAnchor(animation, (double) rndY);\r\n                            AnchorPane.setLeftAnchor(animation, (double) rndX);\r\n                            AnchorPane.setBottomAnchor(animation, 0.0);\r\n                            AnchorPane.setRightAnchor(animation, 0.0);\r\n                            animationPane.getChildren().add(animation);\r\n                            root.getChildren().remove(previous);\r\n                            root.getChildren().add(animationPane);\r\n                        }\r\n                    }, \r\n                    new KeyValue[0]) \/\/ don't use binding\r\n        );\r\n        timeLine.playFromStart();\r\n\r\n        Scene scene = new Scene(root, width, height);\r\n\r\n        stage.setTitle(\"Moving ImageView Overlay Test\");\r\n        stage.setScene(scene);\r\n        stage.show();\r\n    }\r\n\r\n    \/**\r\n     * The main() method is ignored in correctly deployed JavaFX application.\r\n     * main() serves only as fallback in case the application can not be\r\n     * launched through deployment artifacts, e.g., in IDEs with limited FX\r\n     * support. NetBeans ignores main().\r\n     *\r\n     * @param args the command line arguments\r\n     *\/\r\n    public static void main(String[] args) {\r\n        launch(args);\r\n    }\r\n}<\/pre>\n<p>In the end each node in the overlay will be such an AnchorPane in a second stack layout on the root stack. I will do it so complicatedly so it is easier to use. I want to be able to add animations and nodes to the overlay (back to front). When creating a custom Layout using these existing layouts, I will be able to provide simple setter methods.<\/p>\n<p>An extension of the anchor pane will then be an animated pane. Imagine a walk cycle of o figure. Each image in the animation has a different location, while the difference in the location stays constant. This will hold for all animations, so I only have to pass the direction of the walk.<\/p>\n<p>The animation is added to all four available anchor points. This should result in proper scaling. This will be the next issue:<\/p>\n<ul>\n<li>Scaling of a box<\/li>\n<li>Scaling of an image<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Aim of this post is to show how multiple animations or other nodes can be placed side by side in an efficient way on a single layer on the stack<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7,6],"tags":[301,252,110,189],"class_list":["post-2263","post","type-post","status-publish","format-standard","hentry","category-java","category-programmieren","tag-java","tag-javafx","tag-layout","tag-openpatrician"],"_links":{"self":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/comments?post=2263"}],"version-history":[{"count":1,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2263\/revisions"}],"predecessor-version":[{"id":2264,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2263\/revisions\/2264"}],"wp:attachment":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/media?parent=2263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/categories?post=2263"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/tags?post=2263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}