Replace the Internal Event Bus with Event Bus 0.0.3 #20
@@ -10,16 +10,7 @@ import envoy.event.Event;
 | 
				
			|||||||
 * @author Kai S. K. Engelbart
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 * @since Envoy Client v0.2-alpha
 | 
					 * @since Envoy Client v0.2-alpha
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class ThemeChangeEvent extends Event<String> {
 | 
					public final class ThemeChangeEvent extends Event.Valueless {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final long serialVersionUID = 0L;
 | 
						private static final long serialVersionUID = 0L;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Initializes a {@link ThemeChangeEvent} conveying information about the change
 | 
					 | 
				
			||||||
	 * of the theme currently in use.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * @param theme the name of the new theme
 | 
					 | 
				
			||||||
	 * @since Envoy Client v0.2-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public ThemeChangeEvent(String theme) { super(theme); }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,20 +1,19 @@
 | 
				
			|||||||
package envoy.client.net;
 | 
					package envoy.client.net;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.Closeable;
 | 
					import java.io.*;
 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.net.Socket;
 | 
					import java.net.Socket;
 | 
				
			||||||
import java.util.concurrent.TimeoutException;
 | 
					import java.util.concurrent.TimeoutException;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.*;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.*;
 | 
					import envoy.client.data.*;
 | 
				
			||||||
import envoy.client.event.SendEvent;
 | 
					import envoy.client.event.SendEvent;
 | 
				
			||||||
import envoy.data.*;
 | 
					import envoy.data.*;
 | 
				
			||||||
import envoy.event.*;
 | 
					import envoy.event.*;
 | 
				
			||||||
import envoy.event.contact.ContactOperation;
 | 
					import envoy.event.Event;
 | 
				
			||||||
import envoy.event.contact.UserSearchResult;
 | 
					import envoy.event.contact.*;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.*;
 | 
				
			||||||
import envoy.util.SerializationUtils;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Establishes a connection to the server, performs a handshake and delivers
 | 
					 * Establishes a connection to the server, performs a handshake and delivers
 | 
				
			||||||
@@ -29,7 +28,7 @@ import envoy.util.SerializationUtils;
 | 
				
			|||||||
 * @author Leon Hofmeister
 | 
					 * @author Leon Hofmeister
 | 
				
			||||||
 * @since Envoy Client v0.1-alpha
 | 
					 * @since Envoy Client v0.1-alpha
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class Client implements Closeable {
 | 
					public final class Client implements EventListener, Closeable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Connection handling
 | 
						// Connection handling
 | 
				
			||||||
	private Socket		socket;
 | 
						private Socket		socket;
 | 
				
			||||||
@@ -45,6 +44,15 @@ public final class Client implements Closeable {
 | 
				
			|||||||
	private static final Logger			logger		= EnvoyLog.getLogger(Client.class);
 | 
						private static final Logger			logger		= EnvoyLog.getLogger(Client.class);
 | 
				
			||||||
	private static final EventBus		eventBus	= EventBus.getInstance();
 | 
						private static final EventBus		eventBus	= EventBus.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Constructs a client and registers it as an event listener.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public Client() {
 | 
				
			||||||
 | 
							eventBus.registerListener(this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Enters the online mode by acquiring a user ID from the server. As a
 | 
						 * Enters the online mode by acquiring a user ID from the server. As a
 | 
				
			||||||
	 * connection has to be established and a handshake has to be made, this method
 | 
						 * connection has to be established and a handshake has to be made, this method
 | 
				
			||||||
@@ -164,22 +172,14 @@ public final class Client implements Closeable {
 | 
				
			|||||||
		// Process ProfilePicChanges
 | 
							// Process ProfilePicChanges
 | 
				
			||||||
		receiver.registerProcessor(ProfilePicChange.class, eventBus::dispatch);
 | 
							receiver.registerProcessor(ProfilePicChange.class, eventBus::dispatch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Process requests to not send any more attachments as they will not be shown to
 | 
							// Process requests to not send any more attachments as they will not be shown
 | 
				
			||||||
 | 
							// to
 | 
				
			||||||
		// other users
 | 
							// other users
 | 
				
			||||||
		receiver.registerProcessor(NoAttachments.class, eventBus::dispatch);
 | 
							receiver.registerProcessor(NoAttachments.class, eventBus::dispatch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Process group creation results - they might have been disabled on the server
 | 
							// Process group creation results - they might have been disabled on the server
 | 
				
			||||||
		receiver.registerProcessor(GroupCreationResult.class, eventBus::dispatch);
 | 
							receiver.registerProcessor(GroupCreationResult.class, eventBus::dispatch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Send event
 | 
					 | 
				
			||||||
		eventBus.register(SendEvent.class, evt -> {
 | 
					 | 
				
			||||||
			try {
 | 
					 | 
				
			||||||
				sendEvent(evt.get());
 | 
					 | 
				
			||||||
			} catch (final IOException e) {
 | 
					 | 
				
			||||||
				logger.log(Level.WARNING, "An error occurred when trying to send " + evt, e);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Request a generator if none is present or the existing one is consumed
 | 
							// Request a generator if none is present or the existing one is consumed
 | 
				
			||||||
		if (!localDB.hasIDGenerator() || !localDB.getIDGenerator().hasNext()) requestIdGenerator();
 | 
							if (!localDB.hasIDGenerator() || !localDB.getIDGenerator().hasNext()) requestIdGenerator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -219,6 +219,21 @@ public final class Client implements Closeable {
 | 
				
			|||||||
		writeObject(new IDGeneratorRequest());
 | 
							writeObject(new IDGeneratorRequest());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Sends the value of a send event to the server.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param evt the send event to extract the value from
 | 
				
			||||||
 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						@dev.kske.eventbus.Event
 | 
				
			||||||
 | 
						private void onSendEvent(SendEvent evt) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								sendEvent(evt.get());
 | 
				
			||||||
 | 
							} catch (final IOException e) {
 | 
				
			||||||
 | 
								logger.log(Level.WARNING, "An error occurred when trying to send " + evt, e);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void close() throws IOException { if (online) socket.close(); }
 | 
						public void close() throws IOException { if (online) socket.close(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,11 @@ import java.util.function.Consumer;
 | 
				
			|||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.event.GroupMessageStatusChange;
 | 
					import envoy.event.GroupMessageStatusChange;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 * File: <strong>GroupMessageStatusChangePocessor.java</strong><br>
 | 
					 * File: <strong>GroupMessageStatusChangePocessor.java</strong><br>
 | 
				
			||||||
@@ -25,5 +26,4 @@ public final class GroupMessageStatusChangeProcessor implements Consumer<GroupMe
 | 
				
			|||||||
		if (evt.get().ordinal() < MessageStatus.RECEIVED.ordinal()) logger.warning("Received invalid group message status change " + evt);
 | 
							if (evt.get().ordinal() < MessageStatus.RECEIVED.ordinal()) logger.warning("Received invalid group message status change " + evt);
 | 
				
			||||||
		else EventBus.getInstance().dispatch(evt);
 | 
							else EventBus.getInstance().dispatch(evt);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,11 @@ import java.util.function.Consumer;
 | 
				
			|||||||
import java.util.logging.Logger;
 | 
					import java.util.logging.Logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.event.MessageStatusChange;
 | 
					import envoy.event.MessageStatusChange;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 * File: <strong>MessageStatusChangeProcessor.java</strong><br>
 | 
					 * File: <strong>MessageStatusChangeProcessor.java</strong><br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,10 @@ import java.util.logging.Logger;
 | 
				
			|||||||
import envoy.client.event.MessageCreationEvent;
 | 
					import envoy.client.event.MessageCreationEvent;
 | 
				
			||||||
import envoy.data.GroupMessage;
 | 
					import envoy.data.GroupMessage;
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 * File: <strong>ReceivedGroupMessageProcessor.java</strong><br>
 | 
					 * File: <strong>ReceivedGroupMessageProcessor.java</strong><br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,8 @@ import java.util.function.Consumer;
 | 
				
			|||||||
import envoy.client.event.MessageCreationEvent;
 | 
					import envoy.client.event.MessageCreationEvent;
 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
import envoy.data.Message.MessageStatus;
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,15 +6,15 @@ import java.util.logging.Level;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import javafx.application.Platform;
 | 
					import javafx.application.Platform;
 | 
				
			||||||
import javafx.fxml.FXMLLoader;
 | 
					import javafx.fxml.FXMLLoader;
 | 
				
			||||||
import javafx.scene.Parent;
 | 
					import javafx.scene.*;
 | 
				
			||||||
import javafx.scene.Scene;
 | 
					 | 
				
			||||||
import javafx.stage.Stage;
 | 
					import javafx.stage.Stage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.Settings;
 | 
					import envoy.client.data.Settings;
 | 
				
			||||||
import envoy.client.event.ThemeChangeEvent;
 | 
					import envoy.client.event.ThemeChangeEvent;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Manages a stack of scenes. The most recently added scene is displayed inside
 | 
					 * Manages a stack of scenes. The most recently added scene is displayed inside
 | 
				
			||||||
 * a stage. When a scene is removed from the stack, its predecessor is
 | 
					 * a stage. When a scene is removed from the stack, its predecessor is
 | 
				
			||||||
@@ -30,7 +30,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
 * @author Kai S. K. Engelbart
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class SceneContext {
 | 
					public final class SceneContext implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Contains information about different scenes and their FXML resource files.
 | 
						 * Contains information about different scenes and their FXML resource files.
 | 
				
			||||||
@@ -84,7 +84,7 @@ public final class SceneContext {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public SceneContext(Stage stage) {
 | 
						public SceneContext(Stage stage) {
 | 
				
			||||||
		this.stage = stage;
 | 
							this.stage = stage;
 | 
				
			||||||
		EventBus.getInstance().register(ThemeChangeEvent.class, theme -> applyCSS());
 | 
							EventBus.getInstance().registerListener(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -152,6 +152,9 @@ public final class SceneContext {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event(priority = 150, eventType = ThemeChangeEvent.class)
 | 
				
			||||||
 | 
						private void onThemeChange() { applyCSS(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @param <T> the type of the controller
 | 
						 * @param <T> the type of the controller
 | 
				
			||||||
	 * @return the controller used by the current scene
 | 
						 * @return the controller used by the current scene
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,9 @@ import javafx.stage.Stage;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import envoy.client.event.MessageCreationEvent;
 | 
					import envoy.client.event.MessageCreationEvent;
 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					import dev.kske.eventbus.Event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
@@ -18,7 +20,7 @@ import envoy.event.EventBus;
 | 
				
			|||||||
 * @author Kai S. K. Engelbart
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 * @since Envoy Client v0.2-alpha
 | 
					 * @since Envoy Client v0.2-alpha
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class StatusTrayIcon {
 | 
					public final class StatusTrayIcon implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * The {@link TrayIcon} provided by the System Tray API for controlling the
 | 
						 * The {@link TrayIcon} provided by the System Tray API for controlling the
 | 
				
			||||||
@@ -67,14 +69,7 @@ public final class StatusTrayIcon {
 | 
				
			|||||||
		trayIcon.addActionListener(evt -> Platform.runLater(() -> { stage.setIconified(false); stage.toFront(); stage.requestFocus(); }));
 | 
							trayIcon.addActionListener(evt -> Platform.runLater(() -> { stage.setIconified(false); stage.toFront(); stage.requestFocus(); }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Start processing message events
 | 
							// Start processing message events
 | 
				
			||||||
		EventBus.getInstance().register(MessageCreationEvent.class, evt -> {
 | 
							EventBus.getInstance().registerListener(this);
 | 
				
			||||||
			if (displayMessages) trayIcon
 | 
					 | 
				
			||||||
				.displayMessage(
 | 
					 | 
				
			||||||
						evt.get().hasAttachment() ? "New " + evt.get().getAttachment().getType().toString().toLowerCase() + " message received"
 | 
					 | 
				
			||||||
								: "New message received",
 | 
					 | 
				
			||||||
						evt.get().getText(),
 | 
					 | 
				
			||||||
						MessageType.INFO);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -94,4 +89,11 @@ public final class StatusTrayIcon {
 | 
				
			|||||||
	 * @since Envoy Client v0.2-beta
 | 
						 * @since Envoy Client v0.2-beta
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void hide() { SystemTray.getSystemTray().remove(trayIcon); }
 | 
						public void hide() { SystemTray.getSystemTray().remove(trayIcon); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onMessageCreation(MessageCreationEvent evt) {
 | 
				
			||||||
 | 
							if (displayMessages) trayIcon
 | 
				
			||||||
 | 
								.displayMessage(evt.get().hasAttachment() ? "New " + evt.get().getAttachment().getType().toString().toLowerCase() + " message received"
 | 
				
			||||||
 | 
										: "New message received", evt.get().getText(), MessageType.INFO);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
package envoy.client.ui.controller;
 | 
					package envoy.client.ui.controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static envoy.data.Message.MessageStatus.RECEIVED;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.awt.Toolkit;
 | 
					import java.awt.Toolkit;
 | 
				
			||||||
import java.awt.datatransfer.StringSelection;
 | 
					import java.awt.datatransfer.StringSelection;
 | 
				
			||||||
import java.io.*;
 | 
					import java.io.*;
 | 
				
			||||||
@@ -36,11 +34,15 @@ import envoy.client.ui.listcell.*;
 | 
				
			|||||||
import envoy.client.util.ReflectionUtil;
 | 
					import envoy.client.util.ReflectionUtil;
 | 
				
			||||||
import envoy.data.*;
 | 
					import envoy.data.*;
 | 
				
			||||||
import envoy.data.Attachment.AttachmentType;
 | 
					import envoy.data.Attachment.AttachmentType;
 | 
				
			||||||
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.event.*;
 | 
					import envoy.event.*;
 | 
				
			||||||
import envoy.event.contact.ContactOperation;
 | 
					import envoy.event.contact.ContactOperation;
 | 
				
			||||||
import envoy.exception.EnvoyException;
 | 
					import envoy.exception.EnvoyException;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					import dev.kske.eventbus.Event;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 * File: <strong>ChatSceneController.java</strong><br>
 | 
					 * File: <strong>ChatSceneController.java</strong><br>
 | 
				
			||||||
@@ -49,7 +51,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
 * @author Kai S. K. Engelbart
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class ChatScene implements Restorable {
 | 
					public final class ChatScene implements EventListener, Restorable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private GridPane scene;
 | 
						private GridPane scene;
 | 
				
			||||||
@@ -160,6 +162,8 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private void initialize() {
 | 
						private void initialize() {
 | 
				
			||||||
 | 
							eventBus.registerListener(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Initialize message and user rendering
 | 
							// Initialize message and user rendering
 | 
				
			||||||
		messageList.setCellFactory(MessageListCell::new);
 | 
							messageList.setCellFactory(MessageListCell::new);
 | 
				
			||||||
		chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
 | 
							chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
 | 
				
			||||||
@@ -201,110 +205,119 @@ public final class ChatScene implements Restorable {
 | 
				
			|||||||
				updateInfoLabel("You are offline", "info-label-warning");
 | 
									updateInfoLabel("You are offline", "info-label-warning");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Listen to backEvents
 | 
						@Event(eventType = BackEvent.class)
 | 
				
			||||||
		eventBus.register(BackEvent.class, e -> tabPane.getSelectionModel().select(Tabs.CONTACT_LIST.ordinal()));
 | 
						private void onBackEvent() { tabPane.getSelectionModel().select(Tabs.CONTACT_LIST.ordinal()); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Listen to received messages
 | 
						@Event
 | 
				
			||||||
		eventBus.register(MessageCreationEvent.class, e -> {
 | 
						private void onMessageCreation(MessageCreationEvent evt) {
 | 
				
			||||||
			final var message = e.get();
 | 
							final var message = evt.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// The sender of the message is the recipient of the chat
 | 
							// The sender of the message is the recipient of the chat
 | 
				
			||||||
			// Exceptions: this user is the sender (sync) or group message (group is
 | 
							// Exceptions: this user is the sender (sync) or group message (group is
 | 
				
			||||||
			// recipient)
 | 
							// recipient)
 | 
				
			||||||
			final var recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID()
 | 
							final var recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID()
 | 
				
			||||||
					: message.getSenderID();
 | 
									: message.getSenderID();
 | 
				
			||||||
			localDB.getChat(recipientID).ifPresent(chat -> {
 | 
							localDB.getChat(recipientID).ifPresent(chat -> {
 | 
				
			||||||
				chat.insert(message);
 | 
								chat.insert(message);
 | 
				
			||||||
				if (chat.equals(currentChat)) {
 | 
								if (chat.equals(currentChat)) {
 | 
				
			||||||
					try {
 | 
									try {
 | 
				
			||||||
						currentChat.read(writeProxy);
 | 
										currentChat.read(writeProxy);
 | 
				
			||||||
					} catch (final IOException e1) {
 | 
									} catch (final IOException e1) {
 | 
				
			||||||
						logger.log(Level.WARNING, "Could not read current chat: ", e1);
 | 
										logger.log(Level.WARNING, "Could not read current chat: ", e1);
 | 
				
			||||||
					}
 | 
									}
 | 
				
			||||||
					Platform.runLater(() -> { ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); });
 | 
									Platform.runLater(() -> { ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); });
 | 
				
			||||||
					// TODO: Increment unread counter for group messages with status < RECEIVED
 | 
									// TODO: Increment unread counter for group messages with status < RECEIVED
 | 
				
			||||||
				} else if (message.getSenderID() != localDB.getUser().getID() && message.getStatus() == RECEIVED) chat.incrementUnreadAmount();
 | 
								} else
 | 
				
			||||||
 | 
									if (message.getSenderID() != localDB.getUser().getID() && message.getStatus() == MessageStatus.RECEIVED) chat.incrementUnreadAmount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Move chat with most recent unread messages to the top
 | 
								// Move chat with most recent unread messages to the top
 | 
				
			||||||
				Platform.runLater(() -> {
 | 
					 | 
				
			||||||
					chats.getSource().remove(chat);
 | 
					 | 
				
			||||||
					((ObservableList<Chat>) chats.getSource()).add(0, chat);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					if (chat.equals(currentChat)) chatList.getSelectionModel().select(0);
 | 
					 | 
				
			||||||
				});
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Listen to message status changes
 | 
					 | 
				
			||||||
		eventBus.register(MessageStatusChange.class, e -> localDB.getMessage(e.getID()).ifPresent(message -> {
 | 
					 | 
				
			||||||
			message.setStatus(e.get());
 | 
					 | 
				
			||||||
			// Update UI if in current chat and the current user was the sender of the
 | 
					 | 
				
			||||||
			// message
 | 
					 | 
				
			||||||
			if (currentChat != null && message.getSenderID() == client.getSender().getID()) Platform.runLater(messageList::refresh);
 | 
					 | 
				
			||||||
		}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		eventBus.register(GroupMessageStatusChange.class, e -> localDB.getMessage(e.getID()).ifPresent(groupMessage -> {
 | 
					 | 
				
			||||||
			((GroupMessage) groupMessage).getMemberStatuses().replace(e.getMemberID(), e.get());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// Update UI if in current chat
 | 
					 | 
				
			||||||
			if (currentChat != null && groupMessage.getRecipientID() == currentChat.getRecipient().getID()) Platform.runLater(messageList::refresh);
 | 
					 | 
				
			||||||
		}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Listen to user status changes
 | 
					 | 
				
			||||||
		eventBus.register(UserStatusChange.class,
 | 
					 | 
				
			||||||
				e -> chats.getSource()
 | 
					 | 
				
			||||||
					.stream()
 | 
					 | 
				
			||||||
					.filter(c -> c.getRecipient().getID() == e.getID())
 | 
					 | 
				
			||||||
					.findAny()
 | 
					 | 
				
			||||||
					.map(Chat::getRecipient)
 | 
					 | 
				
			||||||
					.ifPresent(u -> { ((User) u).setStatus(e.get()); Platform.runLater(() -> ListViewRefresh.deepRefresh(chatList)); }));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Listen to contacts changes
 | 
					 | 
				
			||||||
		eventBus.register(ContactOperation.class, e -> {
 | 
					 | 
				
			||||||
			final var contact = e.get();
 | 
					 | 
				
			||||||
			switch (e.getOperationType()) {
 | 
					 | 
				
			||||||
				case ADD:
 | 
					 | 
				
			||||||
					if (contact instanceof User) localDB.getUsers().put(contact.getName(), (User) contact);
 | 
					 | 
				
			||||||
					final var chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact);
 | 
					 | 
				
			||||||
					Platform.runLater(() -> ((ObservableList<Chat>) chats.getSource()).add(0, chat));
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				case REMOVE:
 | 
					 | 
				
			||||||
					Platform.runLater(() -> chats.getSource().removeIf(c -> c.getRecipient().equals(contact)));
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Disable attachment button if server says attachments will be filtered out
 | 
					 | 
				
			||||||
		eventBus.register(NoAttachments.class, e -> {
 | 
					 | 
				
			||||||
			Platform.runLater(() -> {
 | 
								Platform.runLater(() -> {
 | 
				
			||||||
				attachmentButton.setDisable(true);
 | 
									chats.getSource().remove(chat);
 | 
				
			||||||
				voiceButton.setDisable(true);
 | 
									((ObservableList<Chat>) chats.getSource()).add(0, chat);
 | 
				
			||||||
				final var alert = new Alert(AlertType.ERROR);
 | 
					
 | 
				
			||||||
				alert.setTitle("No attachments possible");
 | 
									if (chat.equals(currentChat)) chatList.getSelectionModel().select(0);
 | 
				
			||||||
				alert.setHeaderText("Your current server does not support attachments.");
 | 
					 | 
				
			||||||
				alert.setContentText("If this is unplanned, please contact your server administrator.");
 | 
					 | 
				
			||||||
				alert.showAndWait();
 | 
					 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		eventBus.register(GroupCreationResult.class, e -> Platform.runLater(() -> { newGroupButton.setDisable(!e.get()); }));
 | 
						@Event
 | 
				
			||||||
 | 
						private void onMessageStatusChange(MessageStatusChange evt) {
 | 
				
			||||||
		eventBus.register(ThemeChangeEvent.class, e -> {
 | 
							localDB.getMessage(evt.getID()).ifPresent(message -> {
 | 
				
			||||||
			settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE)));
 | 
							message.setStatus(evt.get());
 | 
				
			||||||
			voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
							// Update UI if in current chat and the current user was the sender of the
 | 
				
			||||||
			attachmentButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("attachment", DEFAULT_ICON_SIZE)));
 | 
							// message
 | 
				
			||||||
			DEFAULT_ATTACHMENT_VIEW_IMAGE = IconUtil.loadIconThemeSensitive("attachment_present", 20);
 | 
							if (currentChat != null && message.getSenderID() == client.getSender().getID()) Platform.runLater(messageList::refresh);
 | 
				
			||||||
			attachmentView.setImage(isCustomAttachmentImage ? attachmentView.getImage() : DEFAULT_ATTACHMENT_VIEW_IMAGE);
 | 
					 | 
				
			||||||
			messageSearchButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("search", DEFAULT_ICON_SIZE)));
 | 
					 | 
				
			||||||
			clientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
 | 
					 | 
				
			||||||
			chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
 | 
					 | 
				
			||||||
			messageList.setCellFactory(MessageListCell::new);
 | 
					 | 
				
			||||||
			if (currentChat.getRecipient() instanceof User) recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
 | 
					 | 
				
			||||||
			else recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43));
 | 
					 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onGroupMessageStatusChange(GroupMessageStatusChange evt) {
 | 
				
			||||||
 | 
							localDB.getMessage(evt.getID()).ifPresent(groupMessage -> {
 | 
				
			||||||
 | 
								((GroupMessage) groupMessage).getMemberStatuses().replace(evt.getMemberID(), evt.get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Update UI if in current chat
 | 
				
			||||||
 | 
							if (currentChat != null && groupMessage.getRecipientID() == currentChat.getRecipient().getID()) Platform.runLater(messageList::refresh);
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onUserStatusChange(UserStatusChange evt) {
 | 
				
			||||||
 | 
							chats.getSource()
 | 
				
			||||||
 | 
								.stream()
 | 
				
			||||||
 | 
								.filter(c -> c.getRecipient().getID() == evt.getID())
 | 
				
			||||||
 | 
								.findAny()
 | 
				
			||||||
 | 
								.map(Chat::getRecipient)
 | 
				
			||||||
 | 
								.ifPresent(u -> { ((User) u).setStatus(evt.get()); Platform.runLater(() -> ListViewRefresh.deepRefresh(chatList)); });
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onContactOperation(ContactOperation operation) {
 | 
				
			||||||
 | 
							final var contact = operation.get();
 | 
				
			||||||
 | 
							switch (operation.getOperationType()) {
 | 
				
			||||||
 | 
								case ADD:
 | 
				
			||||||
 | 
									if (contact instanceof User) localDB.getUsers().put(contact.getName(), (User) contact);
 | 
				
			||||||
 | 
									final var chat = contact instanceof User ? new Chat(contact) : new GroupChat(client.getSender(), contact);
 | 
				
			||||||
 | 
									Platform.runLater(() -> ((ObservableList<Chat>) chats.getSource()).add(0, chat));
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case REMOVE:
 | 
				
			||||||
 | 
									Platform.runLater(() -> chats.getSource().removeIf(c -> c.getRecipient().equals(contact)));
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event(eventType = NoAttachments.class)
 | 
				
			||||||
 | 
						private void onNoAttachments() {
 | 
				
			||||||
 | 
							Platform.runLater(() -> {
 | 
				
			||||||
 | 
								attachmentButton.setDisable(true);
 | 
				
			||||||
 | 
								voiceButton.setDisable(true);
 | 
				
			||||||
 | 
								final var alert = new Alert(AlertType.ERROR);
 | 
				
			||||||
 | 
								alert.setTitle("No attachments possible");
 | 
				
			||||||
 | 
								alert.setHeaderText("Your current server does not support attachments.");
 | 
				
			||||||
 | 
								alert.setContentText("If this is unplanned, please contact your server administrator.");
 | 
				
			||||||
 | 
								alert.showAndWait();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onGroupCreationResult(GroupCreationResult result) { Platform.runLater(() -> newGroupButton.setDisable(!result.get())); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event(eventType = ThemeChangeEvent.class)
 | 
				
			||||||
 | 
						private void onThemeChange() {
 | 
				
			||||||
 | 
							settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
 | 
							voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
 | 
							attachmentButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("attachment", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
 | 
							DEFAULT_ATTACHMENT_VIEW_IMAGE = IconUtil.loadIconThemeSensitive("attachment_present", 20);
 | 
				
			||||||
 | 
							attachmentView.setImage(isCustomAttachmentImage ? attachmentView.getImage() : DEFAULT_ATTACHMENT_VIEW_IMAGE);
 | 
				
			||||||
 | 
							messageSearchButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("search", DEFAULT_ICON_SIZE)));
 | 
				
			||||||
 | 
							clientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
 | 
				
			||||||
 | 
							chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
 | 
				
			||||||
 | 
							messageList.setCellFactory(MessageListCell::new);
 | 
				
			||||||
 | 
							if (currentChat.getRecipient() instanceof User) recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("user_icon", 43));
 | 
				
			||||||
 | 
							else recipientProfilePic.setImage(IconUtil.loadIconThemeSensitive("group_icon", 43));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Initializes all {@code SystemCommands} used in {@code ChatScene}.
 | 
						 * Initializes all {@code SystemCommands} used in {@code ChatScene}.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +1,21 @@
 | 
				
			|||||||
package envoy.client.ui.controller;
 | 
					package envoy.client.ui.controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.function.Consumer;
 | 
					import java.util.logging.*;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					 | 
				
			||||||
import java.util.logging.Logger;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javafx.application.Platform;
 | 
					import javafx.application.Platform;
 | 
				
			||||||
import javafx.fxml.FXML;
 | 
					import javafx.fxml.FXML;
 | 
				
			||||||
import javafx.scene.control.*;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
import javafx.scene.control.Alert.AlertType;
 | 
					import javafx.scene.control.Alert.AlertType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.event.BackEvent;
 | 
					import envoy.client.event.*;
 | 
				
			||||||
import envoy.client.event.SendEvent;
 | 
					import envoy.client.ui.listcell.*;
 | 
				
			||||||
import envoy.client.ui.listcell.ContactControl;
 | 
					 | 
				
			||||||
import envoy.client.ui.listcell.ListCellFactory;
 | 
					 | 
				
			||||||
import envoy.data.User;
 | 
					import envoy.data.User;
 | 
				
			||||||
import envoy.event.ElementOperation;
 | 
					import envoy.event.ElementOperation;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					import envoy.event.contact.*;
 | 
				
			||||||
import envoy.event.contact.ContactOperation;
 | 
					 | 
				
			||||||
import envoy.event.contact.UserSearchRequest;
 | 
					 | 
				
			||||||
import envoy.event.contact.UserSearchResult;
 | 
					 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					import envoy.util.EnvoyLog;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Provides a search bar in which a user name (substring) can be entered. The
 | 
					 * Provides a search bar in which a user name (substring) can be entered. The
 | 
				
			||||||
 * users with a matching name are then displayed inside a list view. A
 | 
					 * users with a matching name are then displayed inside a list view. A
 | 
				
			||||||
@@ -39,7 +34,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
 * @author Maximilian Käfer
 | 
					 * @author Maximilian Käfer
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class ContactSearchTab {
 | 
					public class ContactSearchTab implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private TextArea searchBar;
 | 
						private TextArea searchBar;
 | 
				
			||||||
@@ -48,26 +43,29 @@ public class ContactSearchTab {
 | 
				
			|||||||
	private ListView<User> userList;
 | 
						private ListView<User> userList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Alert alert = new Alert(AlertType.CONFIRMATION);
 | 
						private Alert alert = new Alert(AlertType.CONFIRMATION);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	private User currentlySelectedUser;
 | 
						private User currentlySelectedUser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private final Consumer<ContactOperation> handler = e -> {
 | 
					 | 
				
			||||||
		final var contact = e.get();
 | 
					 | 
				
			||||||
		if (e.getOperationType() == ElementOperation.ADD) Platform.runLater(() -> {
 | 
					 | 
				
			||||||
			userList.getItems().remove(contact);
 | 
					 | 
				
			||||||
			if (currentlySelectedUser != null && currentlySelectedUser.equals(contact) && alert.isShowing()) alert.close();
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static final EventBus	eventBus	= EventBus.getInstance();
 | 
						private static final EventBus	eventBus	= EventBus.getInstance();
 | 
				
			||||||
	private static final Logger		logger		= EnvoyLog.getLogger(ChatScene.class);
 | 
						private static final Logger		logger		= EnvoyLog.getLogger(ChatScene.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private void initialize() {
 | 
						private void initialize() {
 | 
				
			||||||
 | 
							eventBus.registerListener(this);
 | 
				
			||||||
		userList.setCellFactory(new ListCellFactory<>(ContactControl::new));
 | 
							userList.setCellFactory(new ListCellFactory<>(ContactControl::new));
 | 
				
			||||||
		eventBus.register(UserSearchResult.class,
 | 
						}
 | 
				
			||||||
				response -> Platform.runLater(() -> { userList.getItems().clear(); userList.getItems().addAll(response.get()); }));
 | 
					
 | 
				
			||||||
		eventBus.register(ContactOperation.class, handler);
 | 
						@Event
 | 
				
			||||||
 | 
						private void onUserSearchResult(UserSearchResult result) {
 | 
				
			||||||
 | 
							Platform.runLater(() -> { userList.getItems().clear(); userList.getItems().addAll(result.get()); });
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onContactOperation(ContactOperation operation) {
 | 
				
			||||||
 | 
							final var contact = operation.get();
 | 
				
			||||||
 | 
							if (operation.getOperationType() == ElementOperation.ADD) Platform.runLater(() -> {
 | 
				
			||||||
 | 
								userList.getItems().remove(contact);
 | 
				
			||||||
 | 
								if (currentlySelectedUser != null && currentlySelectedUser.equals(contact) && alert.isShowing()) alert.close();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,20 +8,15 @@ import javafx.fxml.FXML;
 | 
				
			|||||||
import javafx.scene.control.*;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
import javafx.scene.layout.HBox;
 | 
					import javafx.scene.layout.HBox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.Chat;
 | 
					import envoy.client.data.*;
 | 
				
			||||||
import envoy.client.data.Context;
 | 
					import envoy.client.event.*;
 | 
				
			||||||
import envoy.client.data.LocalDB;
 | 
					import envoy.client.ui.listcell.*;
 | 
				
			||||||
import envoy.client.event.BackEvent;
 | 
					import envoy.data.*;
 | 
				
			||||||
import envoy.client.event.SendEvent;
 | 
					 | 
				
			||||||
import envoy.client.ui.listcell.ContactControl;
 | 
					 | 
				
			||||||
import envoy.client.ui.listcell.ListCellFactory;
 | 
					 | 
				
			||||||
import envoy.data.Contact;
 | 
					 | 
				
			||||||
import envoy.data.Group;
 | 
					 | 
				
			||||||
import envoy.data.User;
 | 
					 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.event.GroupCreation;
 | 
					import envoy.event.GroupCreation;
 | 
				
			||||||
import envoy.util.Bounds;
 | 
					import envoy.util.Bounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Provides a group creation interface. A group name can be entered in the text
 | 
					 * Provides a group creation interface. A group name can be entered in the text
 | 
				
			||||||
 * field at the top. Available users (local chat recipients) are displayed
 | 
					 * field at the top. Available users (local chat recipients) are displayed
 | 
				
			||||||
@@ -38,7 +33,7 @@ import envoy.util.Bounds;
 | 
				
			|||||||
 * @author Maximilian Käfer
 | 
					 * @author Maximilian Käfer
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class GroupCreationTab {
 | 
					public class GroupCreationTab implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private Button createButton;
 | 
						private Button createButton;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
package envoy.client.ui.controller;
 | 
					package envoy.client.ui.controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.*;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javafx.application.Platform;
 | 
					 | 
				
			||||||
import javafx.fxml.FXML;
 | 
					import javafx.fxml.FXML;
 | 
				
			||||||
import javafx.geometry.Insets;
 | 
					import javafx.geometry.Insets;
 | 
				
			||||||
import javafx.scene.control.*;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
@@ -11,13 +9,12 @@ import javafx.scene.control.Alert.AlertType;
 | 
				
			|||||||
import javafx.scene.image.ImageView;
 | 
					import javafx.scene.image.ImageView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.ClientConfig;
 | 
					import envoy.client.data.ClientConfig;
 | 
				
			||||||
import envoy.client.ui.IconUtil;
 | 
					import envoy.client.ui.*;
 | 
				
			||||||
import envoy.client.ui.Startup;
 | 
					 | 
				
			||||||
import envoy.data.LoginCredentials;
 | 
					import envoy.data.LoginCredentials;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.event.HandshakeRejection;
 | 
					import envoy.event.HandshakeRejection;
 | 
				
			||||||
import envoy.util.Bounds;
 | 
					import envoy.util.*;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
@@ -28,7 +25,7 @@ import envoy.util.EnvoyLog;
 | 
				
			|||||||
 * @author Maximilian Käfer
 | 
					 * @author Maximilian Käfer
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public final class LoginScene {
 | 
					public final class LoginScene implements EventListener {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
	private TextField userTextField;
 | 
						private TextField userTextField;
 | 
				
			||||||
@@ -60,7 +57,6 @@ public final class LoginScene {
 | 
				
			|||||||
	private boolean registration = false;
 | 
						private boolean registration = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final Logger			logger		= EnvoyLog.getLogger(LoginScene.class);
 | 
						private static final Logger			logger		= EnvoyLog.getLogger(LoginScene.class);
 | 
				
			||||||
	private static final EventBus		eventBus	= EventBus.getInstance();
 | 
					 | 
				
			||||||
	private static final ClientConfig	config		= ClientConfig.getInstance();
 | 
						private static final ClientConfig	config		= ClientConfig.getInstance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@FXML
 | 
						@FXML
 | 
				
			||||||
@@ -68,7 +64,7 @@ public final class LoginScene {
 | 
				
			|||||||
		connectionLabel.setText("Server: " + config.getServer() + ":" + config.getPort());
 | 
							connectionLabel.setText("Server: " + config.getServer() + ":" + config.getPort());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Show an alert after an unsuccessful handshake
 | 
							// Show an alert after an unsuccessful handshake
 | 
				
			||||||
		eventBus.register(HandshakeRejection.class, e -> Platform.runLater(() -> { new Alert(AlertType.ERROR, e.get()).showAndWait(); }));
 | 
							EventBus.getInstance().registerListener(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		logo.setImage(IconUtil.loadIcon("envoy_logo"));
 | 
							logo.setImage(IconUtil.loadIcon("envoy_logo"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -119,4 +115,7 @@ public final class LoginScene {
 | 
				
			|||||||
		logger.log(Level.INFO, "The login process has been cancelled. Exiting...");
 | 
							logger.log(Level.INFO, "The login process has been cancelled. Exiting...");
 | 
				
			||||||
		System.exit(0);
 | 
							System.exit(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Event
 | 
				
			||||||
 | 
						private void onHandshakeRejection(HandshakeRejection evt) { new Alert(AlertType.ERROR, evt.get()).showAndWait(); }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,9 +7,10 @@ import javafx.scene.input.InputEvent;
 | 
				
			|||||||
import envoy.client.event.SendEvent;
 | 
					import envoy.client.event.SendEvent;
 | 
				
			||||||
import envoy.client.util.IssueUtil;
 | 
					import envoy.client.util.IssueUtil;
 | 
				
			||||||
import envoy.data.User;
 | 
					import envoy.data.User;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					 | 
				
			||||||
import envoy.event.IssueProposal;
 | 
					import envoy.event.IssueProposal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * This class offers the option for users to submit a bug report. Only the title
 | 
					 * This class offers the option for users to submit a bug report. Only the title
 | 
				
			||||||
 * of a bug is needed to be sent.
 | 
					 * of a bug is needed to be sent.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,12 @@
 | 
				
			|||||||
package envoy.client.ui.settings;
 | 
					package envoy.client.ui.settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javafx.scene.control.ComboBox;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
import javafx.scene.control.Tooltip;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.data.SettingsItem;
 | 
					import envoy.client.data.SettingsItem;
 | 
				
			||||||
import envoy.client.event.ThemeChangeEvent;
 | 
					import envoy.client.event.ThemeChangeEvent;
 | 
				
			||||||
import envoy.data.User.UserStatus;
 | 
					import envoy.data.User.UserStatus;
 | 
				
			||||||
import envoy.event.EventBus;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
@@ -44,7 +44,7 @@ public final class GeneralSettingsPane extends SettingsPane {
 | 
				
			|||||||
		combobox.setTooltip(new Tooltip("Determines the current theme Envoy will be displayed in."));
 | 
							combobox.setTooltip(new Tooltip("Determines the current theme Envoy will be displayed in."));
 | 
				
			||||||
		combobox.setValue(settings.getCurrentTheme());
 | 
							combobox.setValue(settings.getCurrentTheme());
 | 
				
			||||||
		combobox.setOnAction(
 | 
							combobox.setOnAction(
 | 
				
			||||||
				e -> { settings.setCurrentTheme(combobox.getValue()); EventBus.getInstance().dispatch(new ThemeChangeEvent(combobox.getValue())); });
 | 
									e -> { settings.setCurrentTheme(combobox.getValue()); EventBus.getInstance().dispatch(new ThemeChangeEvent()); });
 | 
				
			||||||
		getChildren().add(combobox);
 | 
							getChildren().add(combobox);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		final var statusComboBox = new ComboBox<UserStatus>();
 | 
							final var statusComboBox = new ComboBox<UserStatus>();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,31 +1,27 @@
 | 
				
			|||||||
package envoy.client.ui.settings;
 | 
					package envoy.client.ui.settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.ByteArrayInputStream;
 | 
					import java.io.*;
 | 
				
			||||||
import java.io.File;
 | 
					 | 
				
			||||||
import java.io.IOException;
 | 
					 | 
				
			||||||
import java.nio.file.Files;
 | 
					import java.nio.file.Files;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.*;
 | 
				
			||||||
import java.util.logging.Logger;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javafx.event.EventHandler;
 | 
					import javafx.event.EventHandler;
 | 
				
			||||||
import javafx.geometry.Pos;
 | 
					import javafx.geometry.Pos;
 | 
				
			||||||
import javafx.scene.Cursor;
 | 
					import javafx.scene.Cursor;
 | 
				
			||||||
import javafx.scene.control.*;
 | 
					import javafx.scene.control.*;
 | 
				
			||||||
import javafx.scene.control.Alert.AlertType;
 | 
					import javafx.scene.control.Alert.AlertType;
 | 
				
			||||||
import javafx.scene.image.Image;
 | 
					import javafx.scene.image.*;
 | 
				
			||||||
import javafx.scene.image.ImageView;
 | 
					 | 
				
			||||||
import javafx.scene.input.InputEvent;
 | 
					import javafx.scene.input.InputEvent;
 | 
				
			||||||
import javafx.scene.layout.HBox;
 | 
					import javafx.scene.layout.HBox;
 | 
				
			||||||
import javafx.stage.FileChooser;
 | 
					import javafx.stage.FileChooser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.event.SendEvent;
 | 
					import envoy.client.event.SendEvent;
 | 
				
			||||||
import envoy.client.ui.IconUtil;
 | 
					import envoy.client.ui.*;
 | 
				
			||||||
import envoy.client.ui.SceneContext;
 | 
					 | 
				
			||||||
import envoy.client.ui.custom.ProfilePicImageView;
 | 
					import envoy.client.ui.custom.ProfilePicImageView;
 | 
				
			||||||
import envoy.data.User;
 | 
					import envoy.data.User;
 | 
				
			||||||
import envoy.event.*;
 | 
					import envoy.event.*;
 | 
				
			||||||
import envoy.util.Bounds;
 | 
					import envoy.util.*;
 | 
				
			||||||
import envoy.util.EnvoyLog;
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.EventBus;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,19 +7,20 @@
 | 
				
			|||||||
 * @author Maximilian Käfer
 | 
					 * @author Maximilian Käfer
 | 
				
			||||||
 * @since Envoy Client v0.1-beta
 | 
					 * @since Envoy Client v0.1-beta
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
module envoy {
 | 
					module envoy.client {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	requires transitive envoy.common;
 | 
						requires envoy.common;
 | 
				
			||||||
	requires transitive java.desktop;
 | 
						requires java.desktop;
 | 
				
			||||||
	requires transitive java.logging;
 | 
						requires java.logging;
 | 
				
			||||||
	requires transitive java.prefs;
 | 
						requires java.prefs;
 | 
				
			||||||
	requires javafx.controls;
 | 
						requires javafx.controls;
 | 
				
			||||||
	requires javafx.fxml;
 | 
						requires javafx.fxml;
 | 
				
			||||||
	requires javafx.base;
 | 
						requires javafx.base;
 | 
				
			||||||
	requires javafx.graphics;
 | 
						requires javafx.graphics;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opens envoy.client.ui to javafx.graphics, javafx.fxml;
 | 
						opens envoy.client.ui to javafx.graphics, javafx.fxml, dev.kske.eventbus;
 | 
				
			||||||
	opens envoy.client.ui.controller to javafx.graphics, javafx.fxml, envoy.client.util;
 | 
						opens envoy.client.ui.controller to javafx.graphics, javafx.fxml, envoy.client.util, dev.kske.eventbus;
 | 
				
			||||||
	opens envoy.client.ui.custom to javafx.graphics, javafx.fxml;
 | 
						opens envoy.client.ui.custom to javafx.graphics, javafx.fxml;
 | 
				
			||||||
	opens envoy.client.ui.settings to envoy.client.util;
 | 
						opens envoy.client.ui.settings to envoy.client.util;
 | 
				
			||||||
 | 
						opens envoy.client.net to dev.kske.eventbus;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,11 +12,24 @@
 | 
				
			|||||||
		<version>0.1-beta</version>
 | 
							<version>0.1-beta</version>
 | 
				
			||||||
	</parent>
 | 
						</parent>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						<repositories>
 | 
				
			||||||
 | 
							<repository>
 | 
				
			||||||
 | 
								<id>kske-repo</id>
 | 
				
			||||||
 | 
								<url>https://kske.dev/maven-repo</url>
 | 
				
			||||||
 | 
							</repository>
 | 
				
			||||||
 | 
						</repositories>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<dependencies>
 | 
						<dependencies>
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>dev.kske</groupId>
 | 
				
			||||||
 | 
								<artifactId>event-bus</artifactId>
 | 
				
			||||||
 | 
								<version>0.0.3</version>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
		<dependency>
 | 
							<dependency>
 | 
				
			||||||
			<groupId>org.junit.jupiter</groupId>
 | 
								<groupId>org.junit.jupiter</groupId>
 | 
				
			||||||
			<artifactId>junit-jupiter-engine</artifactId>
 | 
								<artifactId>junit-jupiter-engine</artifactId>
 | 
				
			||||||
			<version>5.5.2</version>
 | 
								<version>5.5.2</version>
 | 
				
			||||||
 | 
								<scope>test</scope>
 | 
				
			||||||
		</dependency>
 | 
							</dependency>
 | 
				
			||||||
	</dependencies>
 | 
						</dependencies>
 | 
				
			||||||
	<build>
 | 
						<build>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,13 @@ package envoy.event;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.eventbus.IEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
					 * This class serves as a convenience base class for all events. It implements
 | 
				
			||||||
 | 
					 * the {@link IEvent} interface and provides a generic value. For events without
 | 
				
			||||||
 | 
					 * a value there also is {@link envoy.event.Event.Valueless}.
 | 
				
			||||||
 | 
					 * <p>
 | 
				
			||||||
 * Project: <strong>envoy-common</strong><br>
 | 
					 * Project: <strong>envoy-common</strong><br>
 | 
				
			||||||
 * File: <strong>Event.java</strong><br>
 | 
					 * File: <strong>Event.java</strong><br>
 | 
				
			||||||
 * Created: <strong>04.12.2019</strong><br>
 | 
					 * Created: <strong>04.12.2019</strong><br>
 | 
				
			||||||
@@ -11,7 +17,7 @@ import java.io.Serializable;
 | 
				
			|||||||
 * @param <T> the type of the Event
 | 
					 * @param <T> the type of the Event
 | 
				
			||||||
 * @since Envoy v0.2-alpha
 | 
					 * @since Envoy v0.2-alpha
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public abstract class Event<T> implements Serializable {
 | 
					public abstract class Event<T> implements IEvent, Serializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected final T value;
 | 
						protected final T value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,82 +0,0 @@
 | 
				
			|||||||
package envoy.event;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import java.util.*;
 | 
					 | 
				
			||||||
import java.util.function.Consumer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * This class handles events by allowing event handlers to register themselves
 | 
					 | 
				
			||||||
 * and then be notified about certain events dispatched by the event bus.<br>
 | 
					 | 
				
			||||||
 * <br>
 | 
					 | 
				
			||||||
 * The event bus is a singleton and can be used across the entire application to
 | 
					 | 
				
			||||||
 * guarantee the propagation of events.<br>
 | 
					 | 
				
			||||||
 * <br>
 | 
					 | 
				
			||||||
 * Project: <strong>envoy-common</strong><br>
 | 
					 | 
				
			||||||
 * File: <strong>EventBus.java</strong><br>
 | 
					 | 
				
			||||||
 * Created: <strong>04.12.2019</strong><br>
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Kai S. K. Engelbart
 | 
					 | 
				
			||||||
 * @since Envoy v0.2-alpha
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
public final class EventBus {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Contains all event handler instances registered at this event bus as values
 | 
					 | 
				
			||||||
	 * mapped to by their supported event classes.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	private Map<Class<? extends Event<?>>, List<Consumer<Event<?>>>> handlers = new HashMap<>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * The singleton instance of this event bus that is used across the
 | 
					 | 
				
			||||||
	 * entire application.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	private static EventBus eventBus = new EventBus();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * This constructor is not accessible from outside this class because a
 | 
					 | 
				
			||||||
	 * singleton instance of it is provided by the {@link EventBus#getInstance()}
 | 
					 | 
				
			||||||
	 * method.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	private EventBus() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * @return the singleton instance of the event bus
 | 
					 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public static EventBus getInstance() { return eventBus; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Registers an event handler to be notified when an
 | 
					 | 
				
			||||||
	 * event of a certain type is dispatched.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * @param <T>        the type of event values to notify the handler about
 | 
					 | 
				
			||||||
	 * @param eventClass the class which the event handler is subscribing to
 | 
					 | 
				
			||||||
	 * @param handler    the event handler to register
 | 
					 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public <T extends Event<?>> void register(Class<T> eventClass, Consumer<T> handler) {
 | 
					 | 
				
			||||||
		if (!handlers.containsKey(eventClass)) handlers.put(eventClass, new ArrayList<>());
 | 
					 | 
				
			||||||
		handlers.get(eventClass).add((Consumer<Event<?>>) handler);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Dispatches an event to every event handler subscribed to it.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * @param event the {@link Event} to dispatch
 | 
					 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public void dispatch(Event<?> event) {
 | 
					 | 
				
			||||||
		handlers.keySet()
 | 
					 | 
				
			||||||
			.stream()
 | 
					 | 
				
			||||||
			.filter(event.getClass()::equals)
 | 
					 | 
				
			||||||
			.map(handlers::get)
 | 
					 | 
				
			||||||
			.flatMap(List::stream)
 | 
					 | 
				
			||||||
			.forEach(h -> h.accept(event));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * @return a map of all event handler instances currently registered at this
 | 
					 | 
				
			||||||
	 *         event bus with the event classes they are subscribed to as keys
 | 
					 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public Map<Class<? extends Event<?>>, List<Consumer<Event<?>>>> getHandlers() { return handlers; }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -16,4 +16,5 @@ module envoy.common {
 | 
				
			|||||||
	exports envoy.event.contact;
 | 
						exports envoy.event.contact;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	requires transitive java.logging;
 | 
						requires transitive java.logging;
 | 
				
			||||||
 | 
						requires transitive dev.kske.eventbus;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,5 +16,4 @@ module envoy.server {
 | 
				
			|||||||
	requires transitive java.persistence;
 | 
						requires transitive java.persistence;
 | 
				
			||||||
	requires transitive java.sql;
 | 
						requires transitive java.sql;
 | 
				
			||||||
	requires transitive org.hibernate.orm.core;
 | 
						requires transitive org.hibernate.orm.core;
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user