3

I am trying to make a custom event and listener in Java. I already looked at these articles and questions:

Create a custom event in Java

Java custom event handler and listeners

https://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html

But I still can't really wrap my head around it. This is what I want done:

I have a String object whose content changes as the program runs. I want to be able to add a listener to the string which listens wether it contains a specific string and when it does run a piece of code. I want to use it like this:

String string = "";
//String.addListener() and textListener need to be created
string.addListener(new textListener("hello world") {
    @Override
    public void onMatch(
         System.out.println("Hello world detected");
    )
}

//do a bunch of stuff

string = "The text Hello World is used by programmers a lot"; //the string contains "Hello World", so the listener will now print out "Hello world detected"

I know there might be easier ways of doing this, but I would like to know how to do it this way.

Thank you @Marcos Vasconcelos for pointing out that you cannot add methods to a String object, so is there a way I can use a custom class like @Ben pointed out?

Conner Dassen
  • 729
  • 4
  • 11
  • 28
  • You cannot add methods to String, you can add to the class you use it – Marcos Vasconcelos Mar 19 '18 at 14:29
  • You could do this with Kotlin and its extensions. A wrapper class and a Java 101 tutorial on events should do it in Java. – duffymo Mar 19 '18 at 14:31
  • You can create your own class `EventString` (or something else), have a String object in there and then implement a custom Event Listener for it. – Ben Mar 19 '18 at 14:31
  • @Ben And how do I implement a custom Event Listener? As I said I still don't really understand it after reading mutliple questions and articles – Conner Dassen Mar 19 '18 at 14:34
  • Basically, event listeners are not magic. In order for listeners to work, you need to program a mechanism that triggers the events when changes happen. That is, you can't allow the program to directly assign to the string - you have to do it through that mechanism. – RealSkeptic Mar 19 '18 at 14:37
  • It's a simple two fold process. You need some interface `MyEventListener` with a method `onMyEvent`. Then you have a `addMyEventListener(MyEventListener)` in your `EventString` class that holds references to the listeners. And when whatever you want to happen happens (e.g. in your `setValue` method the value `hello world` is the parameter) you call the `onMyEvent` method for your listeners. – Ben Mar 19 '18 at 14:37
  • But that's perfectly explained in the posts you linked so no reason to repeat all of that here. – Ben Mar 19 '18 at 14:37

1 Answers1

7

So I made a minimal example maybe that will help you:

You need an interface for your listener:

public interface MyEventListener
{
    public void onMyEvent();
}

Then for your String you need some wrapper class that also handles your events

public class EventString
{
    private String                  myString;

    private List<MyEventListener>   eventListeners;

    public EventString(String myString)
    {
        this.myString = myString;
        this.eventListeners = new ArrayList<MyEventListener>();
    }

    public void addMyEventListener(MyEventListener evtListener)
    {
        this.eventListeners.add(evtListener);
    }

    public void setValue(String val)
    {
        myString = val;

        if (val.equals("hello world"))
        {
            eventListeners.forEach((el) -> el.onMyEvent());
        }
    }
}

You see that the myString field is private and only accessible using the setValue method. This is so we can see when our event condition triggers.

And then you only need some implementation of this, such as:

EventString temp = new EventString("test");

temp.addMyEventListener(() -> {
    System.out.println("hello world detected");
});

temp.setValue("hello world");
Ben
  • 1,665
  • 1
  • 11
  • 22
  • is there a way to not check whenever you call `setValue` but to check continuously? Maybe with a while loop? – Conner Dassen Mar 19 '18 at 16:46
  • You can trigger the event whenever you want. Just use the `eventListeners.forEach((el) -> el.onMyEvent());` line. – Ben Mar 19 '18 at 16:48