Merge branch 'develop' into f/logger
This commit is contained in:
		| @@ -14,6 +14,8 @@ import java.util.logging.Logger; | ||||
| import javax.xml.datatype.DatatypeConfigurationException; | ||||
| import javax.xml.datatype.DatatypeFactory; | ||||
|  | ||||
| import envoy.client.event.EventBus; | ||||
| import envoy.client.event.MessageCreationEvent; | ||||
| import envoy.exception.EnvoyException; | ||||
| import envoy.schema.Message; | ||||
| import envoy.schema.Message.Metadata.MessageState; | ||||
| @@ -38,12 +40,12 @@ public class LocalDB { | ||||
| 	private ObjectFactory	objectFactory	= new ObjectFactory(); | ||||
| 	private DatatypeFactory	datatypeFactory; | ||||
|  | ||||
| 	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); | ||||
|  | ||||
| 	private Sync	unreadMessagesSync	= objectFactory.createSync(); | ||||
| 	private Sync	sync				= objectFactory.createSync(); | ||||
| 	private Sync	readMessages		= objectFactory.createSync(); | ||||
|  | ||||
| 	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); | ||||
|  | ||||
| 	/** | ||||
| 	 * Constructs an empty local database. | ||||
| 	 * | ||||
| @@ -108,7 +110,7 @@ public class LocalDB { | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a {@link Message} object serializable to XML. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @param textContent The content (text) of the message | ||||
| 	 * @param recipient   The recipient of the message | ||||
| 	 * @return prepared {@link Message} object | ||||
| @@ -132,6 +134,14 @@ public class LocalDB { | ||||
| 		return message; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
| 	 * Creates a {@link Sync} object filled with the changes that occurred to the | ||||
| 	 * local database since the last synchronization. | ||||
| 	 *  | ||||
| 	 * @param userId the ID of the user that is synchronized by this client | ||||
| 	 * @return {@link Sync} object filled with the current changes | ||||
|      * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public Sync fillSync(long userId) { | ||||
| 		addWaitingMessagesToSync(); | ||||
|  | ||||
| @@ -142,78 +152,74 @@ public class LocalDB { | ||||
| 		return sync; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Applies the changes carried by a {@link Sync} object to the local database | ||||
| 	 *  | ||||
| 	 * @param returnSync the {@link Sync} object to apply | ||||
|      * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void applySync(Sync returnSync) { | ||||
| 		for (int i = 0; i < returnSync.getMessages().size(); i++) { | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0 | ||||
| 					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.SENT) { | ||||
| 				// Update Local Messages with State WAITING (add Message ID and change State to | ||||
| 				// SENT) | ||||
| 				for (int j = 0; j < sync.getMessages().size(); j++) { | ||||
| 					if (j == i) { | ||||
| 						sync.getMessages().get(j).getMetadata().setMessageId(returnSync.getMessages().get(j).getMetadata().getMessageId()); | ||||
| 						sync.getMessages().get(j).getMetadata().setState(returnSync.getMessages().get(j).getMetadata().getState()); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0 && returnSync.getMessages().get(i).getMetadata().getSender() != 0 | ||||
| 					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.RECEIVED) { | ||||
| 				// these are the unread Messages from the server | ||||
| 				unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); | ||||
| 			} | ||||
|  | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0 && returnSync.getMessages().get(i).getMetadata().getSender() == 0 | ||||
| 					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.RECEIVED) { | ||||
| 				// Update Messages in localDB to state RECEIVED | ||||
| 				for (int j = 0; j < getChats().size(); j++) { | ||||
| 					if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | ||||
| 						for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | ||||
| 							if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | ||||
| 								.get(i) | ||||
| 								.getMetadata() | ||||
| 								.getMessageId()) { | ||||
| 								// Update Message in LocalDB | ||||
| 								getChats().get(j).getModel().get(k).getMetadata().setState(returnSync.getMessages().get(j).getMetadata().getState()); | ||||
| 							} | ||||
| 			// The message has an ID | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) { | ||||
|  | ||||
| 				// Messages are processes differently corresponding to their state | ||||
| 				switch (returnSync.getMessages().get(i).getMetadata().getState()) { | ||||
| 					case SENT: | ||||
| 						// Update previously waiting and now sent messages that were assigned an ID by | ||||
| 						// the server | ||||
| 						sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId()); | ||||
| 						sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 						break; | ||||
| 					case RECEIVED: | ||||
| 						if (returnSync.getMessages().get(i).getMetadata().getSender() != 0) { | ||||
| 							// these are the unread Messages from the server | ||||
| 							unreadMessagesSync.getMessages().add(returnSync.getMessages().get(i)); | ||||
|  | ||||
| 							// Create and dispatch message creation event | ||||
| 							EventBus.getInstance().dispatch(new MessageCreationEvent(returnSync.getMessages().get(i))); | ||||
| 						} else { | ||||
| 							// Update Messages in localDB to state RECEIVED | ||||
| 							for (Chat chat : getChats()) | ||||
| 								if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) | ||||
| 									for (int j = 0; j < chat.getModel().getSize(); j++) | ||||
| 									if (chat.getModel().get(j).getMetadata().getMessageId() == returnSync.getMessages() | ||||
| 										.get(i) | ||||
| 										.getMetadata() | ||||
| 										.getMessageId()) | ||||
| 										chat.getModel().get(j).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
|  | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0 | ||||
| 					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.READ) { | ||||
| 				// Update local Messages to state READ | ||||
| 				logger.finest("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | ||||
| 						+ "was initialized to be set to READ in localDB."); | ||||
| 				for (int j = 0; j < getChats().size(); j++) { | ||||
| 					if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | ||||
| 						logger.fine("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected."); | ||||
| 						for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | ||||
| 							if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | ||||
| 								.get(i) | ||||
| 								.getMetadata() | ||||
| 								.getMessageId()) { | ||||
| 								logger | ||||
| 									.finest("Message with ID: " + getChats().get(j).getModel().get(k).getMetadata().getMessageId() + "was selected."); | ||||
| 								getChats().get(j).getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 								logger.finest("Message State is now: " + getChats().get(j).getModel().get(k).getMetadata().getState().toString()); | ||||
| 						break; | ||||
| 					case READ: | ||||
| 						// Update local Messages to state READ | ||||
| 						logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | ||||
| 								+ "was initialized to be set to READ in localDB."); | ||||
| 						for (Chat chat : getChats()) | ||||
| 							if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | ||||
| 								logger.info("Chat with: " + chat.getRecipient().getID() + "was selected."); | ||||
| 								for (int k = 0; k < chat.getModel().getSize(); k++) | ||||
| 									if (chat.getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | ||||
| 										.get(i) | ||||
| 										.getMetadata() | ||||
| 										.getMessageId()) { | ||||
| 										logger.info("Message with ID: " + chat.getModel().get(k).getMetadata().getMessageId() + "was selected."); | ||||
| 										chat.getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 										logger.info("Message State is now: " + chat.getModel().get(k).getMetadata().getState()); | ||||
| 									} | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| 						break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// Updating UserStatus of all users in LocalDB | ||||
| 		for (int j = 0; j < returnSync.getUsers().size(); j++) { | ||||
| 			for (int k = 0; k < getChats().size(); k++) { | ||||
| 				if (getChats().get(k).getRecipient().getID() == returnSync.getUsers().get(j).getID()) { | ||||
|  | ||||
| 					getChats().get(k).getRecipient().setStatus(returnSync.getUsers().get(j).getStatus()); | ||||
| 					logger.info(getChats().get(k).getRecipient().getStatus().toString()); | ||||
| 		for (User user : returnSync.getUsers()) | ||||
| 			for (Chat chat : getChats()) | ||||
| 				if (user.getID() == chat.getRecipient().getID()) { | ||||
| 					chat.getRecipient().setStatus(user.getStatus()); | ||||
| 					logger.info(chat.getRecipient().getStatus().toString()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		sync.getMessages().clear(); | ||||
| 		sync.getUsers().clear(); | ||||
| @@ -222,15 +228,15 @@ public class LocalDB { | ||||
| 	/** | ||||
| 	 * Adds the unread messages returned from the server in the latest sync to the | ||||
| 	 * right chats in the LocalDB. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void addUnreadMessagesToLocalDB() { | ||||
| 		Sync unreadMessages = unreadMessagesSync; | ||||
| 		for (int i = 0; i < unreadMessages.getMessages().size(); i++) | ||||
| 			for (int j = 0; j < getChats().size(); j++) | ||||
| 				if (getChats().get(j).getRecipient().getID() == unreadMessages.getMessages().get(i).getMetadata().getSender()) { | ||||
| 					getChats().get(j).appendMessage(unreadMessages.getMessages().get(i)); | ||||
| 		for (Message message : unreadMessagesSync.getMessages()) | ||||
| 			for (Chat chat : getChats()) | ||||
| 				if (message.getMetadata().getSender() == chat.getRecipient().getID()) { | ||||
| 					chat.appendMessage(message); | ||||
| 					break; | ||||
| 				} | ||||
| 	} | ||||
|  | ||||
| @@ -239,7 +245,7 @@ public class LocalDB { | ||||
| 	 * {@code READ}. | ||||
| 	 * <br> | ||||
| 	 * Adds these messages to the {@code readMessages} {@link Sync} object. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @param currentChat the {@link Chat} that was just opened | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| @@ -255,14 +261,13 @@ public class LocalDB { | ||||
| 	/** | ||||
| 	 * Adds all messages with state {@code WAITING} from the {@link LocalDB} to the | ||||
| 	 * {@link Sync} object. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void addWaitingMessagesToSync() { | ||||
| 		for (Chat chat : getChats()) | ||||
| 			for (int i = 0; i < chat.getModel().size(); i++) | ||||
| 				if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) { | ||||
| 					// addMessageToSync(localDB.getChats().get(i).getModel().get(j)); | ||||
| 					logger.info("Got Waiting Message"); | ||||
| 					sync.getMessages().add(chat.getModel().get(i)); | ||||
| 				} | ||||
| @@ -270,14 +275,14 @@ public class LocalDB { | ||||
|  | ||||
| 	/** | ||||
| 	 * Clears the {@code unreadMessagesSync} {@link Sync} object. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return all saves {@link Chat} objects that list the client user as the | ||||
| 	 *         client | ||||
| 	 * @return all saved {@link Chat} objects that list the client user as the | ||||
| 	 *         sender | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 **/ | ||||
| 	public List<Chat> getChats() { return chats; } | ||||
|   | ||||
							
								
								
									
										17
									
								
								src/main/java/envoy/client/event/Event.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/main/java/envoy/client/event/Event.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-clientChess</strong><br> | ||||
