3

I have this following example, where I want to pass my paremeter "text" together with my event (when my button "bla" is clicked). How can I do it?

  EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            System.out.println(text);
        }
    };

    public void test(){
    //...

    Text text = "123567";

    bla.setOnMousePressed(handler);

    //...
    }

Small question:

When I do have the following:

   object1.setOnMouseClicked( event -> {
        System.out.println("HELLO");
    });

   object2.setOnMouseClicked( event -> {
        System.out.println("HELLO");
    });

two objects, doing the same thing when "setOnMouseClicked" on them. is there any syntax to merge them?

user3650191
  • 351
  • 2
  • 5
  • 17

2 Answers2

7

There is multiple ways you can go at it. If the parameter you want to pass along is part of the event source or target you can:

  • use getSource or getTarget
  • check the class of source or target
  • cast the source/target to that class
  • access parameters via the getters and setters of that class

However if the parameter has nothing to do with the event, you will have to write a custom event:

class CustomEvent extends Event {

    private String parameter;

    public static final EventType<CustomEvent> CUSTOM = new EventType(ANY, "CUSTOM");
    public CustomEvent(String parameter) {
        super(CustomEvent.CUSTOM);
        this.parameter = parameter;
    }

    public String getParameter() {
        return this.parameter;
    }

}

Now to use that event you will first have to fire it.

You can do this with

objectThatWillFireThisEvent.fireEvent(new CustomEvent("Get this parameter guys!"));

So you now fired an event with a parameter. Now to set the EventHandler simple add this to the class of the object that will fire the event:

public final void setOnCustomEvent(
        EventHandler<? super CustomEvent> value) {
    this.addEventHandler(CustomEvent.CUSTOM, value);
}

Now you can set the event handler:

objectThatWillFireTheEvent.setOnCustomEvent( event -> {
    System.out.println(event.getParameter());
});

Alternatively if want you can use the way to write event handlers that you posted in your question (if you don't want to use lambdas).

Or you can just call a function that you wrote, that should handle that parameter:

objectThatWillFireTheEvent.setOnCustomEvent( event -> myFunction(event.getParameter) );

I hope I didn't make any typos. But if something does not work or you have any more questions, don't hesitate to ask! :)

In addition to that I would advice you to google casting (if you do not know that already) and more on custom events (since my answer is only a starting point and if you want to do more crazy shit with custom events it's better to read up on that :D)

Edit: Is this what you meant in your comment?

Since comments will destroy layout and readability

String text = "This is text!";
Button button = new Button();
object.setOnMouseClicked( event -> {
    function1(text);
    function2(button);
});
Clement Cherlin
  • 387
  • 6
  • 13
JohnRW
  • 748
  • 7
  • 22
  • Here you can find an answer with casting: http://stackoverflow.com/questions/23928132/javafx-eventhandler-pass-parameter – JohnRW Feb 12 '16 at 23:32
  • If you wanted to avoid custom events at all costs, you COULD extend the class that fires your event with a custom parameter, setter and getter and use the event source / target method to get it again. However I would strongly advice against this, since parameters that are in concept not connected to a class should not be added to a class in implementation ;) – JohnRW Feb 12 '16 at 23:34
  • thank you - another small question: when I do have two elements, let's say "text" and "button" - and I want to bind them the both function when "setOnMouseClick" is done... is there any syntax I can use instead of writing text.setOnMouseClicked(new EventHandler() {....} + button.setOnMouseClicked(new EventHandler() {...} - is there any easy way like saying text&button.setOnMouseClicked.... - because then I would not need the stuff above - I could say it shall do the same stuff for both elements, when onmouse.. is fired – user3650191 Feb 12 '16 at 23:48
  • Edited my answer, because code gets crazy in comments :) – JohnRW Feb 12 '16 at 23:54
  • 1
    No you have to set the event handler for both objects, however you can use the same method to handle those events with a lambda ( event -> methodx() ) – JohnRW Feb 13 '16 at 00:01
0

If you're using setOnMousePressed() method, you can access the variable text directly using lambda expression:

bla.setOnMousePressed(event -> {
    System.out.println(text);
});

But if you're going to use the EventHandler interface anyway or if you're going to use bla.addEventHandler(); here's a better way to do it:

You see the idea is to create a Custom EventHandler through which we pass all the data we need as parameters i.e. text in our case.

To create a Custom EventHandler, create an abstract class that implements the EventHandler interface.

public abstract class CustomEventHandler implements EventHandler<Event>
{
    private String text;

    public CustomEventHandler(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

Now you can pass the variable text through the constructor:

Button bla = new Button("bla");

String text = "123567";

bla.setOnMousePressed(new CustomEventHandler(text) {

    @Override
    public void handle(Event event) {
        System.out.println(getText());
    }
});

Output when the bla button is pressed:

123567

I hope this answers your question.
Please ask away anything if you don't understand! :)