Merge pull request #36 from informatik-ag-ngl/f/message_notification
Implemented event system and status tray icon
This commit is contained in:
		@@ -1,8 +1,107 @@
 | 
				
			|||||||
eclipse.preferences.version=1
 | 
					eclipse.preferences.version=1
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 | 
				
			||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 | 
					org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
 | 
				
			||||||
org.eclipse.jdt.core.compiler.compliance=1.8
 | 
					org.eclipse.jdt.core.compiler.compliance=1.8
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.APILeak=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.deadCode=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.deprecation=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
 | 
				
			||||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
 | 
					org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
 | 
				
			||||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 | 
					org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nullReference=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
 | 
				
			||||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
 | 
					org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedImport=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 | 
				
			||||||
 | 
					org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 | 
				
			||||||
org.eclipse.jdt.core.compiler.release=disabled
 | 
					org.eclipse.jdt.core.compiler.release=disabled
 | 
				
			||||||
org.eclipse.jdt.core.compiler.source=1.8
 | 
					org.eclipse.jdt.core.compiler.source=1.8
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,8 @@ import java.util.logging.Logger;
 | 
				
			|||||||
import javax.xml.datatype.DatatypeConfigurationException;
 | 
					import javax.xml.datatype.DatatypeConfigurationException;
 | 
				
			||||||
import javax.xml.datatype.DatatypeFactory;
 | 
					import javax.xml.datatype.DatatypeFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import envoy.client.event.EventBus;
 | 
				
			||||||
 | 
					import envoy.client.event.MessageCreationEvent;
 | 
				
			||||||
import envoy.exception.EnvoyException;
 | 
					import envoy.exception.EnvoyException;
 | 
				
			||||||
import envoy.schema.Message;
 | 
					import envoy.schema.Message;
 | 
				
			||||||
import envoy.schema.Message.Metadata.MessageState;
 | 
					import envoy.schema.Message.Metadata.MessageState;
 | 
				
			||||||
@@ -38,12 +40,12 @@ public class LocalDB {
 | 
				
			|||||||
	private ObjectFactory	objectFactory	= new ObjectFactory();
 | 
						private ObjectFactory	objectFactory	= new ObjectFactory();
 | 
				
			||||||
	private DatatypeFactory	datatypeFactory;
 | 
						private DatatypeFactory	datatypeFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName());
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	private Sync	unreadMessagesSync	= objectFactory.createSync();
 | 
						private Sync	unreadMessagesSync	= objectFactory.createSync();
 | 
				
			||||||
	private Sync	sync				= objectFactory.createSync();
 | 
						private Sync	sync				= objectFactory.createSync();
 | 
				
			||||||
	private Sync	readMessages		= objectFactory.createSync();
 | 
						private Sync	readMessages		= objectFactory.createSync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Constructs an empty local database.
 | 
						 * Constructs an empty local database.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