|  * File: <strong>Event.javaEvent.java</strong><br> | ||||
|  * Created: <strong>04.12.2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.2-alpha | ||||
|  */ | ||||
| public interface Event<T> { | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the data associated with this event | ||||
| 	 */ | ||||
| 	T get(); | ||||
| } | ||||
							
								
								
									
										71
									
								
								src/main/java/envoy/client/event/EventBus.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/main/java/envoy/client/event/EventBus.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * This class handles events by allowing {@link EventHandler} object 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. | ||||
|  * Project: <strong>envoy-client</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 class EventBus { | ||||
|  | ||||
| 	/** | ||||
| 	 * Contains all {@link EventHandler} instances registered at this | ||||
| 	 * {@link EventBus}. | ||||
| 	 */ | ||||
| 	private List<EventHandler> handlers = new ArrayList<>(); | ||||
|  | ||||
| 	/** | ||||
| 	 * The singleton instance of this {@link EventBus} 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 {@link EventBus} | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public static EventBus getInstance() { return eventBus; } | ||||
|  | ||||
| 	/** | ||||
| 	 * Registers a list of {@link EventHandler} objects to be notified when a | ||||
| 	 * {@link Event} is dispatched that they are subscribed to. | ||||
| 	 *  | ||||
| 	 * @param handlers the {@link EventHandler} objects to register | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void register(EventHandler... handlers) { this.handlers.addAll(Arrays.asList(handlers)); } | ||||
|  | ||||
| 	/** | ||||
| 	 * Dispatches a {@link Event} to every {@link EventHandler} subscribed to it. | ||||
| 	 *  | ||||
| 	 * @param event the {@link Event} to dispatch | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void dispatch(Event<?> event) { handlers.stream().filter(h -> h.supports().contains(event.getClass())).forEach(h -> h.handle(event)); } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return a list of all {@link EventHandler} instances currently registered at | ||||
| 	 *         this {@link EventBus} | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public List<EventHandler> getHandlers() { return handlers; } | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/main/java/envoy/client/event/EventHandler.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/main/java/envoy/client/event/EventHandler.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-clientChess</strong><br> | ||||
|  * File: <strong>EventHandler.javaEvent.java</strong><br> | ||||
|  * Created: <strong>04.12.2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  */ | ||||
| public interface EventHandler { | ||||
|  | ||||
| 	/** | ||||
| 	 * Consumes an event dispatched by the event bus. | ||||
| 	 *  | ||||
| 	 * @param event The event dispatched by the event bus, only of supported type | ||||
| 	 */ | ||||
| 	void handle(Event<?> event); | ||||
|  | ||||
| 	/** | ||||
| 	 * @return A set of classes this class is supposed to handle in events | ||||
| 	 */ | ||||
| 	Set<Class<? extends Event<?>>> supports(); | ||||
| } | ||||
							
								
								
									
										18
									
								
								src/main/java/envoy/client/event/MessageCreationEvent.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/main/java/envoy/client/event/MessageCreationEvent.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>MessageCreationEvent.java</strong><br> | ||||
|  * Created: <strong>4 Dec 2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  */ | ||||
| public class MessageCreationEvent extends MessageEvent { | ||||
|  | ||||
| 	/** | ||||
| 	 * @param message the {@link Message} that has been created | ||||
| 	 */ | ||||
| 	public MessageCreationEvent(Message message) { super(message); } | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/main/java/envoy/client/event/MessageEvent.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/main/java/envoy/client/event/MessageEvent.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>MessageCreationEvent.java</strong><br> | ||||
|  * Created: <strong>4 Dec 2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  */ | ||||
| public class MessageEvent implements Event<Message> { | ||||
|  | ||||
| 	protected final Message message; | ||||
|  | ||||
| 	public MessageEvent(Message message) { this.message = message; } | ||||
|  | ||||
| 	@Override | ||||
| 	public Message get() { return message; } | ||||
| } | ||||
| @@ -0,0 +1,18 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>MessageModificationEvent.java</strong><br> | ||||
|  * Created: <strong>4 Dec 2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  */ | ||||
| public class MessageModificationEvent extends MessageEvent { | ||||
|  | ||||
| 	/** | ||||
| 	 * @param message the {@link Message} that has been modified | ||||
| 	 */ | ||||
| 	public MessageModificationEvent(Message message) { super(message); } | ||||
| } | ||||
| @@ -40,7 +40,7 @@ import envoy.schema.User; | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>ChatWindow.java</strong><br> | ||||
|  * Created: <strong>28 Sep 2019</strong><br> | ||||
|  *  | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Leon Hofmeister | ||||
| @@ -59,7 +59,7 @@ public class ChatWindow extends JFrame { | ||||
| 	private Chat		currentChat; | ||||
|  | ||||
| 	private JTextArea messageEnterTextArea; | ||||
|  | ||||
| 	 | ||||
| 	private static final Logger logger = Logger.getLogger(ChatWindow.class.getSimpleName()); | ||||
|  | ||||
| 	public ChatWindow(Client client, LocalDB localDB) { | ||||
| @@ -134,13 +134,9 @@ public class ChatWindow extends JFrame { | ||||
|  | ||||
| 			@Override | ||||
| 			public void keyReleased(KeyEvent e) { | ||||
|  | ||||
| 				if (e.getKeyCode() == KeyEvent.VK_ENTER | ||||
| 						&& ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) { | ||||
|  | ||||
| 						&& ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) | ||||
| 					postMessage(messageList); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		}); | ||||
| 		// Checks for changed Message | ||||
| @@ -268,6 +264,7 @@ public class ChatWindow extends JFrame { | ||||
| 	private void postMessage(JList<Message> messageList) { | ||||
| 		if (!client.hasRecipient()) { | ||||
| 			JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE); | ||||
| 			return; | ||||
| 		} | ||||
|  | ||||
| 		if (!messageEnterTextArea.getText().isEmpty()) try { | ||||
| @@ -292,7 +289,7 @@ public class ChatWindow extends JFrame { | ||||
| 	/** | ||||
| 	 * Initializes the elements of the user list by downloading them from the | ||||
| 	 * server. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void loadUsersAndChats() { | ||||
| @@ -313,7 +310,7 @@ public class ChatWindow extends JFrame { | ||||
| 	/** | ||||
| 	 * Updates the data model and the UI repeatedly after a certain amount of | ||||
| 	 * time. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @param timeout the amount of time that passes between two requests sent to | ||||
| 	 *                the server | ||||
| 	 * @since Envoy v0.1-alpha | ||||
|   | ||||
| @@ -71,8 +71,9 @@ public class Startup { | ||||
|  | ||||
| 		EventQueue.invokeLater(() -> { | ||||
| 			try { | ||||
| 				ChatWindow frame = new ChatWindow(client, localDB); | ||||
| 				frame.setVisible(true); | ||||
| 				ChatWindow chatWindow = new ChatWindow(client, localDB); | ||||
| 				new StatusTrayIcon(chatWindow).show(); | ||||
| 				chatWindow.setVisible(true); | ||||
| 			} catch (Exception e) { | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										133
									
								
								src/main/java/envoy/client/ui/StatusTrayIcon.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								src/main/java/envoy/client/ui/StatusTrayIcon.java
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.AWTException; | ||||
| import java.awt.Image; | ||||
| import java.awt.MenuItem; | ||||
| import java.awt.PopupMenu; | ||||
| import java.awt.SystemTray; | ||||
| import java.awt.Toolkit; | ||||
| import java.awt.TrayIcon; | ||||
| import java.awt.TrayIcon.MessageType; | ||||
| import java.awt.Window; | ||||
| import java.awt.event.WindowAdapter; | ||||
| import java.awt.event.WindowEvent; | ||||
| import java.util.HashSet; | ||||
| import java.util.Set; | ||||
|  | ||||
| import envoy.client.event.Event; | ||||
| import envoy.client.event.EventBus; | ||||
| import envoy.client.event.EventHandler; | ||||
| import envoy.client.event.MessageCreationEvent; | ||||
| import envoy.exception.EnvoyException; | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>StatusTrayIcon.java</strong><br> | ||||
|  * Created: <strong>3 Dec 2019</strong><br> | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.2-alpha | ||||
|  */ | ||||
| public class StatusTrayIcon implements EventHandler { | ||||
|  | ||||
| 	/** | ||||
| 	 * The {@link TrayIcon} provided by the System Tray API for controlling the | ||||
| 	 * system tray. This includes displaying the icon, but also creating | ||||
| 	 * notifications when new messages are received. | ||||
| 	 */ | ||||
| 	private TrayIcon trayIcon; | ||||
|  | ||||
| 	/** | ||||
| 	 * A received {@link Message} is only displayed as a system tray notification if | ||||
| 	 * this variable is set to {@code true}. | ||||
| 	 */ | ||||
| 	private boolean displayMessages = false; | ||||
|  | ||||
| 	/** | ||||
| 	 * Creates a {@link StatusTrayIcon} with the Envoy logo, a tool tip and a pop-up | ||||
| 	 * menu. | ||||
| 	 * | ||||
| 	 * @param focusTarget the {@link Window} which focus determines if message | ||||
| 	 *                    notifications are displayed | ||||
| 	 * @throws EnvoyException if the currently used OS does not support the System | ||||
| 	 *                        Tray API | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public StatusTrayIcon(Window focusTarget) throws EnvoyException { | ||||
| 		if (!SystemTray.isSupported()) throw new EnvoyException("The Envoy tray icon is not supported."); | ||||
|  | ||||
| 		ClassLoader	loader	= Thread.currentThread().getContextClassLoader(); | ||||
| 		Image		img		= Toolkit.getDefaultToolkit().createImage(loader.getResource("envoy_logo.png")); | ||||
| 		trayIcon = new TrayIcon(img, "Envoy Client"); | ||||
| 		trayIcon.setImageAutoSize(true); | ||||
| 		trayIcon.setToolTip("You are notified if you have unread messages."); | ||||
|  | ||||
| 		PopupMenu popup = new PopupMenu(); | ||||
|  | ||||
| 		MenuItem exitMenuItem = new MenuItem("Exit"); | ||||
| 		exitMenuItem.addActionListener((evt) -> System.exit(0)); | ||||
| 		popup.add(exitMenuItem); | ||||
|  | ||||
| 		trayIcon.setPopupMenu(popup); | ||||
|  | ||||
| 		// Only display messages if the chat window is not focused | ||||
| 		focusTarget.addWindowFocusListener(new WindowAdapter() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void windowGainedFocus(WindowEvent e) { | ||||
| 				displayMessages = false; | ||||
| 			} | ||||
|  | ||||
| 			@Override | ||||
| 			public void windowLostFocus(WindowEvent e) { | ||||
| 				displayMessages = true; | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		// Start processing message events | ||||
| 		EventBus.getInstance().register(this); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Makes this {@link StatusTrayIcon} appear in the system tray. | ||||
| 	 * | ||||
| 	 * @throws EnvoyException if the status icon could not be attaches to the system | ||||
| 	 *                        tray for system-internal reasons | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void show() throws EnvoyException { | ||||
| 		try { | ||||
| 			SystemTray.getSystemTray().add(trayIcon); | ||||
| 		} catch (AWTException e) { | ||||
| 			throw new EnvoyException("Could not attach Envoy tray icon to system tray.", e); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Notifies the user of a message by displaying a pop-up every time a new | ||||
| 	 * message is received. | ||||
| 	 * | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void handle(Event<?> event) { | ||||
| 		System.out.println("Message received. Displaying message: " + displayMessages); | ||||
| 		if (displayMessages) | ||||
| 			trayIcon.displayMessage("New message received", ((MessageCreationEvent) event).get().getContent().get(0).getText(), MessageType.INFO); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * The {@link StatusTrayIcon} only reacts to {@link MessageCreationEvent} | ||||
| 	 * instances which signify newly received messages. | ||||
| 	 * | ||||
| 	 * @return A set with the single element {@code MessageCreationEvent.class} | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public Set<Class<? extends Event<?>>> supports() { | ||||
| 		Set<Class<? extends Event<?>>> supportedEvents = new HashSet<>(); | ||||
| 		supportedEvents.add(MessageCreationEvent.class); | ||||
| 		return supportedEvents; | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 delvh
					delvh