Replace the internal event bus with Event Bus 0.0.3
The Event class has been retrofitted to implement IEvent, so that no event implementations had to be changed.
This commit is contained in:
parent
69ea737361
commit
465ed20efa
@ -10,16 +10,7 @@ import envoy.event.Event;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.*;
|
||||
|
||||
import envoy.client.data.*;
|
||||
import envoy.client.event.SendEvent;
|
||||
import envoy.data.*;
|
||||
import envoy.event.*;
|
||||
import envoy.event.contact.ContactOperation;
|
||||
import envoy.event.contact.UserSearchResult;
|
||||
import envoy.util.EnvoyLog;
|
||||
import envoy.util.SerializationUtils;
|
||||
import envoy.event.Event;
|
||||
import envoy.event.contact.*;
|
||||
import envoy.util.*;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
|
||||
/**
|
||||
* Establishes a connection to the server, performs a handshake and delivers
|
||||
@ -29,7 +28,7 @@ import envoy.util.SerializationUtils;
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Client v0.1-alpha
|
||||
*/
|
||||
public final class Client implements Closeable {
|
||||
public final class Client implements EventListener, Closeable {
|
||||
|
||||
// Connection handling
|
||||
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 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
|
||||
* 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
|
||||
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
|
||||
receiver.registerProcessor(NoAttachments.class, eventBus::dispatch);
|
||||
|
||||
// Process group creation results - they might have been disabled on the server
|
||||
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
|
||||
if (!localDB.hasIDGenerator() || !localDB.getIDGenerator().hasNext()) requestIdGenerator();
|
||||
|
||||
@ -219,6 +219,21 @@ public final class Client implements Closeable {
|
||||
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
|
||||
public void close() throws IOException { if (online) socket.close(); }
|
||||
|
||||
|
@ -4,10 +4,11 @@ import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.GroupMessageStatusChange;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</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);
|
||||
else EventBus.getInstance().dispatch(evt);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.MessageStatusChange;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>MessageStatusChangeProcessor.java</strong><br>
|
||||
|
@ -6,9 +6,10 @@ import java.util.logging.Logger;
|
||||
import envoy.client.event.MessageCreationEvent;
|
||||
import envoy.data.GroupMessage;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>ReceivedGroupMessageProcessor.java</strong><br>
|
||||
|
@ -5,7 +5,8 @@ import java.util.function.Consumer;
|
||||
import envoy.client.event.MessageCreationEvent;
|
||||
import envoy.data.Message;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.EventBus;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
|
@ -6,15 +6,15 @@ import java.util.logging.Level;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.*;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import envoy.client.data.Settings;
|
||||
import envoy.client.event.ThemeChangeEvent;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -30,7 +30,7 @@ import envoy.util.EnvoyLog;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @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.
|
||||
@ -84,7 +84,7 @@ public final class SceneContext {
|
||||
*/
|
||||
public SceneContext(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
|
||||
* @return the controller used by the current scene
|
||||
|
@ -8,7 +8,9 @@ import javafx.stage.Stage;
|
||||
|
||||
import envoy.client.event.MessageCreationEvent;
|
||||
import envoy.data.Message;
|
||||
import envoy.event.EventBus;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
import dev.kske.eventbus.Event;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
@ -18,7 +20,7 @@ import envoy.event.EventBus;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @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
|
||||
@ -67,14 +69,7 @@ public final class StatusTrayIcon {
|
||||
trayIcon.addActionListener(evt -> Platform.runLater(() -> { stage.setIconified(false); stage.toFront(); stage.requestFocus(); }));
|
||||
|
||||
// Start processing message events
|
||||
EventBus.getInstance().register(MessageCreationEvent.class, 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);
|
||||
});
|
||||
EventBus.getInstance().registerListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,4 +89,11 @@ public final class StatusTrayIcon {
|
||||
* @since Envoy Client v0.2-beta
|
||||
*/
|
||||
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;
|
||||
|
||||
import static envoy.data.Message.MessageStatus.RECEIVED;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.io.*;
|
||||
@ -36,11 +34,15 @@ import envoy.client.ui.listcell.*;
|
||||
import envoy.client.util.ReflectionUtil;
|
||||
import envoy.data.*;
|
||||
import envoy.data.Attachment.AttachmentType;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.event.*;
|
||||
import envoy.event.contact.ContactOperation;
|
||||
import envoy.exception.EnvoyException;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
import dev.kske.eventbus.Event;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>ChatSceneController.java</strong><br>
|
||||
@ -49,7 +51,7 @@ import envoy.util.EnvoyLog;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final class ChatScene implements Restorable {
|
||||
public final class ChatScene implements EventListener, Restorable {
|
||||
|
||||
@FXML
|
||||
private GridPane scene;
|
||||
@ -160,6 +162,8 @@ public final class ChatScene implements Restorable {
|
||||
*/
|
||||
@FXML
|
||||
private void initialize() {
|
||||
eventBus.registerListener(this);
|
||||
|
||||
// Initialize message and user rendering
|
||||
messageList.setCellFactory(MessageListCell::new);
|
||||
chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
|
||||
@ -201,110 +205,119 @@ public final class ChatScene implements Restorable {
|
||||
updateInfoLabel("You are offline", "info-label-warning");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Listen to backEvents
|
||||
eventBus.register(BackEvent.class, e -> tabPane.getSelectionModel().select(Tabs.CONTACT_LIST.ordinal()));
|
||||
@Event(eventType = BackEvent.class)
|
||||
private void onBackEvent() { tabPane.getSelectionModel().select(Tabs.CONTACT_LIST.ordinal()); }
|
||||
|
||||
// Listen to received messages
|
||||
eventBus.register(MessageCreationEvent.class, e -> {
|
||||
final var message = e.get();
|
||||
@Event
|
||||
private void onMessageCreation(MessageCreationEvent evt) {
|
||||
final var message = evt.get();
|
||||
|
||||
// The sender of the message is the recipient of the chat
|
||||
// Exceptions: this user is the sender (sync) or group message (group is
|
||||
// recipient)
|
||||
final var recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID()
|
||||
: message.getSenderID();
|
||||
localDB.getChat(recipientID).ifPresent(chat -> {
|
||||
chat.insert(message);
|
||||
if (chat.equals(currentChat)) {
|
||||
try {
|
||||
currentChat.read(writeProxy);
|
||||
} catch (final IOException e1) {
|
||||
logger.log(Level.WARNING, "Could not read current chat: ", e1);
|
||||
}
|
||||
Platform.runLater(() -> { ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); });
|
||||
// TODO: Increment unread counter for group messages with status < RECEIVED
|
||||
} else if (message.getSenderID() != localDB.getUser().getID() && message.getStatus() == RECEIVED) chat.incrementUnreadAmount();
|
||||
// The sender of the message is the recipient of the chat
|
||||
// Exceptions: this user is the sender (sync) or group message (group is
|
||||
// recipient)
|
||||
final var recipientID = message instanceof GroupMessage || message.getSenderID() == localDB.getUser().getID() ? message.getRecipientID()
|
||||
: message.getSenderID();
|
||||
localDB.getChat(recipientID).ifPresent(chat -> {
|
||||
chat.insert(message);
|
||||
if (chat.equals(currentChat)) {
|
||||
try {
|
||||
currentChat.read(writeProxy);
|
||||
} catch (final IOException e1) {
|
||||
logger.log(Level.WARNING, "Could not read current chat: ", e1);
|
||||
}
|
||||
Platform.runLater(() -> { ListViewRefresh.deepRefresh(messageList); scrollToMessageListEnd(); });
|
||||
// TODO: Increment unread counter for group messages with status < RECEIVED
|
||||
} else
|
||||
if (message.getSenderID() != localDB.getUser().getID() && message.getStatus() == MessageStatus.RECEIVED) chat.incrementUnreadAmount();
|
||||
|
||||
// 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 -> {
|
||||
// Move chat with most recent unread messages to the top
|
||||
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();
|
||||
chats.getSource().remove(chat);
|
||||
((ObservableList<Chat>) chats.getSource()).add(0, chat);
|
||||
|
||||
if (chat.equals(currentChat)) chatList.getSelectionModel().select(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
eventBus.register(GroupCreationResult.class, e -> Platform.runLater(() -> { newGroupButton.setDisable(!e.get()); }));
|
||||
|
||||
eventBus.register(ThemeChangeEvent.class, e -> {
|
||||
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));
|
||||
@Event
|
||||
private void onMessageStatusChange(MessageStatusChange evt) {
|
||||
localDB.getMessage(evt.getID()).ifPresent(message -> {
|
||||
message.setStatus(evt.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);
|
||||
});
|
||||
}
|
||||
|
||||
@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}.
|
||||
*
|
||||
|
@ -1,26 +1,21 @@
|
||||
package envoy.client.ui.controller;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.*;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
|
||||
import envoy.client.event.BackEvent;
|
||||
import envoy.client.event.SendEvent;
|
||||
import envoy.client.ui.listcell.ContactControl;
|
||||
import envoy.client.ui.listcell.ListCellFactory;
|
||||
import envoy.client.event.*;
|
||||
import envoy.client.ui.listcell.*;
|
||||
import envoy.data.User;
|
||||
import envoy.event.ElementOperation;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.contact.ContactOperation;
|
||||
import envoy.event.contact.UserSearchRequest;
|
||||
import envoy.event.contact.UserSearchResult;
|
||||
import envoy.event.contact.*;
|
||||
import envoy.util.EnvoyLog;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -39,7 +34,7 @@ import envoy.util.EnvoyLog;
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class ContactSearchTab {
|
||||
public class ContactSearchTab implements EventListener {
|
||||
|
||||
@FXML
|
||||
private TextArea searchBar;
|
||||
@ -48,26 +43,29 @@ public class ContactSearchTab {
|
||||
private ListView<User> userList;
|
||||
|
||||
private Alert alert = new Alert(AlertType.CONFIRMATION);
|
||||
|
||||
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 Logger logger = EnvoyLog.getLogger(ChatScene.class);
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
eventBus.registerListener(this);
|
||||
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.layout.HBox;
|
||||
|
||||
import envoy.client.data.Chat;
|
||||
import envoy.client.data.Context;
|
||||
import envoy.client.data.LocalDB;
|
||||
import envoy.client.event.BackEvent;
|
||||
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.client.data.*;
|
||||
import envoy.client.event.*;
|
||||
import envoy.client.ui.listcell.*;
|
||||
import envoy.data.*;
|
||||
import envoy.event.GroupCreation;
|
||||
import envoy.util.Bounds;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -38,7 +33,7 @@ import envoy.util.Bounds;
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class GroupCreationTab {
|
||||
public class GroupCreationTab implements EventListener {
|
||||
|
||||
@FXML
|
||||
private Button createButton;
|
||||
|
@ -1,9 +1,7 @@
|
||||
package envoy.client.ui.controller;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.*;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.*;
|
||||
@ -11,13 +9,12 @@ import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
import envoy.client.data.ClientConfig;
|
||||
import envoy.client.ui.IconUtil;
|
||||
import envoy.client.ui.Startup;
|
||||
import envoy.client.ui.*;
|
||||
import envoy.data.LoginCredentials;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.HandshakeRejection;
|
||||
import envoy.util.Bounds;
|
||||
import envoy.util.EnvoyLog;
|
||||
import envoy.util.*;
|
||||
|
||||
import dev.kske.eventbus.*;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
@ -28,7 +25,7 @@ import envoy.util.EnvoyLog;
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final class LoginScene {
|
||||
public final class LoginScene implements EventListener {
|
||||
|
||||
@FXML
|
||||
private TextField userTextField;
|
||||
@ -60,7 +57,6 @@ public final class LoginScene {
|
||||
private boolean registration = false;
|
||||
|
||||
private static final Logger logger = EnvoyLog.getLogger(LoginScene.class);
|
||||
private static final EventBus eventBus = EventBus.getInstance();
|
||||
private static final ClientConfig config = ClientConfig.getInstance();
|
||||
|
||||
@FXML
|
||||
@ -68,7 +64,7 @@ public final class LoginScene {
|
||||
connectionLabel.setText("Server: " + config.getServer() + ":" + config.getPort());
|
||||
|
||||
// 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"));
|
||||
|
||||
@ -119,4 +115,7 @@ public final class LoginScene {
|
||||
logger.log(Level.INFO, "The login process has been cancelled. Exiting...");
|
||||
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.util.IssueUtil;
|
||||
import envoy.data.User;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.IssueProposal;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* This class offers the option for users to submit a bug report. Only the title
|
||||
* of a bug is needed to be sent.
|
||||
|
@ -1,12 +1,12 @@
|
||||
package envoy.client.ui.settings;
|
||||
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Tooltip;
|
||||
import javafx.scene.control.*;
|
||||
|
||||
import envoy.client.data.SettingsItem;
|
||||
import envoy.client.event.ThemeChangeEvent;
|
||||
import envoy.data.User.UserStatus;
|
||||
import envoy.event.EventBus;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* 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.setValue(settings.getCurrentTheme());
|
||||
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);
|
||||
|
||||
final var statusComboBox = new ComboBox<UserStatus>();
|
||||
|
@ -1,31 +1,27 @@
|
||||
package envoy.client.ui.settings;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.*;
|
||||
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.image.*;
|
||||
import javafx.scene.input.InputEvent;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.stage.FileChooser;
|
||||
|
||||
import envoy.client.event.SendEvent;
|
||||
import envoy.client.ui.IconUtil;
|
||||
import envoy.client.ui.SceneContext;
|
||||
import envoy.client.ui.*;
|
||||
import envoy.client.ui.custom.ProfilePicImageView;
|
||||
import envoy.data.User;
|
||||
import envoy.event.*;
|
||||
import envoy.util.Bounds;
|
||||
import envoy.util.EnvoyLog;
|
||||
import envoy.util.*;
|
||||
|
||||
import dev.kske.eventbus.EventBus;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
|
@ -7,19 +7,20 @@
|
||||
* @author Maximilian Käfer
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
module envoy {
|
||||
module envoy.client {
|
||||
|
||||
requires transitive envoy.common;
|
||||
requires transitive java.desktop;
|
||||
requires transitive java.logging;
|
||||
requires transitive java.prefs;
|
||||
requires envoy.common;
|
||||
requires java.desktop;
|
||||
requires java.logging;
|
||||
requires java.prefs;
|
||||
requires javafx.controls;
|
||||
requires javafx.fxml;
|
||||
requires javafx.base;
|
||||
requires javafx.graphics;
|
||||
|
||||
opens envoy.client.ui to javafx.graphics, javafx.fxml;
|
||||
opens envoy.client.ui.controller to javafx.graphics, javafx.fxml, envoy.client.util;
|
||||
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, dev.kske.eventbus;
|
||||
opens envoy.client.ui.custom to javafx.graphics, javafx.fxml;
|
||||
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>
|
||||
</parent>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>kske-repo</id>
|
||||
<url>https://kske.dev/maven-repo</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.kske</groupId>
|
||||
<artifactId>event-bus</artifactId>
|
||||
<version>0.0.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.5.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
@ -2,7 +2,13 @@ package envoy.event;
|
||||
|
||||
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>
|
||||
* File: <strong>Event.java</strong><br>
|
||||
* Created: <strong>04.12.2019</strong><br>
|
||||
@ -11,7 +17,7 @@ import java.io.Serializable;
|
||||
* @param <T> the type of the Event
|
||||
* @since Envoy v0.2-alpha
|
||||
*/
|
||||
public abstract class Event<T> implements Serializable {
|
||||
public abstract class Event<T> implements IEvent, Serializable {
|
||||
|
||||
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;
|
||||
|
||||
requires transitive java.logging;
|
||||
requires transitive dev.kske.eventbus;
|
||||
}
|
||||
|
@ -16,5 +16,4 @@ module envoy.server {
|
||||
requires transitive java.persistence;
|
||||
requires transitive java.sql;
|
||||
requires transitive org.hibernate.orm.core;
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user