@@ -116,7 +118,7 @@ public class LocalDB {
 | 
				
			|||||||
	 * Creates a {@link Message} object serializable to XML.
 | 
						 * Creates a {@link Message} object serializable to XML.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @param textContent The content (text) of the message
 | 
						 * @param textContent The content (text) of the message
 | 
				
			||||||
	 * @param recipient The recipient of the message
 | 
						 * @param recipient   The recipient of the message
 | 
				
			||||||
	 * @return prepared {@link Message} object
 | 
						 * @return prepared {@link Message} object
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
@@ -138,6 +140,13 @@ public class LocalDB {
 | 
				
			|||||||
		return message;
 | 
							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
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	public Sync fillSync(long userId) {
 | 
						public Sync fillSync(long userId) {
 | 
				
			||||||
		addWaitingMessagesToSync();
 | 
							addWaitingMessagesToSync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,86 +157,73 @@ public class LocalDB {
 | 
				
			|||||||
		return sync;
 | 
							return sync;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Applies the changes carried by a {@link Sync} object to the local database
 | 
				
			||||||
 | 
						 * 
 | 
				
			||||||
 | 
						 * @param returnSync the {@link Sync} object to apply
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	public void applySync(Sync returnSync) {
 | 
						public void applySync(Sync returnSync) {
 | 
				
			||||||
		for (int i = 0; i < returnSync.getMessages().size(); i++) {
 | 
							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
 | 
								// The message has an ID
 | 
				
			||||||
					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.RECEIVED) {
 | 
								if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0) {
 | 
				
			||||||
				// Update Messages in localDB to state RECEIVED
 | 
					
 | 
				
			||||||
				for (int j = 0; j < getChats().size(); j++) {
 | 
									// Messages are processes differently corresponding to their state
 | 
				
			||||||
					if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) {
 | 
									switch (returnSync.getMessages().get(i).getMetadata().getState()) {
 | 
				
			||||||
						for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) {
 | 
										case SENT:
 | 
				
			||||||
							if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages()
 | 
											// Update previously waiting and now sent messages that were assigned an ID by
 | 
				
			||||||
								.get(i)
 | 
											// the server
 | 
				
			||||||
								.getMetadata()
 | 
											sync.getMessages().get(i).getMetadata().setMessageId(returnSync.getMessages().get(i).getMetadata().getMessageId());
 | 
				
			||||||
								.getMessageId()) {
 | 
											sync.getMessages().get(i).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState());
 | 
				
			||||||
								// Update Message in LocalDB
 | 
											break;
 | 
				
			||||||
								getChats().get(j).getModel().get(k).getMetadata().setState(returnSync.getMessages().get(j).getMetadata().getState());
 | 
										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());
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
											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.");
 | 
				
			||||||
			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0
 | 
											for (Chat chat : getChats())
 | 
				
			||||||
					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.READ) {
 | 
												if (chat.getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) {
 | 
				
			||||||
				// Update local Messages to state READ
 | 
													logger.info("Chat with: " + chat.getRecipient().getID() + "was selected.");
 | 
				
			||||||
				logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId()
 | 
													for (int k = 0; k < chat.getModel().getSize(); k++)
 | 
				
			||||||
						+ "was initialized to be set to READ in localDB.");
 | 
														if (chat.getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages()
 | 
				
			||||||
				for (int j = 0; j < getChats().size(); j++) {
 | 
															.get(i)
 | 
				
			||||||
					if (getChats().get(j)
 | 
															.getMetadata()
 | 
				
			||||||
						.getRecipient()
 | 
															.getMessageId()) {
 | 
				
			||||||
						.getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) {
 | 
															logger.info("Message with ID: " + chat.getModel().get(k).getMetadata().getMessageId() + "was selected.");
 | 
				
			||||||
						logger.info("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected.");
 | 
															chat.getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState());
 | 
				
			||||||
						for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) {
 | 
															logger.info("Message State is now: " + chat.getModel().get(k).getMetadata().getState());
 | 
				
			||||||
							if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages()
 | 
														}
 | 
				
			||||||
								.get(i)
 | 
					 | 
				
			||||||
								.getMetadata()
 | 
					 | 
				
			||||||
								.getMessageId()) {
 | 
					 | 
				
			||||||
								logger.info("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.info("Message State is now: "
 | 
					 | 
				
			||||||
										+ getChats().get(j).getModel().get(k).getMetadata().getState().toString());
 | 
					 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											break;
 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Updating UserStatus of all users in LocalDB
 | 
							// Updating UserStatus of all users in LocalDB
 | 
				
			||||||
		for (int j = 0; j < returnSync.getUsers().size(); j++) {
 | 
							for (User user : returnSync.getUsers())
 | 
				
			||||||
			for (int k = 0; k < getChats().size(); k++) {
 | 
								for (Chat chat : getChats())
 | 
				
			||||||
				if (getChats().get(k).getRecipient().getID() == returnSync.getUsers().get(j).getID()) {
 | 
									if (user.getID() == chat.getRecipient().getID()) {
 | 
				
			||||||
 | 
										chat.getRecipient().setStatus(user.getStatus());
 | 
				
			||||||
					getChats().get(k).getRecipient().setStatus(returnSync.getUsers().get(j).getStatus());
 | 
										logger.info(chat.getRecipient().getStatus().toString());
 | 
				
			||||||
					logger.info(getChats().get(k).getRecipient().getStatus().toString());
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sync.getMessages().clear();
 | 
							sync.getMessages().clear();
 | 
				
			||||||
		sync.getUsers().clear();
 | 
							sync.getUsers().clear();
 | 
				
			||||||
@@ -241,11 +237,11 @@ public class LocalDB {
 | 
				
			|||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void addUnreadMessagesToLocalDB() {
 | 
						public void addUnreadMessagesToLocalDB() {
 | 
				
			||||||
		Sync unreadMessages = unreadMessagesSync;
 | 
							for (Message message : unreadMessagesSync.getMessages())
 | 
				
			||||||
		for (int i = 0; i < unreadMessages.getMessages().size(); i++)
 | 
								for (Chat chat : getChats())
 | 
				
			||||||
			for (int j = 0; j < getChats().size(); j++)
 | 
									if (message.getMetadata().getSender() == chat.getRecipient().getID()) {
 | 
				
			||||||
				if (getChats().get(j).getRecipient().getID() == unreadMessages.getMessages().get(i).getMetadata().getSender()) {
 | 
										chat.appendMessage(message);
 | 
				
			||||||
					getChats().get(j).appendMessage(unreadMessages.getMessages().get(i));
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -277,7 +273,6 @@ public class LocalDB {
 | 
				
			|||||||
		for (Chat chat : getChats())
 | 
							for (Chat chat : getChats())
 | 
				
			||||||
			for (int i = 0; i < chat.getModel().size(); i++)
 | 
								for (int i = 0; i < chat.getModel().size(); i++)
 | 
				
			||||||
				if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) {
 | 
									if (chat.getModel().get(i).getMetadata().getState() == MessageState.WAITING) {
 | 
				
			||||||
					// addMessageToSync(localDB.getChats().get(i).getModel().get(j));
 | 
					 | 
				
			||||||
					logger.info("Got Waiting Message");
 | 
										logger.info("Got Waiting Message");
 | 
				
			||||||
					sync.getMessages().add(chat.getModel().get(i));
 | 
										sync.getMessages().add(chat.getModel().get(i));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -291,8 +286,8 @@ public class LocalDB {
 | 
				
			|||||||
	public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); }
 | 
						public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return all saves {@link Chat} objects that list the client user as the
 | 
						 * @return all saved {@link Chat} objects that list the client user as the
 | 
				
			||||||
	 *         client
 | 
						 *         sender
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 **/
 | 
						 **/
 | 
				
			||||||
	public List<Chat> getChats() { return chats; }
 | 
						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); }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -125,13 +125,11 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			@Override
 | 
								@Override
 | 
				
			||||||
			public void keyReleased(KeyEvent e) {
 | 
								public void keyReleased(KeyEvent e) {
 | 
				
			||||||
 | 
									if (e.getKeyCode() == KeyEvent.VK_ENTER
 | 
				
			||||||
				if (e.getKeyCode() == KeyEvent.VK_ENTER && ((SettingsScreen.enterToSend && e.getModifiersEx() == 0)
 | 
											&& ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) {
 | 
				
			||||||
						|| (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					postMessage(messageList);
 | 
										postMessage(messageList);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		// Checks for changed Message
 | 
							// Checks for changed Message
 | 
				
			||||||
@@ -219,11 +217,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
				final User			user				= selectedUserList.getSelectedValue();
 | 
									final User			user				= selectedUserList.getSelectedValue();
 | 
				
			||||||
				client.setRecipient(user);
 | 
									client.setRecipient(user);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				currentChat = localDB.getChats()
 | 
									currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get();
 | 
				
			||||||
					.stream()
 | 
					 | 
				
			||||||
					.filter(chat -> chat.getRecipient().getID() == user.getID())
 | 
					 | 
				
			||||||
					.findFirst()
 | 
					 | 
				
			||||||
					.get();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Set all unread messages in the chat to read
 | 
									// Set all unread messages in the chat to read
 | 
				
			||||||
				readCurrentChat();
 | 
									readCurrentChat();
 | 
				
			||||||
@@ -262,10 +256,8 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	private void postMessage(JList<Message> messageList) {
 | 
						private void postMessage(JList<Message> messageList) {
 | 
				
			||||||
		if (!client.hasRecipient()) {
 | 
							if (!client.hasRecipient()) {
 | 
				
			||||||
			JOptionPane.showMessageDialog(this,
 | 
								JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE);
 | 
				
			||||||
					"Please select a recipient!",
 | 
								return;
 | 
				
			||||||
					"Cannot send message",
 | 
					 | 
				
			||||||
					JOptionPane.INFORMATION_MESSAGE);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!messageEnterTextArea.getText().isEmpty()) try {
 | 
							if (!messageEnterTextArea.getText().isEmpty()) try {
 | 
				
			||||||
@@ -321,8 +313,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
			new Thread(() -> {
 | 
								new Thread(() -> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Synchronize
 | 
									// Synchronize
 | 
				
			||||||
				localDB.applySync(
 | 
									localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID())));
 | 
				
			||||||
						client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID())));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Process unread messages
 | 
									// Process unread messages
 | 
				
			||||||
				localDB.addUnreadMessagesToLocalDB();
 | 
									localDB.addUnreadMessagesToLocalDB();
 | 
				
			||||||
@@ -332,8 +323,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
				readCurrentChat();
 | 
									readCurrentChat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Update UI
 | 
									// Update UI
 | 
				
			||||||
				SwingUtilities
 | 
									SwingUtilities.invokeLater(() -> { updateUserStates(); contentPane.revalidate(); contentPane.repaint(); });
 | 
				
			||||||
					.invokeLater(() -> { updateUserStates(); contentPane.revalidate(); contentPane.repaint(); });
 | 
					 | 
				
			||||||
			}).start();
 | 
								}).start();
 | 
				
			||||||
		}).start();
 | 
							}).start();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,8 +72,9 @@ public class Startup {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		EventQueue.invokeLater(() -> {
 | 
							EventQueue.invokeLater(() -> {
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				ChatWindow frame = new ChatWindow(client, localDB);
 | 
									ChatWindow chatWindow = new ChatWindow(client, localDB);
 | 
				
			||||||
				frame.setVisible(true);
 | 
									new StatusTrayIcon(chatWindow).show();
 | 
				
			||||||
 | 
									chatWindow.setVisible(true);
 | 
				
			||||||
			} catch (Exception e) {
 | 
								} catch (Exception e) {
 | 
				
			||||||
				e.printStackTrace();
 | 
									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;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/envoy_logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/envoy_logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 8.0 KiB  | 
		Reference in New Issue
	
	Block a user