Add EventHandler to ImageView contained in TilePane contained in VBox?

37,600

Solution 1

ImageViews don't generate ActionEvents; so it is no surprise that your event handler is never invoked. Since the mouse event is not processed by the ImageView, it propagates up to the container.

Try

img.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {

     @Override
     public void handle(MouseEvent event) {
         System.out.println("Tile pressed ");
         event.consume();
     }
});

Solution 2

@James_D is correct; but note for Java 8 you can use the simpler syntax:

img.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
         System.out.println("Tile pressed ");
         event.consume();
     });

Solution 3

Note that MouseEvent.MOUSE_CLICKED is a class from javafx, not from java.awt.event package

imgView. addEventHandler(javafx.scene.input.MouseEvent.MOUSE_CLICKED, event -> {
    //event clicked here
});

For someone who mistakenly import java.awt.event.MouseEvent class

Share:
37,600
bog
Author by

bog

Updated on May 15, 2020

Comments

  • bog
    bog about 4 years

    I have the following schema:

    • A VBox, containing a HBox and a TilePane.

    In HBox are buttons, labels, and text fields.

    Every time I click on the root (HBox), I should add a ImageView to the tile pane. This ImageView shold contain an image (example: "2.jpg"). Maximum of tile pane components is 5.

    Every time I click the image, i should load a new image to the clicked ImageView, exemple "1.jpg". It is not working. When I click on my image it is like i'm clicking on the root so it creates another cell of TilePane. Here's the code, can you help me?

    /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package dadao1;
    
    import java.util.HashSet;
    import javafx.application.Application;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.TextField;
    import javafx.scene.image.ImageView;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.StackPane;
    import javafx.scene.layout.TilePane;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
    /**
     *
     * @author Ambra
     */
    public class Dadao1 extends Application {
        VBox root;
        HashSet dadi = new HashSet();
        //static int numeroDadi = 0;
        @Override
        public void start(Stage primaryStage) {       
    
            setGui();
            Scene scene = new Scene(root, 300, 300);
    
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        } 
        /**
         *This private method sets up the GUI.
         * No parameters are required
         */
        private void setGui(){
            root = new VBox();
            HBox buttons = new HBox();
            final Button newGame = new Button("New Game");
            final Button print = new Button("Print");
            final Button animation = new Button("Moving");
            animation.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
                // this button is labeled "Moving" at the begin. If pressed it changes its label to "Dissolving" and viceversa.
                @Override
                public void handle(ActionEvent event) {
                    if (animation.getText().equals(new String("Moving")))
                        animation.setText("Dissolving");
                    else animation.setText("Mooving");
                }
            });
            final Label score = new Label("Total");
            final TextField points = new TextField();
            final Label pointsLabel = new Label("Score");
            root.setStyle("-fx-background-color: green");
    
            buttons.getChildren().addAll(newGame,print,animation,score,points,pointsLabel);
            final TilePane dadiPane = new TilePane();
            dadiPane.setVgap(10);
            dadiPane.setHgap(10);
            root.getChildren().addAll(buttons, dadiPane);
    
            root.setOnMouseClicked(new EventHandler<MouseEvent>() {
    
                @Override
                public void handle(MouseEvent event) {
                    if(dadi.size()<5){
                        System.out.println("Adding img");
                        final ImageView img = new ImageView("2.jpg");
                        // should I put final in front of ImageView?
                        img.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
    
                            @Override
                            public void handle(ActionEvent event) {
                                // I want that when a tile is pressed an event occours.
                                // that event should be "add a new image to the ImageView just clicked",
                                // for example: img is not "2.jpg" but "3.jpj", by the way, I'm not able neither 
                                // to to print the folowing messagge :(
                                // It's like my root is pressed even if my mouse ha clicked at the image in img var.
                                System.out.println("Tile pressed ");
                            }
                        });
                        dadi.add(img);
                        dadiPane.getChildren().add(img);
                    }else System.out.println("You cannot create more than 5 dices");
                }
            });
        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
    }