{"id":2261,"date":"2012-12-16T12:06:59","date_gmt":"2012-12-16T11:06:59","guid":{"rendered":"http:\/\/sahits.ch\/blog\/?p=2261"},"modified":"2012-12-16T12:06:59","modified_gmt":"2012-12-16T11:06:59","slug":"javafx-overlay-with-imageview","status":"publish","type":"post","link":"http:\/\/sahits.ch\/blog\/blog\/2012\/12\/16\/javafx-overlay-with-imageview\/","title":{"rendered":"JavaFX overlay with ImageView"},"content":{"rendered":"<p>Replacing the Canvas with an ImageView from my <a href=\"http:\/\/sahits.ch\/blog\/?p=2257\">previous post<\/a> was easy.<\/p>\n<p><!--more--><\/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.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 MovingImageViewOverlayTest extends Application {\r\n\r\n    private Timeline timeLine;\r\n    private List&lt;Image&gt; images;\r\n    private Random rnd = new Random(System.nanoTime());\r\n    private ImageView animation = 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&lt;ActionEvent&gt;() {\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 ImageView previous = animation;\r\n                            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                            animation.setLayoutX(rndX);\r\n                            animation.setLayoutY(rndY);\r\n                            root.getChildren().remove(previous);\r\n                            root.getChildren().add(animation);\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>The only thing to point out is that the event handler creates a new ImageView each time. Besides the fact that this can be optimized, it is important that the new image view replaces the old one.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Replacing the Canvas with an ImageView from my previous post was easy.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[138],"tags":[],"class_list":["post-2261","post","type-post","status-publish","format-standard","hentry","category-it"],"_links":{"self":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2261","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=2261"}],"version-history":[{"count":1,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2261\/revisions"}],"predecessor-version":[{"id":2262,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/posts\/2261\/revisions\/2262"}],"wp:attachment":[{"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/media?parent=2261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/categories?post=2261"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/sahits.ch\/blog\/wp-json\/wp\/v2\/tags?post=2261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}