0

I define a event and I would like to notify all component which has define listener in project . The following is event code snippet;



/**
 * 消息事件
 */
public class ChatEvent extends Event {
    public static final EventType<ChatEvent> CHAT_ANY = new EventType<>(Event.ANY, "CHAT");


    public static final EventType<ChatEvent> RECEIVE_CHAT = new EventType<>(CHAT_ANY, "CHAT_RECEIVE");


    private final Chat.ChatMessage chatMessage ;


    public ChatEvent(  EventType<? extends Event> eventType, Chat.ChatMessage chatMessage ) {
        super(eventType);
        this.chatMessage = chatMessage ;
    }

    @Override
    public Object getSource() {
        return chatMessage;
    }


    public Chat.ChatMessage getChatMessage(){
        return chatMessage;
    }


    public ChatEvent(Object source, EventTarget target, EventType<? extends Event> eventType,Chat.ChatMessage chatMessage) {
        super(source, target, eventType);
        this.chatMessage = chatMessage;
    }
}
> Event definition 

Conponent eventHandler

receiveMessage.addEventHandler(ChatEvent.RECEIVE_CHAT , (chat)-> {
            log.info("client receive message");
            Chat.ChatMessage chatMessage = chat.getChatMessage();
            MessagePane msgPane = new MessagePane(chatMessage);
            vBox.getChildren().add(msgPane);
            receiveMessage.setText(chatMessage.getContent());
        });

Above is all about event , and the I use the below method to fire event .

   
        Runnable fireEvent = () -> EventUtil.fireEvent( receiveMessage,chatEvent );
        if (!Platform.isFxApplicationThread()){
            Platform.runLater(fireEvent);
        }
        else {
            fireEvent.run();
        }

Above code snippet EventUtil.fireEvent just only fire the specify component , it is not desired .

Major question

Is there some method could notify all component which has define eventHander ?

kleopatra
  • 51,061
  • 28
  • 99
  • 211
Peng
  • 653
  • 8
  • 5
    There's not an easy way to do this. Only thing I can think of is to get all the leaf nodes of the scene graph, then fire the event at each of them (though that runs the risk of notifying a node multiple times due to how the capturing/bubbling of events work). But a UI event is really the wrong way to do this. You should have a model, and that model should be observable. Then share that model instance with every UI component that needs it. That way the model serves as the single source of truth, and UI code can add listeners as needed. – Slaw Jun 04 '23 at 09:50
  • @Slaw , Thanks, I got it . There should be a context which is single instance and make sure that event in context would be notify at most or at least once . Every event node should be register in this context and confirm its visible that could control event more compact. – Peng Jun 04 '23 at 13:26
  • 1
    Well, yes... but no. Again, using a UI event for this is conceptually wrong. And by "UI event", I mean an event that inherits from `javafx.event.Event`. You should have a model independent of the UI. Make that model observable. Share the model as needed. Observe the model and update the UI accordingly. I recommend researching architectures like Model-View-Controller (MVC), Model-View-ViewModel (MVVM), and so on. – Slaw Jun 04 '23 at 20:45
  • okay, Is there some related article for reference? – Peng Jun 05 '23 at 01:00
  • I agree that JavaFX events are probably the wrong thing for what you are trying to do. On the other hand, advising on a “right” alternative is difficult and out of scope for StackOverflow. – jewelsea Jun 05 '23 at 01:25
  • Some things to consider: an [event bus](https://github.com/google/guava/wiki/EventBusExplained), but even Google who wrote it don’t recommend it and recommend [RXJava](https://github.com/ReactiveX/RxJava) instead (not something I have experience with). May be simpler and sufficient to stick with JavaFX properties, listeners and binding using [mvc](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx). If it is network based messaging subscriptions for chat, that is often implemented with websockets or JMX or Stomp or a custom chat protocol. – jewelsea Jun 05 '23 at 01:34
  • @jewelsea In this project , I use reactor-netty as network framework and protobuf as transport protocol . you reminded of me ,It may be better way to solve mine scenario that based on reactive programming (Reactor) framework and bind the event with reactive model. – Peng Jun 05 '23 at 05:28

0 Answers0