質問

I've looked everywhere online and have been stumped for a few hours now. I have a program where I have an array of 40 imageViews on a screen. What I want to happen is when I click on a particular imageView in the array, I want the image to change within the imageView.

Here is what I have:

public void initBubbles(){
    Image image = new Image("file:src/bubbles/images/bubble.png");
    for (int i = 0; i < bubbles.length; i++) {
        //Creates a new bubble
        bubbles[i] = new Bubble(image, 'A', 1);

        //Creates a new image view
        ivs[i] = new ImageView(image);

       //Various lines of codes that put the imageView in the scene..... (Not relevant)


      ivs[i].addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent> () {

            @Override
            public void handle(MouseEvent event) {
                System.out.println("Bubble Popped!");
                ivs[i].setImage(new Image("popped.png":); //Will result in arrayOutOfBounds
            }
        });

    }

}

The problem I am running into is getting the selected element from the MouseEvent. I understand that the line right after the "Bubble Popped!" message will cause an ArrayOutOfBounds exception. But I hope you understand what I am trying to. How can I get the imageView that was clicked based on the MouseEvent?

Any help is greatly appreciated as I've been stuck for a few hours.

役に立ちましたか?

解決

I cannot check it in compiler now but based on the documentation I guess you will refer to the correct ImageView by the getTarget() method which MouseEvent inherits from javafx.event.Event.

So the correct code would be something like this:

@Override
public void handle(MouseEvent event) {
    final ImageView iv = (ImageView) (event.getTarget());
    iv.setImage(new Image("popped.png"));
}

And if you really wish to have a single EventHandler for entire array, you should define it outside of the for loop and assign it to a variable - otherwise you are creating a new instance of the handler for each ImageView.

public void initBubbles(){
    final Image image = new Image("file:src/bubbles/images/bubble.png");
    // Create an event handler to be re-used for all the ImageView's
    final EventHandler eventHandler = new EventHandler<MouseEvent> () {
        @Override
        public void handle(MouseEvent event) {
            final ImageView iv = (ImageView) (event.getTarget());
            iv.setImage(new Image("popped.png"));
        }
    }
    for (int i = 0; i < bubbles.length; i++) {
        //Creates a new bubble
        bubbles[i] = new Bubble(image, 'A', 1);
        //Creates a new image view
        ivs[i] = new ImageView(image);
        // Register the event handler
        ivs[i].addEventHandler(MouseEvent.MOUSE_CLICKED, eventHandler);
    }
}

The handler code runs in different context than where you register the handler (addEventHandler()), so the value of i does not have the same meaning. You should consider the code of the handle() method as completely separate and independent on its surrounding code. The information of the "run-time context" of the handler is in the event which triggered the handler.

To use a parable, by calling the addEventHandler() you tell the ImageView this:

Dear ImageView, when a mouse event occurs above you, call the code of the handler.

And the handler:

Dear handler, when you are triggered, have a look at the target upon which you have been called, consider it as an instance of ImageView and set its image to something new.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top