Merge branch 'develop' into f/logger

This commit is contained in:
delvh 2019-12-20 12:30:53 +01:00 committed by GitHub
commit e8d15be940
17 changed files with 877 additions and 484 deletions

View File

@ -1,6 +1,7 @@
package envoy.client; package envoy.client;
import java.util.logging.Logger; import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity; import javax.ws.rs.client.Entity;
@ -10,7 +11,7 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller; import javax.xml.bind.Marshaller;
import envoy.client.util.EnvoyLog; import envoy.exception.EnvoyException;
import envoy.schema.ObjectFactory; import envoy.schema.ObjectFactory;
import envoy.schema.Sync; import envoy.schema.Sync;
import envoy.schema.User; import envoy.schema.User;
@ -30,14 +31,28 @@ public class Client {
private ObjectFactory objectFactory = new ObjectFactory(); private ObjectFactory objectFactory = new ObjectFactory();
private Config config; private Config config;
private User sender, recipient; private User sender, recipient;
private boolean online = false;
private static final Logger logger = EnvoyLog.getLogger(Client.class.getSimpleName()); /**
* Initializes the client. At this state, the client user has yet to be
* initialized, which can be done by calling {@link Client#onlineInit(String).
*
* @param config The {@link Config} instance to use in this client
* @since Envoy v0.2-alpha
*/
public Client(Config config) { this.config = config; }
public Client(Config config, String username) { /**
this.config = config; * Enters the online mode by acquiring a user ID from the server.
sender = getUser(username); *
* @param userName the name of the client user
logger.info("ID: " + sender.getID()); * @throws EnvoyException if the online mode could not be entered or the request
* failed for some other reason
* @since Envoy v0.2-alpha
*/
public void onlineInit(String userName) throws EnvoyException {
sender = getUser(userName);
online = true;
} }
private <T, R> R post(String uri, T body, Class<R> responseBodyClass) { private <T, R> R post(String uri, T body, Class<R> responseBodyClass) {
@ -49,26 +64,26 @@ public class Client {
client.close(); client.close();
return responseBody; return responseBody;
} }
/** /**
* Returns a {@link Sync} with all users on the server. * @return a {@code Map<String, User>} of all users on the server with their
* * user names as keys
* @return Sync - List of all users on the server. * @since Envoy v0.2-alpha
* @since Envoy v0.1-alpha
*/ */
public Sync getUsersListXml() { public Map<String, User> getUsers() {
Sync sendSync = objectFactory.createSync(); Sync sendSync = objectFactory.createSync();
User user = objectFactory.createUser(); User user = objectFactory.createUser();
user.setID(-1); user.setID(-1);
sendSync.getUsers().add(user); sendSync.getUsers().add(user);
Sync returnSendSync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), Sync returnSync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0),
sendSync, sendSync,
Sync.class); Sync.class);
return returnSendSync;
Map<String, User> users = new HashMap<>();
returnSync.getUsers().forEach(u -> users.put(u.getName(), u));
return users;
} }
/** /**
@ -76,27 +91,29 @@ public class Client {
* *
* @param name - the name of the {@link User} * @param name - the name of the {@link User}
* @return a {@link User} with the specified name * @return a {@link User} with the specified name
* @throws EnvoyException if the server does not return the requested ID
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
private User getUser(String name) { private User getUser(String name) throws EnvoyException {
// Create a sync with only a user with the requested name
Sync senderSync = objectFactory.createSync(); Sync senderSync = objectFactory.createSync();
User user = objectFactory.createUser(); User user = objectFactory.createUser();
user.setName(name); user.setName(name);
senderSync.getUsers().add(user); senderSync.getUsers().add(user);
Sync returnSenderSync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), try {
senderSync, Sync sync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0),
Sync.class); senderSync,
Sync.class);
User returnSender = objectFactory.createUser(); // Expecting a single user with an ID
if (sync.getUsers().size() == 1) {
if (returnSenderSync.getUsers().size() == 1) { online = true;
returnSender = returnSenderSync.getUsers().get(0); return sync.getUsers().get(0);
} else { } else throw new EnvoyException("Unexpected response from Envoy Server");
logger.warning("ERROR exiting..."); } catch (Exception e) {
throw new EnvoyException("Could not connect to server", e);
} }
return returnSender;
} }
/** /**
@ -134,9 +151,12 @@ public class Client {
* @param sync the sync object (yet to be converted from java class to * @param sync the sync object (yet to be converted from java class to
* sync.xml) * sync.xml)
* @return a returnSync.xml file * @return a returnSync.xml file
* @throws EnvoyException if the client is not in online mode
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public Sync sendSync(long userId, Sync sync) { public Sync sendSync(long userId, Sync sync) throws EnvoyException {
if(!isOnline())
throw new EnvoyException("Client is not in online mode");
// Print sync XML to console // Print sync XML to console
JAXBContext jc; JAXBContext jc;
try { try {
@ -158,6 +178,14 @@ public class Client {
*/ */
public User getSender() { return sender; } public User getSender() { return sender; }
/**
* Sets the client user which is used to send messages.
*
* @param sender the client user to set
* @since Envoy v0.2-alpha
*/
public void setSender(User sender) { this.sender = sender; }
/** /**
* @return the current recipient of the current chat. * @return the current recipient of the current chat.
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
@ -167,7 +195,7 @@ public class Client {
/** /**
* Sets the recipient. * Sets the recipient.
* *
* @param recipient - the recipient to set * @param recipient the recipient to set
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void setRecipient(User recipient) { this.recipient = recipient; } public void setRecipient(User recipient) { this.recipient = recipient; }
@ -177,4 +205,10 @@ public class Client {
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public boolean hasRecipient() { return recipient != null; } public boolean hasRecipient() { return recipient != null; }
/**
* @return {@code true} if a connection to the server could be established
* @since Envoy v0.2-alpha
*/
public boolean isOnline() { return online; }
} }

View File

@ -3,6 +3,8 @@ package envoy.client;
import java.io.File; import java.io.File;
import java.util.Properties; import java.util.Properties;
import envoy.exception.EnvoyException;
/** /**
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>Config.java</strong><br> * File: <strong>Config.java</strong><br>
@ -29,17 +31,26 @@ public class Config {
/** /**
* Defaults to the {@code client.properties} file for information. * Defaults to the {@code client.properties} file for information.
* This file contains information about
* the server and port, as well as the path to the local
* database and the synchronization timeout
* *
* @param properties a {@link Properties} object containing information about * @throws EnvoyException if the {@code client.properties} file could not be
* the server and port, as well as the path to the local * loaded
* database and the synchronization timeout
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void load(Properties properties) { public void load() throws EnvoyException {
if (properties.containsKey("server")) server = properties.getProperty("server"); ClassLoader loader = getClass().getClassLoader();
if (properties.containsKey("port")) port = Integer.parseInt(properties.getProperty("port")); try {
localDB = new File(properties.getProperty("localDB", ".\\localDB")); Properties properties = new Properties();
syncTimeout = Integer.parseInt(properties.getProperty("syncTimeout", "1000")); properties.load(loader.getResourceAsStream("client.properties"));
if (properties.containsKey("server")) server = properties.getProperty("server");
if (properties.containsKey("port")) port = Integer.parseInt(properties.getProperty("port"));
localDB = new File(properties.getProperty("localDB", ".\\localDB"));
syncTimeout = Integer.parseInt(properties.getProperty("syncTimeout", "1000"));
} catch (Exception e) {
throw new EnvoyException("Failed to load client.properties", e);
}
} }
/** /**
@ -47,9 +58,10 @@ public class Config {
* -s, --port / -p and --localDB / -db. * -s, --port / -p and --localDB / -db.
* *
* @param args the command line arguments to parse * @param args the command line arguments to parse
* @throws EnvoyException if the command line arguments contain an unknown token
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void load(String[] args) { public void load(String[] args) throws EnvoyException {
for (int i = 0; i < args.length; i++) for (int i = 0; i < args.length; i++)
switch (args[i]) { switch (args[i]) {
case "--server": case "--server":
@ -64,6 +76,8 @@ public class Config {
case "-db": case "-db":
localDB = new File(args[++i]); localDB = new File(args[++i]);
break; break;
default:
throw new EnvoyException("Unknown token " + args[i] + " found");
} }
} }

View File

@ -8,7 +8,9 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConfigurationException;
@ -35,9 +37,11 @@ import envoy.schema.User;
*/ */
public class LocalDB { public class LocalDB {
private File localDB; private File localDBDir, localDBFile, usersFile;
private User sender; private User user;
private List<Chat> chats = new ArrayList<>(); private Map<String, User> users = new HashMap<>();
private List<Chat> chats = new ArrayList<>();
private ObjectFactory objectFactory = new ObjectFactory(); private ObjectFactory objectFactory = new ObjectFactory();
private DatatypeFactory datatypeFactory; private DatatypeFactory datatypeFactory;
@ -45,67 +49,94 @@ public class LocalDB {
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 = EnvoyLog.getLogger(LocalDB.class.getSimpleName()); private static final Logger logger = EnvoyLog.getLogger(LocalDB.class.getSimpleName());
/** /**
* Constructs an empty local database. * Constructs an empty local database. To serialize any chats to the file
* system, call {@link LocalDB#initializeDBFile(File)}.
* *
* @param sender the user that is logged in with this client * @param localDBDir the directory in which to store users and chats
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public LocalDB(User sender) { public LocalDB(File localDBDir) throws IOException {
this.sender = sender; this.localDBDir = localDBDir;
try { try {
datatypeFactory = DatatypeFactory.newInstance(); datatypeFactory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) { } catch (DatatypeConfigurationException e) {
e.printStackTrace(); e.printStackTrace();
} }
// Initialize local database directory
if (localDBDir.exists() && !localDBDir.isDirectory())
throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath()));
usersFile = new File(localDBDir, "users.db");
} }
/** /**
* Initializes the local database and fills it with values * Creates a database file for a user-specific list of chats.
* if the user has already sent or received messages.
* *
* @param localDBDir the directory where we wish to save/load the database from. * @throws NullPointerException if the client user is not yet specified
* @throws EnvoyException if the directory selected is not an actual directory.
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void initializeDBFile(File localDBDir) throws EnvoyException { public void initializeDBFile() {
if (localDBDir.exists() && !localDBDir.isDirectory()) if (user == null) throw new NullPointerException("Client user is null");
throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); localDBFile = new File(localDBDir, user.getID() + ".db");
localDB = new File(localDBDir, sender.getID() + ".db");
if (localDB.exists()) loadFromLocalDB();
} }
/** /**
* Saves the database into a file for future use. * Stores all users to the local database. If the client user is specified, the
* chats related to this user are stored as well.
* *
* @throws IOException if something went wrong during saving * @throws IOException if something went wrong during saving
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void saveToLocalDB() throws IOException { public void save() throws IOException {
localDB.getParentFile().mkdirs(); // Save users
localDB.createNewFile(); write(usersFile, users);
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) {
out.writeObject(chats); // Save chats
} catch (IOException ex) { write(localDBFile, chats);
throw ex;
}
} }
/**
* Loads all users that are stored in the local database.
*
* @throws EnvoyException if the loading process failed
* @since Envoy v0.2-alpha
*/
@SuppressWarnings("unchecked")
public void loadUsers() throws EnvoyException { users = read(usersFile, HashMap.class); }
/** /**
* Loads all chats saved by Envoy for the client user. * Loads all chats saved by Envoy for the client user.
* *
* @throws EnvoyException if something fails while loading. * @throws EnvoyException if the loading process failed
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void loadFromLocalDB() throws EnvoyException { public void loadChats() throws EnvoyException { chats = read(localDBFile, ArrayList.class); }
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) {
Object obj = in.readObject(); private <T> T read(File file, Class<T> serializedClass) throws EnvoyException {
if (obj instanceof ArrayList<?>) chats = (ArrayList<Chat>) obj; if (file == null) throw new NullPointerException("File is null");
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(file))) {
return serializedClass.cast(in.readObject());
} catch (ClassNotFoundException | IOException e) { } catch (ClassNotFoundException | IOException e) {
throw new EnvoyException(e); throw new EnvoyException("Could not load serialized object", e);
}
}
private <T> void write(File file, T obj) throws IOException {
if (file == null) throw new NullPointerException("File is null");
if (obj == null) throw new NullPointerException("Object to serialize is null");
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
out.writeObject(obj);
} catch (IOException e) {
throw e;
} }
} }
@ -119,7 +150,7 @@ public class LocalDB {
*/ */
public Message createMessage(String textContent, long recipientID) { public Message createMessage(String textContent, long recipientID) {
Message.Metadata metaData = objectFactory.createMessageMetadata(); Message.Metadata metaData = objectFactory.createMessageMetadata();
metaData.setSender(sender.getID()); metaData.setSender(user.getID());
metaData.setRecipient(recipientID); metaData.setRecipient(recipientID);
metaData.setState(MessageState.WAITING); metaData.setState(MessageState.WAITING);
metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString()));
@ -135,13 +166,13 @@ public class LocalDB {
return message; return message;
} }
/** /**
* Creates a {@link Sync} object filled with the changes that occurred to the * Creates a {@link Sync} object filled with the changes that occurred to the
* local database since the last synchronization. * local database since the last synchronization.
* *
* @param userId the ID of the user that is synchronized by this client * @param userId the ID of the user that is synchronized by this client
* @return {@link Sync} object filled with the current changes * @return {@link Sync} object filled with the current changes
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public Sync fillSync(long userId) { public Sync fillSync(long userId) {
addWaitingMessagesToSync(); addWaitingMessagesToSync();
@ -157,7 +188,7 @@ public class LocalDB {
* Applies the changes carried by a {@link Sync} object to the local database * Applies the changes carried by a {@link Sync} object to the local database
* *
* @param returnSync the {@link Sync} object to apply * @param returnSync the {@link Sync} object to apply
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
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++) {
@ -281,6 +312,17 @@ public class LocalDB {
*/ */
public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); } public void clearUnreadMessagesSync() { unreadMessagesSync.getMessages().clear(); }
/**
* @return a {@code Map<String, User>} of all users stored locally with their user names as keys
* @since Envoy v0.2-alpha
*/
public Map<String, User> getUsers() { return users; }
/**
* @param users the users to set
*/
public void setUsers(Map<String, User> users) { this.users = users; }
/** /**
* @return all saved {@link Chat} objects that list the client user as the * @return all saved {@link Chat} objects that list the client user as the
* sender * sender
@ -289,8 +331,19 @@ public class LocalDB {
public List<Chat> getChats() { return chats; } public List<Chat> getChats() { return chats; }
/** /**
* @return the {@link User} who initialized the local database * @param chats the chats to set
* @since Envoy v0.1-alpha
*/ */
public User getUser() { return sender; } public void setChats(List<Chat> chats) { this.chats = chats; }
/**
* @return the {@link User} who initialized the local database
* @since Envoy v0.2-alpha
*/
public User getUser() { return user; }
/**
* @param user the user to set
* @since Envoy v0.2-alpha
*/
public void setUser(User user) { this.user = user; }
} }

View File

@ -26,8 +26,6 @@ import envoy.client.ui.Theme;
public class Settings { public class Settings {
// Actual settings accessible by the rest of the application // Actual settings accessible by the rest of the application
private String username;
private String email;
private boolean enterToSend = true; private boolean enterToSend = true;
private Map<String, Theme> themes; private Map<String, Theme> themes;
private String currentTheme; private String currentTheme;
@ -65,8 +63,6 @@ public class Settings {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void load() { private void load() {
setUsername(prefs.get("username", ""));
setEmail(prefs.get("email", ""));
setEnterToSend(prefs.getBoolean("enterToSend", true)); setEnterToSend(prefs.getBoolean("enterToSend", true));
setCurrentTheme(prefs.get("theme", "dark")); setCurrentTheme(prefs.get("theme", "dark"));
@ -90,14 +86,12 @@ public class Settings {
} }
/** /**
* updates prefs when save button is clicked * Updates the preferences when the save button is clicked.
* *
* @throws IOException if saving was not successful * @throws IOException if saving was not successful
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public void save() throws IOException { public void save() throws IOException {
prefs.put("username", getUsername());
prefs.put("email", getEmail());
prefs.put("theme", currentTheme); prefs.put("theme", currentTheme);
prefs.putBoolean("enterToSend", isEnterToSend()); prefs.putBoolean("enterToSend", isEnterToSend());
@ -116,7 +110,7 @@ public class Settings {
*/ */
public void addNewThemeToMap(Theme theme) { public void addNewThemeToMap(Theme theme) {
settings.getThemes().put(theme.getThemeName(), theme); settings.getThemes().put(theme.getThemeName(), theme);
currentTheme = theme.getThemeName(); // currentTheme = theme.getThemeName();
} }
/** /**
@ -133,30 +127,6 @@ public class Settings {
*/ */
public void setCurrentTheme(String themeName) { currentTheme = themeName; } public void setCurrentTheme(String themeName) { currentTheme = themeName; }
/**
* @return the user name
* @since Envoy v0.2-alpha
*/
public String getUsername() { return username; }
/**
* @param username the user name to set
* @since Envoy v0.2-alpha
*/
public void setUsername(String username) { this.username = username; }
/**
* @return the email associated with that user.
* @since Envoy v0.2-alpha
*/
public String getEmail() { return email; }
/**
* @param email the email to set
* @since Envoy v0.2-alpha
*/
public void setEmail(String email) { this.email = email; }
/** /**
* @return true, if "enter" suffices to send a message, else it has to be "ctrl" * @return true, if "enter" suffices to send a message, else it has to be "ctrl"
* + "enter" * + "enter"

View File

@ -1,10 +1,10 @@
package envoy.client.event; package envoy.client.event;
/** /**
* Project: <strong>envoy-clientChess</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>Event.javaEvent.java</strong><br> * File: <strong>Event.java</strong><br>
* Created: <strong>04.12.2019</strong><br> * Created: <strong>04.12.2019</strong><br>
* *
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
* @param <T> the type of our Event * @param <T> the type of our Event
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha

View File

@ -1,8 +1,9 @@
package envoy.client.event; package envoy.client.event;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* This class handles events by allowing {@link EventHandler} object to register * This class handles events by allowing {@link EventHandler} object to register
@ -10,11 +11,12 @@ import java.util.List;
* bus.<br> * bus.<br>
* <br> * <br>
* The event bus is a singleton and can be used across the entire application to * The event bus is a singleton and can be used across the entire application to
* guarantee the propagation of events. * guarantee the propagation of events.<br>
*
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>EventBus.java</strong><br> * File: <strong>EventBus.java</strong><br>
* Created: <strong>04.12.2019</strong><br> * Created: <strong>04.12.2019</strong><br>
* *
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
@ -22,9 +24,10 @@ public class EventBus {
/** /**
* Contains all {@link EventHandler} instances registered at this * Contains all {@link EventHandler} instances registered at this
* {@link EventBus}. * {@link EventBus} as values mapped to by their supported {@link Event}
* classes.
*/ */
private List<EventHandler> handlers = new ArrayList<>(); private Map<Class<? extends Event<?>>, List<EventHandler>> handlers = new HashMap<>();
/** /**
* The singleton instance of this {@link EventBus} that is used across the * The singleton instance of this {@link EventBus} that is used across the
@ -46,26 +49,33 @@ public class EventBus {
public static EventBus getInstance() { return eventBus; } public static EventBus getInstance() { return eventBus; }
/** /**
* Registers a list of {@link EventHandler} objects to be notified when a * Registers an {@link EventHandler} to be notified when a
* {@link Event} is dispatched that they are subscribed to. * {@link Event} of a certain type is dispatched.
* *
* @param handlers the {@link EventHandler} objects to register * @param eventClass the class which the {@link EventHandler} is subscribed to
* @param handler the {@link EventHandler} to register
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public void register(EventHandler... handlers) { this.handlers.addAll(Arrays.asList(handlers)); } public void register(Class<? extends Event<?>> eventClass, EventHandler handler) {
if (!handlers.containsKey(eventClass)) handlers.put(eventClass, new ArrayList<>());
handlers.get(eventClass).add(handler);
}
/** /**
* Dispatches a {@link Event} to every {@link EventHandler} subscribed to it. * Dispatches a {@link Event} to every {@link EventHandler} subscribed to it.
* *
* @param event the {@link Event} to dispatch * @param event the {@link Event} to dispatch
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public void dispatch(Event<?> event) { handlers.stream().filter(h -> h.supports().contains(event.getClass())).forEach(h -> h.handle(event)); } public void dispatch(Event<?> event) {
handlers.keySet().stream().filter(event.getClass()::isAssignableFrom).map(handlers::get).flatMap(List::stream).forEach(h -> h.handle(event));
}
/** /**
* @return a list of all {@link EventHandler} instances currently registered at * @return a map of all {@link EventHandler} instances currently registered at
* this {@link EventBus} * this {@link EventBus} with the {@link Event} classes they are
* subscribed to as keys
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public List<EventHandler> getHandlers() { return handlers; } public Map<Class<? extends Event<?>>, List<EventHandler>> getHandlers() { return handlers; }
} }

View File

@ -1,25 +1,18 @@
package envoy.client.event; package envoy.client.event;
import java.util.Set;
/** /**
* Project: <strong>envoy-clientChess</strong><br> * Project: <strong>envoy-clientChess</strong><br>
* File: <strong>EventHandler.javaEvent.java</strong><br> * File: <strong>EventHandler.javaEvent.java</strong><br>
* Created: <strong>04.12.2019</strong><br> * Created: <strong>04.12.2019</strong><br>
* *
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
*/ */
public interface EventHandler { public interface EventHandler {
/** /**
* Consumes an event dispatched by the event bus. * Consumes an event dispatched by the event bus.
* *
* @param event The event dispatched by the event bus, only of supported type * @param event The event dispatched by the event bus, only of supported type
*/ */
void handle(Event<?> event); void handle(Event<?> event);
/**
* @return A set of classes this class is supposed to handle in events
*/
Set<Class<? extends Event<?>>> supports();
} }

View File

@ -0,0 +1,20 @@
package envoy.client.event;
import envoy.client.ui.Theme;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>ThemeChangeEvent.java</strong><br>
* Created: <strong>15 Dec 2019</strong><br>
*
* @author Kai S. K. Engelbart
*/
public class ThemeChangeEvent implements Event<Theme> {
private final Theme theme;
public ThemeChangeEvent(Theme theme) { this.theme = theme; }
@Override
public Theme get() { return theme; }
}

View File

@ -15,13 +15,10 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane; import javax.swing.JTextPane;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@ -34,8 +31,10 @@ import envoy.client.Config;
import envoy.client.LocalDB; import envoy.client.LocalDB;
import envoy.client.Settings; import envoy.client.Settings;
import envoy.client.util.EnvoyLog; import envoy.client.util.EnvoyLog;
import envoy.client.event.EventBus;
import envoy.client.event.ThemeChangeEvent;
import envoy.schema.Message; import envoy.schema.Message;
import envoy.schema.Sync;
import envoy.schema.User; import envoy.schema.User;
/** /**
@ -52,20 +51,20 @@ public class ChatWindow extends JFrame {
private static final long serialVersionUID = 6865098428255463649L; private static final long serialVersionUID = 6865098428255463649L;
// user specific objects // User specific objects
private Client client; private Client client;
private LocalDB localDB; private LocalDB localDB;
// GUI components // GUI components
private JPanel contentPane = new JPanel(); private JPanel contentPane = new JPanel();
private JTextArea messageEnterTextArea = new JTextArea(); private PrimaryTextArea messageEnterTextArea = new PrimaryTextArea(space);
private JList<User> userList = new JList<>(); private JList<User> userList = new JList<>();
private Chat currentChat; private Chat currentChat;
private JList<Message> messageList = new JList<>(); private JList<Message> messageList = new JList<>();
private JScrollPane scrollPane = new JScrollPane(); private PrimaryScrollPane scrollPane = new PrimaryScrollPane();
private JTextPane textPane = new JTextPane(); private JTextPane textPane = new JTextPane();
// private JCheckBox jCbChangeMode; private PrimaryButton postButton = new PrimaryButton("Post");
private JButton postButton = new JButton("Post"); private PrimaryButton settingsButton = new PrimaryButton("Settings");
private JButton settingsButton = new JButton("Settings");
private static int space = 4; private static int space = 4;
@ -87,7 +86,7 @@ public class ChatWindow extends JFrame {
@Override @Override
public void windowClosing(WindowEvent evt) { public void windowClosing(WindowEvent evt) {
try { try {
localDB.saveToLocalDB(); localDB.save();
Settings.getInstance().save(); Settings.getInstance().save();
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); e1.printStackTrace();
@ -116,7 +115,6 @@ public class ChatWindow extends JFrame {
messageList.setBorder(new EmptyBorder(space, space, space, space)); messageList.setBorder(new EmptyBorder(space, space, space, space));
scrollPane.setViewportView(messageList); scrollPane.setViewportView(messageList);
scrollPane.setBorder(null);
GridBagConstraints gbc_scrollPane = new GridBagConstraints(); GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.fill = GridBagConstraints.BOTH; gbc_scrollPane.fill = GridBagConstraints.BOTH;
@ -138,12 +136,6 @@ public class ChatWindow extends JFrame {
} }
} }
}); });
// Checks for changed Message
messageEnterTextArea.setWrapStyleWord(true);
messageEnterTextArea.setLineWrap(true);
messageEnterTextArea.setBorder(null);
messageEnterTextArea.setFont(new Font("Arial", Font.PLAIN, 17));
messageEnterTextArea.setBorder(new EmptyBorder(space, space, space, space));
GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints(); GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints();
gbc_messageEnterTextfield.fill = GridBagConstraints.BOTH; gbc_messageEnterTextfield.fill = GridBagConstraints.BOTH;
@ -155,7 +147,6 @@ public class ChatWindow extends JFrame {
contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
// Post Button // Post Button
postButton.setBorderPainted(false);
GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints();
gbc_moveSelectionPostButton.fill = GridBagConstraints.BOTH; gbc_moveSelectionPostButton.fill = GridBagConstraints.BOTH;
@ -168,8 +159,6 @@ public class ChatWindow extends JFrame {
contentPane.add(postButton, gbc_moveSelectionPostButton); contentPane.add(postButton, gbc_moveSelectionPostButton);
// Settings Button // Settings Button
settingsButton.setBorderPainted(false);
GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints();
gbc_moveSelectionSettingsButton.fill = GridBagConstraints.BOTH; gbc_moveSelectionSettingsButton.fill = GridBagConstraints.BOTH;
@ -208,7 +197,6 @@ public class ChatWindow extends JFrame {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final JList<User> selectedUserList = (JList<User>) listSelectionEvent.getSource(); final JList<User> selectedUserList = (JList<User>) listSelectionEvent.getSource();
final User user = selectedUserList.getSelectedValue(); final User user = selectedUserList.getSelectedValue();
client.setRecipient(user);
currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get(); currentChat = localDB.getChats().stream().filter(chat -> chat.getRecipient().getID() == user.getID()).findFirst().get();
@ -219,6 +207,7 @@ public class ChatWindow extends JFrame {
textPane.setText(currentChat.getRecipient().getName()); textPane.setText(currentChat.getRecipient().getName());
messageList.setModel(currentChat.getModel()); messageList.setModel(currentChat.getModel());
scrollPane.setChatOpened(true);
contentPane.revalidate(); contentPane.revalidate();
} }
}); });
@ -233,25 +222,27 @@ public class ChatWindow extends JFrame {
gbc_userList.anchor = GridBagConstraints.PAGE_START; gbc_userList.anchor = GridBagConstraints.PAGE_START;
gbc_userList.insets = new Insets(space, space, space, space); gbc_userList.insets = new Insets(space, space, space, space);
changeChatWindowColors(Settings.getInstance().getCurrentTheme()); changeChatWindowColors(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
contentPane.add(userList, gbc_userList); contentPane.add(userList, gbc_userList);
contentPane.revalidate(); contentPane.revalidate();
EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> changeChatWindowColors((Theme) evt.get()));
loadUsersAndChats(); loadUsersAndChats();
startSyncThread(Config.getInstance().getSyncTimeout());
if (client.isOnline()) startSyncThread(Config.getInstance().getSyncTimeout());
contentPane.revalidate(); contentPane.revalidate();
} }
/** /**
* Used to immediately reload the ChatWindow when settings were changed. * Used to immediately reload the ChatWindow when settings were changed.
* @param themeName the name of the theme to change the colors into *
* @param theme the theme to change colors into
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public void changeChatWindowColors(String themeName) { private void changeChatWindowColors(Theme theme) {
Theme theme = Settings.getInstance().getThemes().get(themeName);
// contentPane // contentPane
contentPane.setBackground(theme.getBackgroundColor()); contentPane.setBackground(theme.getBackgroundColor());
contentPane.setForeground(theme.getUserNameColor()); contentPane.setForeground(theme.getUserNameColor());
@ -261,8 +252,9 @@ public class ChatWindow extends JFrame {
messageList.setForeground(theme.getMessageColorChat()); messageList.setForeground(theme.getMessageColorChat());
messageList.setBackground(theme.getCellColor()); messageList.setBackground(theme.getCellColor());
// scrollPane // scrollPane
scrollPane.setForeground(theme.getBackgroundColor()); scrollPane.applyTheme(theme);
scrollPane.setBackground(theme.getCellColor()); scrollPane.autoscroll();
// messageEnterTextArea // messageEnterTextArea
messageEnterTextArea.setCaretColor(theme.getTypingMessageColor()); messageEnterTextArea.setCaretColor(theme.getTypingMessageColor());
messageEnterTextArea.setForeground(theme.getTypingMessageColor()); messageEnterTextArea.setForeground(theme.getTypingMessageColor());
@ -316,9 +308,8 @@ public class ChatWindow extends JFrame {
*/ */
private void loadUsersAndChats() { private void loadUsersAndChats() {
new Thread(() -> { new Thread(() -> {
Sync users = client.getUsersListXml(); DefaultListModel<User> userListModel = new DefaultListModel<>();
DefaultListModel<User> userListModel = new DefaultListModel<>(); localDB.getUsers().values().forEach(user -> {
users.getUsers().forEach(user -> {
userListModel.addElement(user); userListModel.addElement(user);
// Check if user exists in local DB // Check if user exists in local DB
@ -342,7 +333,11 @@ public class ChatWindow extends JFrame {
new Thread(() -> { new Thread(() -> {
// Synchronize // Synchronize
localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID()))); try {
localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID())));
} catch (Exception e) {
logger.log(Level.SEVERE, "Could not perform sync", e);
}
// Process unread messages // Process unread messages
localDB.addUnreadMessagesToLocalDB(); localDB.addUnreadMessagesToLocalDB();

View File

@ -0,0 +1,63 @@
package envoy.client.ui;
import java.awt.Graphics;
import javax.swing.JButton;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>PrimaryButton.javaEvent.java</strong><br>
* Created: <strong>07.12.2019</strong><br>
*
* @author Kai S. K. Engelbart
* @author Maximilian K&auml;fer
* @since Envoy v0.2-alpha
*/
public class PrimaryButton extends JButton {
private static final long serialVersionUID = 3662266120667728364L;
private int arcSize;
/**
* Creates a primary button
*
* @param title the title of the button
* @since Envoy 0.2-alpha
*/
public PrimaryButton(String title) { this(title, 6); }
/**
* Creates a primary button
*
* @param title the title of the button
* @param arcSize the size of the arc used to draw the round button edges
* @since Envoy 0.2-alpha
*/
public PrimaryButton(String title, int arcSize) {
super(title);
setBorderPainted(false);
setFocusPainted(false);
setContentAreaFilled(false);
this.arcSize = arcSize;
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRoundRect(0, 0, getWidth(), getHeight(), arcSize, arcSize);
super.paintComponent(g);
}
/**
* @return the arcSize
* @since Envoy 0.2-alpha
*/
public int getArcSize() { return arcSize; }
/**
* @param arcSize the arcSize to set
* @since Envoy 0.2-alpha
*/
public void setArcSize(int arcSize) { this.arcSize = arcSize; }
}

View File

@ -0,0 +1,115 @@
package envoy.client.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.plaf.basic.BasicScrollBarUI;
import envoy.client.Settings;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>PrimaryScrollBar.java</strong><br>
* Created: <strong>14.12.2019</strong><br>
*
* @author Maximilian K&auml;fer
* @since Envoy v0.2-alpha
*/
public class PrimaryScrollBar extends BasicScrollBarUI {
private final Dimension d = new Dimension();
private final int arcSize;
private final Color scrollBarColor;
private final Color hoverColor;
private final Color draggingColor;
private final boolean isVertical;
/**
* Initializes a {@link PrimaryScrollBar} with a color scheme.
*
* @param arcSize the size of the arc used to draw the round scroll bar
* edges
* @param scrollBarColor the default color
* @param hoverColor the color while hovering
* @param draggingColor the color while dragging
* @param isVertical indicates whether this is a vertical
* {@link PrimaryScrollBar}
*/
public PrimaryScrollBar(int arcSize, Color scrollBarColor, Color hoverColor, Color draggingColor, boolean isVertical) {
this.arcSize = arcSize;
this.scrollBarColor = scrollBarColor;
this.hoverColor = hoverColor;
this.draggingColor = draggingColor;
this.isVertical = isVertical;
}
/**
* Initializes a {@link PrimaryScrollBar} using a color scheme specified in a
* {@link Theme}
*
* @param theme the {@link Theme} to be applied to this
* {@link PrimaryScrollBar}
* @param isVertical indicates whether this is a vertical
* {@link PrimaryScrollBar}
*/
public PrimaryScrollBar(Theme theme, boolean isVertical) {
this(5, theme.getInteractableBackgroundColor(), new Color(theme.getInteractableBackgroundColor().getRGB() - 50),
new Color(theme.getInteractableBackgroundColor().getRGB() + 170), isVertical);
}
@Override
protected JButton createDecreaseButton(int orientation) {
JButton button = new JButton();
button.setPreferredSize(d);
return button;
}
@Override
protected JButton createIncreaseButton(int orientation) {
JButton button = new JButton();
button.setPreferredSize(d);
return button;
}
@Override
protected void paintTrack(Graphics g, JComponent c, Rectangle r) {}
@Override
protected void paintThumb(Graphics g, JComponent c, Rectangle r) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color color;
JScrollBar sb = (JScrollBar) c;
if (!sb.isEnabled()) return;
if (isDragging) color = draggingColor;
else if (isThumbRollover()) color = hoverColor;
else color = scrollBarColor;
g2.setPaint(color);
if (isVertical) {
g2.fillRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
g2.setPaint(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getCellColor());
g2.drawRoundRect(r.x - 9, r.y, r.width, r.height, arcSize, arcSize);
} else {
g2.fillRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
g2.setPaint(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getCellColor());
g2.drawRoundRect(r.x, r.y + 9, r.width, r.height - 10, arcSize, arcSize);
}
g2.dispose();
}
@Override
protected void setThumbBounds(int x, int y, int width, int height) {
super.setThumbBounds(x, y, width, height);
scrollbar.repaint();
}
}

View File

@ -0,0 +1,83 @@
package envoy.client.ui;
import javax.swing.JScrollPane;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>PrimaryScrollPane.java</strong><br>
* Created: <strong>15 Dec 2019</strong><br>
*
* @author Kai S. K. Engelbart
* @author Maximilian K&auml;fer
*/
public class PrimaryScrollPane extends JScrollPane {
private static final long serialVersionUID = -4786837444056228439L;
private int verticalScrollBarMaximum = getVerticalScrollBar().getMaximum();
private boolean chatOpened = false;
/**
* Initializes a {@link JScrollPane} with the primary Envoy design scheme
*
* @since Envoy v0.2-alpha
*/
public PrimaryScrollPane() { setBorder(null); }
/**
* Styles the vertical and horizontal scroll bars.
*
* @param theme
* @since Envoy v0.2-alpha
*/
public void applyTheme(Theme theme) {
setForeground(theme.getBackgroundColor());
setBackground(theme.getCellColor());
getVerticalScrollBar().setBackground(theme.getCellColor());
getVerticalScrollBar().setUI(new PrimaryScrollBar(theme, true));
getHorizontalScrollBar().setBackground(theme.getCellColor());
getHorizontalScrollBar().setUI(new PrimaryScrollBar(theme, false));
}
/**
* Implements <b>autoscroll functionality</b> for the vertical scroll bar. </br>
* </br>
* Functionality to automatically scroll down when user views </br>
* the bottom of the chat while there are new messages added. </br>
* </br>
* When chat is opened, the vertical scroll bar starts at the bottom. </br>
* </br>
* When rereading messages, the chat doesn't scroll down if new messages </br>
* are added. (Besides see first point)
*
* @since Envoy v0.2-alpha
*/
public void autoscroll() {
// Automatic scrolling to the bottom
getVerticalScrollBar().addAdjustmentListener(e -> {
if (verticalScrollBarMaximum == e.getAdjustable().getMaximum()) return;
if (chatOpened) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
verticalScrollBarMaximum = getVerticalScrollBar().getMaximum();
chatOpened = false;
return;
}
if (getVerticalScrollBar().getValue() + getVerticalScrollBar().getVisibleAmount() + 100 >= getVerticalScrollBar().getMaximum()) {
e.getAdjustable().setValue(e.getAdjustable().getMaximum());
verticalScrollBarMaximum = getVerticalScrollBar().getMaximum();
}
});
}
/**
* Indicates a chat being opened by the user to this {@link PrimaryScrollPane}
* triggering it to automatically scroll down.
*
* @param chatOpened indicates the chat opening status
* @since Envoy v0.2-alpha
*/
public void setChatOpened(boolean chatOpened) { this.chatOpened = chatOpened; }
}

View File

@ -0,0 +1,67 @@
package envoy.client.ui;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
/**
* Project: <strong>envoy-client</strong><br>
* File: <strong>PrimaryTextArea.javaEvent.java</strong><br>
* Created: <strong>07.12.2019</strong><br>
*
* @author Maximilian K&auml;fer
* @since Envoy v0.2-alpha
*/
public class PrimaryTextArea extends JTextArea {
private static final long serialVersionUID = -5829028696155434913L;
private int arcSize;
/**
* Creates the text area
*
* @param borderSpace
* @since Envoy 0.2-alpha
*/
public PrimaryTextArea(int borderSpace) { this(6, borderSpace); }
/**
* Creates the text area
*
* @param arcSize is the diameter of the arc at the four corners.
* @param borderSpace is the insets of the border on all four sides.
* @since Envoy 0.2-alpha
*/
public PrimaryTextArea(int arcSize, int borderSpace) {
super();
setWrapStyleWord(true);
setLineWrap(true);
setBorder(null);
setFont(new Font("Arial", Font.PLAIN, 17));
setBorder(new EmptyBorder(borderSpace, borderSpace, borderSpace, borderSpace));
setOpaque(false);
this.arcSize = arcSize;
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillRoundRect(0, 0, getWidth(), getHeight(), arcSize, arcSize);
super.paintComponent(g);
}
/**
* @return the arcSize - the diameter of the arc at the four corners.
* @since Envoy 0.2-alpha
*/
public int getArcSize() { return arcSize; }
/**
* @param arcSize the arcSize to set
* @since Envoy 0.2-alpha
*/
public void setArcSize(int arcSize) { this.arcSize = arcSize; }
}

View File

@ -28,14 +28,16 @@ import javax.swing.ListSelectionModel;
import envoy.client.Settings; import envoy.client.Settings;
import envoy.client.util.EnvoyLog; import envoy.client.util.EnvoyLog;
import envoy.client.event.EventBus;
import envoy.client.event.ThemeChangeEvent;
/** /**
* This class provides the GUI to change the user specific settings. * This class provides the GUI to change the user specific settings.
* *
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>SettingsScreen.java</strong><br> * File: <strong>SettingsScreen.java</strong><br>
* Created: <strong>31 Oct 2019</strong><br> * Created: <strong>31 Oct 2019</strong><br>
* *
* @author Leon Hofmeister * @author Leon Hofmeister
* @author Maximilian K&auml;fer * @author Maximilian K&auml;fer
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
@ -46,12 +48,12 @@ public class SettingsScreen extends JDialog {
private final JPanel contentPanel = new JPanel(); private final JPanel contentPanel = new JPanel();
private DefaultListModel<String> optionsListModel = new DefaultListModel<>(); private DefaultListModel<String> optionsListModel = new DefaultListModel<>();
private final JList<String> options = new JList<String>(); private final JList<String> options = new JList<>();
private JPanel buttonPane = new JPanel(); private JPanel buttonPane = new JPanel();
private JPanel themeContent = new JPanel(); private JPanel themeContent = new JPanel();
private String[] themeArray = Settings.getInstance().getThemes().keySet().toArray(new String[0]); private String[] themeArray = Settings.getInstance().getThemes().keySet().toArray(new String[0]);
private JComboBox<String> themes = new JComboBox<String>(themeArray); private JComboBox<String> themes = new JComboBox<>(themeArray);
private GridBagConstraints gbc_themeContent = new GridBagConstraints(); private GridBagConstraints gbc_themeContent = new GridBagConstraints();
@ -61,11 +63,13 @@ public class SettingsScreen extends JDialog {
private JButton cancelButton = new JButton("Cancel"); private JButton cancelButton = new JButton("Cancel");
private static int space = 5; private static int space = 5;
private Theme selectedTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
private Theme temporaryTheme; private Theme temporaryTheme;
private static final Logger logger = EnvoyLog.getLogger(SettingsScreen.class.getSimpleName()); private static final Logger logger = EnvoyLog.getLogger(SettingsScreen.class.getSimpleName());
private static SettingsScreen settingsScreen;
// TODO: Add a JPanel with all the Information necessary: // TODO: Add a JPanel with all the Information necessary:
// change (Picture,Username, Email, Password) and toggle(light/dark mode, // change (Picture,Username, Email, Password) and toggle(light/dark mode,
// "ctrl+enter"/"enter" // "ctrl+enter"/"enter"
@ -73,7 +77,7 @@ public class SettingsScreen extends JDialog {
/** /**
* Builds the settings screen. * Builds the settings screen.
* *
* @since Envoy v0.1-alpha * @since Envoy v0.1-alpha
*/ */
public SettingsScreen() { public SettingsScreen() {
@ -121,11 +125,6 @@ public class SettingsScreen extends JDialog {
Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); Theme theme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
options.setSelectionForeground(theme.getUserNameColor());
options.setSelectionBackground(theme.getSelectionColor());
options.setForeground(theme.getUserNameColor());
options.setBackground(theme.getCellColor());
GridBagConstraints gbc_optionsList = new GridBagConstraints(); GridBagConstraints gbc_optionsList = new GridBagConstraints();
gbc_optionsList.fill = GridBagConstraints.BOTH; gbc_optionsList.fill = GridBagConstraints.BOTH;
gbc_optionsList.gridx = 0; gbc_optionsList.gridx = 0;
@ -147,9 +146,6 @@ public class SettingsScreen extends JDialog {
GridBagLayout gbl_themeLayout = new GridBagLayout(); GridBagLayout gbl_themeLayout = new GridBagLayout();
themeContent.setForeground(theme.getUserNameColor());
themeContent.setBackground(theme.getCellColor());
gbl_themeLayout.columnWidths = new int[] { 1, 1 }; gbl_themeLayout.columnWidths = new int[] { 1, 1 };
gbl_themeLayout.rowHeights = new int[] { 1, 1 }; gbl_themeLayout.rowHeights = new int[] { 1, 1 };
gbl_themeLayout.columnWeights = new double[] { 1.0, 1.0 }; gbl_themeLayout.columnWeights = new double[] { 1.0, 1.0 };
@ -157,8 +153,6 @@ public class SettingsScreen extends JDialog {
themeContent.setLayout(gbl_themeLayout); themeContent.setLayout(gbl_themeLayout);
themes.setBackground(theme.getUserNameColor());
themes.setForeground(theme.getBackgroundColor());
themes.setSelectedItem(Settings.getInstance().getCurrentTheme()); themes.setSelectedItem(Settings.getInstance().getCurrentTheme());
themes.addItemListener(new ItemListener() { themes.addItemListener(new ItemListener() {
@ -183,27 +177,27 @@ public class SettingsScreen extends JDialog {
colorsPanel.setLayout(new BoxLayout(colorsPanel, BoxLayout.Y_AXIS)); colorsPanel.setLayout(new BoxLayout(colorsPanel, BoxLayout.Y_AXIS));
colorsPanel.setAlignmentX(Component.LEFT_ALIGNMENT); colorsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getBackgroundColor(), "Background", 1); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getBackgroundColor(), "Background", 0);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getCellColor(), "Cells", 2); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getCellColor(), "Cells", 1);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
new JTextPane(), new JTextPane(),
theme, theme,
theme.getInteractableForegroundColor(), theme.getInteractableForegroundColor(),
"Interactable Foreground", "Interactable Foreground",
3); 2);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
new JTextPane(), new JTextPane(),
theme, theme,
theme.getInteractableBackgroundColor(), theme.getInteractableBackgroundColor(),
"Interactable Background", "Interactable Background",
4); 3);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getMessageColorChat(), "Messages Chat", 5); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getMessageColorChat(), "Messages Chat", 4);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getDateColorChat(), "Date Chat", 6); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getDateColorChat(), "Date Chat", 5);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getSelectionColor(), "Selection", 7); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getSelectionColor(), "Selection", 6);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getTypingMessageColor(), "Typing Message", 8); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getTypingMessageColor(), "Typing Message", 7);
buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getUserNameColor(), "User Names", 9); buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getUserNameColor(), "User Names", 8);
GridBagConstraints gbc_colorsPanel = new GridBagConstraints(); GridBagConstraints gbc_colorsPanel = new GridBagConstraints();
gbc_colorsPanel.fill = GridBagConstraints.HORIZONTAL; gbc_colorsPanel.fill = GridBagConstraints.HORIZONTAL;
@ -239,8 +233,6 @@ public class SettingsScreen extends JDialog {
contentPanel.revalidate(); contentPanel.revalidate();
contentPanel.repaint(); contentPanel.repaint();
// TODO: Create new Theme
} catch (Exception e) { } catch (Exception e) {
logger.info("New theme couldn't be created! " + e); logger.info("New theme couldn't be created! " + e);
e.printStackTrace(); e.printStackTrace();
@ -287,18 +279,15 @@ public class SettingsScreen extends JDialog {
getRootPane().setDefaultButton(okButton); getRootPane().setDefaultButton(okButton);
okButton.addActionListener((evt) -> { okButton.addActionListener((evt) -> {
try { try {
Settings.getInstance().setUsername(Settings.getInstance().getUsername());// still temporary
Settings.getInstance().setEmail(Settings.getInstance().getEmail());// still temporary value
Settings.getInstance().setEnterToSend(Settings.getInstance().isEnterToSend());// still temporary Settings.getInstance().setEnterToSend(Settings.getInstance().isEnterToSend());// still temporary
Settings.getInstance().setCurrentTheme(selectedTheme.getThemeName()); Settings.getInstance().setCurrentTheme(selectedTheme.getThemeName());
logger.log(Level.FINER, selectedTheme.getThemeName()); logger.log(Level.FINER, selectedTheme.getThemeName());
changeSettingsScreenColors(Settings.getInstance().getCurrentTheme()); final Theme currentTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme());
updateColorVariables(Settings.getInstance().getCurrentTheme()); changeSettingsScreenColors(currentTheme);
updateColorVariables(currentTheme);
EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme));
Settings.getInstance().save(); Settings.getInstance().save();
revalidate(); revalidate();
@ -311,14 +300,14 @@ public class SettingsScreen extends JDialog {
}); });
} }
} }
changeSettingsScreenColors(Settings.getInstance().getCurrentTheme());
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); changeSettingsScreenColors(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setModal(true); setModal(true);
} }
private void changeSettingsScreenColors(String key) { private void changeSettingsScreenColors(Theme theme) {
Theme theme = Settings.getInstance().getThemes().get(key);
// whole JDialog // whole JDialog
setBackground(theme.getBackgroundColor()); setBackground(theme.getBackgroundColor());
// contentPanel // contentPanel
@ -340,8 +329,8 @@ public class SettingsScreen extends JDialog {
themeContent.setForeground(theme.getUserNameColor()); themeContent.setForeground(theme.getUserNameColor());
themeContent.setBackground(theme.getCellColor()); themeContent.setBackground(theme.getCellColor());
// themes // themes
themes.setBackground(theme.getUserNameColor()); themes.setBackground(theme.getBackgroundColor());
themes.setForeground(theme.getBackgroundColor()); themes.setForeground(getInvertedColor(theme.getBackgroundColor()));
createNewThemeButton.setBackground(theme.getInteractableBackgroundColor()); createNewThemeButton.setBackground(theme.getInteractableBackgroundColor());
createNewThemeButton.setForeground(theme.getInteractableForegroundColor()); createNewThemeButton.setForeground(theme.getInteractableForegroundColor());
@ -349,19 +338,8 @@ public class SettingsScreen extends JDialog {
} }
private void updateColorVariables(String key) { private void updateColorVariables(Theme theme) {
Theme theme = Settings.getInstance().getThemes().get(key); temporaryTheme = new Theme("temporaryTheme", theme);
temporaryTheme = new Theme("temporaryTheme",
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getBackgroundColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getCellColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getInteractableForegroundColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getInteractableBackgroundColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getMessageColorChat(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getSelectionColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getTypingMessageColor(),
Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getUserNameColor());
colorsPanel.removeAll(); colorsPanel.removeAll();
@ -372,7 +350,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getBackgroundColor(), theme.getBackgroundColor(),
"Background", "Background",
1); 0);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -380,7 +358,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getCellColor(), theme.getCellColor(),
"Cells", "Cells",
2); 1);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -388,7 +366,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getInteractableForegroundColor(), theme.getInteractableForegroundColor(),
"Interactable Foreground", "Interactable Foreground",
3); 2);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -396,7 +374,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getInteractableBackgroundColor(), theme.getInteractableBackgroundColor(),
"Interactable Background", "Interactable Background",
4); 3);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -404,7 +382,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getMessageColorChat(), theme.getMessageColorChat(),
"Messages Chat", "Messages Chat",
5); 4);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -412,7 +390,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getDateColorChat(), theme.getDateColorChat(),
"Date Chat", "Date Chat",
6); 5);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -420,7 +398,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getSelectionColor(), theme.getSelectionColor(),
"Selection", "Selection",
7); 6);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -428,7 +406,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getTypingMessageColor(), theme.getTypingMessageColor(),
"Typing Message", "Typing Message",
8); 7);
buildCustomizeElement(new JPanel(), buildCustomizeElement(new JPanel(),
new JButton(), new JButton(),
@ -436,7 +414,7 @@ public class SettingsScreen extends JDialog {
theme, theme,
theme.getUserNameColor(), theme.getUserNameColor(),
"User Names", "User Names",
9); 8);
GridBagConstraints gbc_createNewTheme = new GridBagConstraints(); GridBagConstraints gbc_createNewTheme = new GridBagConstraints();
gbc_createNewTheme.gridx = 0; gbc_createNewTheme.gridx = 0;
@ -450,7 +428,7 @@ public class SettingsScreen extends JDialog {
private void buildCustomizeElement(JPanel panel, JButton button, JTextPane textPane, Theme theme, Color color, String name, int yIndex) { private void buildCustomizeElement(JPanel panel, JButton button, JTextPane textPane, Theme theme, Color color, String name, int yIndex) {
textPane.setFont(new Font("Arial", Font.PLAIN, 14)); textPane.setFont(new Font("Arial", Font.PLAIN, 14));
textPane.setBackground(theme.getBackgroundColor()); textPane.setBackground(theme.getBackgroundColor());
textPane.setForeground(theme.getUserNameColor()); textPane.setForeground(getInvertedColor(theme.getBackgroundColor()));
textPane.setText(name); textPane.setText(name);
textPane.setEditable(false); textPane.setEditable(false);
@ -461,18 +439,13 @@ public class SettingsScreen extends JDialog {
try { try {
Color newColor = JColorChooser.showDialog(null, "Choose a color", color); Color newColor = JColorChooser.showDialog(null, "Choose a color", color);
if (newColor.getRGB() != color.getRGB()) { if (newColor.getRGB() != color.getRGB()) {
logger.log(Level.FINEST, String.valueOf(color.getRGB())); logger.log(Level.FINEST, "New Color: " + String.valueOf(color.getRGB()));
Color[] colorsArray = temporaryTheme.getAllColors(); // TODO: When Theme changed in same settings screen, color variable doesnt
for (int i = 0; i < colorsArray.length; i++) { // update.
if (color.getRGB() == colorsArray[i].getRGB()) { temporaryTheme.setColor(yIndex, newColor);
temporaryTheme.setColor(i, newColor); createNewThemeButton.setEnabled(true);
createNewThemeButton.setEnabled(true);
break;
}
}
button.setBackground(newColor);
} }
button.setBackground(newColor);
} catch (Exception e) { } catch (Exception e) {
logger.info("An error occured while opening Color Chooser: " + e); logger.info("An error occured while opening Color Chooser: " + e);
@ -488,4 +461,5 @@ public class SettingsScreen extends JDialog {
colorsPanel.add(panel); colorsPanel.add(panel);
} }
private Color getInvertedColor(Color color) { return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()); }
} }

View File

@ -2,9 +2,9 @@ package envoy.client.ui;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.io.IOException; import java.io.IOException;
import java.util.Properties;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import envoy.client.Client; import envoy.client.Client;
@ -12,11 +12,13 @@ import envoy.client.Config;
import envoy.client.LocalDB; import envoy.client.LocalDB;
import envoy.client.Settings; import envoy.client.Settings;
import envoy.client.util.EnvoyLog; import envoy.client.util.EnvoyLog;
import envoy.exception.EnvoyException; import envoy.exception.EnvoyException;
import envoy.schema.User;
/** /**
* Starts the Envoy client and prompts the user to enter their name. * Starts the Envoy client and prompts the user to enter their name.
* * <br>
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>Startup.java</strong><br> * File: <strong>Startup.java</strong><br>
* Created: <strong>12 Oct 2019</strong><br> * Created: <strong>12 Oct 2019</strong><br>
@ -33,34 +35,69 @@ public class Startup {
public static void main(String[] args) { public static void main(String[] args) {
Config config = Config.getInstance(); Config config = Config.getInstance();
// Load the configuration from client.properties first
ClassLoader loader = Thread.currentThread().getContextClassLoader();
try { try {
Properties configProperties = new Properties(); // Load the configuration from client.properties first
configProperties.load(loader.getResourceAsStream("client.properties")); config.load();
config.load(configProperties);
} catch (IOException e) { // Override configuration values with command line arguments
if (args.length > 0) config.load(args);
// Check if all configuration values have been initialized
if (!config.isInitialized()) throw new EnvoyException("Server or port are not defined");
} catch (Exception e) {
JOptionPane
.showMessageDialog(null, "Error loading configuration values: \n" + e.toString(), "Configuration error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
e.printStackTrace(); e.printStackTrace();
} }
// Override configuration values with command line arguments // Ask the user for their user name
if (args.length > 0) config.load(args);
if (!config.isInitialized()) {
logger.severe("Server or port are not defined. Exiting...");
JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
String userName = JOptionPane.showInputDialog("Please enter your username"); String userName = JOptionPane.showInputDialog("Please enter your username");
if (userName == null || userName.isEmpty()) { if (userName == null || userName.isEmpty()) {
logger.severe("User name is not set or empty. Exiting..."); logger.severe("User name is not set or empty. Exiting...");
System.exit(1); System.exit(1);
} }
Client client = new Client(config, userName);
LocalDB localDB = new LocalDB(client.getSender()); // Initialize the local database
LocalDB localDB;
try { try {
localDB.initializeDBFile(config.getLocalDB()); localDB = new LocalDB(config.getLocalDB());
} catch (IOException e3) {
logger.log(Level.SEVERE, "Could not initialize local database", e3);
JOptionPane.showMessageDialog(null, "Could not initialize local database!\n" + e3.toString());
System.exit(1);
return;
}
// Acquire the client user (with ID) either from the server or from the local
// database, which triggers offline mode
Client client = new Client(config);
try {
// Try entering online mode first
client.onlineInit(userName);
} catch (Exception e1) {
logger.warning("Could not connect to server. Trying offline mode...");
try {
// Try entering offline mode
localDB.loadUsers();
User clientUser = localDB.getUsers().get(userName);
if(clientUser == null)
throw new EnvoyException("Could not enter offline mode: user name unknown");
client.setSender(clientUser);
} catch(Exception e2) {
JOptionPane.showMessageDialog(null, e2.toString(), "Client error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
return;
}
}
// Set client user in local database
localDB.setUser(client.getSender());
// Initialize chats in local database
try {
localDB.initializeDBFile();
localDB.loadChats();
} catch (EnvoyException e) { } catch (EnvoyException e) {
e.printStackTrace(); e.printStackTrace();
JOptionPane.showMessageDialog(null, JOptionPane.showMessageDialog(null,
@ -68,8 +105,13 @@ public class Startup {
"Local DB error", "Local DB error",
JOptionPane.WARNING_MESSAGE); JOptionPane.WARNING_MESSAGE);
} }
Settings.getInstance().setUsername(userName);
logger.info("Client user ID: " + client.getSender().getID());
// Save all users to the local database
if(client.isOnline())
localDB.setUsers(client.getUsers());
EventQueue.invokeLater(() -> { EventQueue.invokeLater(() -> {
try { try {
ChatWindow chatWindow = new ChatWindow(client, localDB); ChatWindow chatWindow = new ChatWindow(client, localDB);
@ -77,6 +119,9 @@ public class Startup {
try { try {
new StatusTrayIcon(chatWindow).show(); new StatusTrayIcon(chatWindow).show();
// If the tray icon is supported, hide the chat window on close
chatWindow.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
} catch (EnvoyException e) { } catch (EnvoyException e) {
logger.warning("The StatusTrayIcon is not supported on this platform!"); logger.warning("The StatusTrayIcon is not supported on this platform!");
} }

View File

@ -11,12 +11,8 @@ import java.awt.TrayIcon.MessageType;
import java.awt.Window; import java.awt.Window;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; 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.EventBus;
import envoy.client.event.EventHandler;
import envoy.client.event.MessageCreationEvent; import envoy.client.event.MessageCreationEvent;
import envoy.exception.EnvoyException; import envoy.exception.EnvoyException;
import envoy.schema.Message; import envoy.schema.Message;
@ -29,7 +25,7 @@ import envoy.schema.Message;
* @author Kai S. K. Engelbart * @author Kai S. K. Engelbart
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public class StatusTrayIcon implements EventHandler { public class StatusTrayIcon {
/** /**
* The {@link TrayIcon} provided by the System Tray API for controlling the * The {@link TrayIcon} provided by the System Tray API for controlling the
@ -81,8 +77,14 @@ public class StatusTrayIcon implements EventHandler {
public void windowLostFocus(WindowEvent e) { displayMessages = true; } public void windowLostFocus(WindowEvent e) { displayMessages = true; }
}); });
// Show the window if the user clicks on the icon
trayIcon.addActionListener((evt) -> { focusTarget.setVisible(true); focusTarget.requestFocus(); });
// Start processing message events // Start processing message events
EventBus.getInstance().register(this); EventBus.getInstance().register(MessageCreationEvent.class, (evt) -> {
if (displayMessages)
trayIcon.displayMessage("New message received", ((MessageCreationEvent) evt).get().getContent().get(0).getText(), MessageType.INFO);
});
} }
/** /**
@ -99,31 +101,4 @@ public class StatusTrayIcon implements EventHandler {
throw new EnvoyException("Could not attach Envoy tray icon to system tray.", 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;
}
} }

View File

@ -1,179 +1,161 @@
package envoy.client.ui; package envoy.client.ui;
import java.awt.Color; import java.awt.Color;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
* File: <strong>Theme.java</strong><br> * File: <strong>Theme.java</strong><br>
* Created: <strong>23 Nov 2019</strong><br> * Created: <strong>23 Nov 2019</strong><br>
* *
* @author Maximilian K&auml;fer * @author Maximilian K&auml;fer
* @since Envoy v0.2-alpha * @since Envoy v0.2-alpha
*/ */
public class Theme implements Serializable { public class Theme implements Serializable {
private static final long serialVersionUID = 141727847527060352L; private static final long serialVersionUID = 141727847527060352L;
private String themeName; private String themeName;
private Color backgroundColor; private Color backgroundColor;
private Color cellColor; private Color cellColor;
private Color interactableBackgroundColor; private Color interactableBackgroundColor;
private Color userNameColor; private Color userNameColor;
private Color interactableForegroundColor; private Color interactableForegroundColor;
private Color messageColorChat; private Color messageColorChat;
private Color dateColorChat; private Color dateColorChat;
private Color selectionColor; private Color selectionColor;
private Color typingMessageColor; private Color typingMessageColor;
public Theme(String themeName, Color backgroundColor, Color cellColor, Color interactableForegroundColor, Color interactableBackgroundColor, public Theme(String themeName, Color backgroundColor, Color cellColor, Color interactableForegroundColor, Color interactableBackgroundColor,
Color messageColorChat, Color dateColorChat, Color selectionColor, Color typingMessageColor, Color userNameColor) { Color messageColorChat, Color dateColorChat, Color selectionColor, Color typingMessageColor, Color userNameColor) {
this.themeName = themeName; this.themeName = themeName;
this.backgroundColor = backgroundColor; this.backgroundColor = backgroundColor;
this.cellColor = cellColor; this.cellColor = cellColor;
this.interactableForegroundColor = interactableForegroundColor; this.interactableForegroundColor = interactableForegroundColor;
this.interactableBackgroundColor = interactableBackgroundColor; this.interactableBackgroundColor = interactableBackgroundColor;
this.messageColorChat = messageColorChat; this.messageColorChat = messageColorChat;
this.dateColorChat = dateColorChat; this.dateColorChat = dateColorChat;
this.selectionColor = selectionColor; this.selectionColor = selectionColor;
this.typingMessageColor = typingMessageColor; this.typingMessageColor = typingMessageColor;
this.userNameColor = userNameColor; this.userNameColor = userNameColor;
} }
public Theme(String name, Theme other) { public Theme(String name, Theme other) {
this(name, other.backgroundColor, other.cellColor, other.interactableBackgroundColor, other.interactableForegroundColor, this(name, other.backgroundColor, other.cellColor, other.interactableForegroundColor,
other.messageColorChat, other.dateColorChat, other.selectionColor, other.typingMessageColor, other.userNameColor); other.interactableBackgroundColor, other.messageColorChat, other.dateColorChat, other.selectionColor,
} other.typingMessageColor, other.userNameColor);
}
/**
* @return name of the theme /**
* @since Envoy v0.2-alpha * @return name of the theme
*/ * @since Envoy v0.2-alpha
public String getThemeName() { return themeName; } */
public String getThemeName() { return themeName; }
/**
* @return interactableForegroundColor /**
* @since Envoy v0.2-alpha * @return interactableForegroundColor
*/ * @since Envoy v0.2-alpha
public Color getInteractableForegroundColor() { return interactableForegroundColor; } */
public Color getInteractableForegroundColor() { return interactableForegroundColor; }
/**
* @return messageColorChat /**
* @since Envoy v0.2-alpha * @return messageColorChat
*/ * @since Envoy v0.2-alpha
public Color getMessageColorChat() { return messageColorChat; } */
public Color getMessageColorChat() { return messageColorChat; }
/**
* @return dateColorChat /**
* @since Envoy v0.2-alpha * @return dateColorChat
*/ * @since Envoy v0.2-alpha
public Color getDateColorChat() { return dateColorChat; } */
public Color getDateColorChat() { return dateColorChat; }
/**
* @return selectionColor /**
* @since Envoy v0.2-alpha * @return selectionColor
*/ * @since Envoy v0.2-alpha
public Color getSelectionColor() { return selectionColor; } */
public Color getSelectionColor() { return selectionColor; }
/**
* @return typingMessageColor /**
* @since Envoy v0.2-alpha * @return typingMessageColor
*/ * @since Envoy v0.2-alpha
public Color getTypingMessageColor() { return typingMessageColor; } */
public Color getTypingMessageColor() { return typingMessageColor; }
/**
* @return backgroundColor /**
* @since Envoy v0.2-alpha * @return backgroundColor
*/ * @since Envoy v0.2-alpha
public Color getBackgroundColor() { return backgroundColor; } */
public Color getBackgroundColor() { return backgroundColor; }
/**
* @return cellColor /**
* @since Envoy v0.2-alpha * @return cellColor
*/ * @since Envoy v0.2-alpha
public Color getCellColor() { return cellColor; } */
public Color getCellColor() { return cellColor; }
/**
* @return interactableBackgroundColor /**
* @since Envoy v0.2-alpha * @return interactableBackgroundColor
*/ * @since Envoy v0.2-alpha
public Color getInteractableBackgroundColor() { return interactableBackgroundColor; } */
public Color getInteractableBackgroundColor() { return interactableBackgroundColor; }
/**
* @return userNameColor /**
* @since Envoy v0.2-alpha * @return userNameColor
*/ * @since Envoy v0.2-alpha
public Color getUserNameColor() { return userNameColor; } */
public Color getUserNameColor() { return userNameColor; }
/**
* @return a color array containing all colors of this theme /**
* @since Envoy v0.2-alpha * Sets the a specific {@link Color} in this theme to a new {@link Color}
*/ *
public Color[] getAllColors() { * @param index - index of the color </br>
Color[] c = new Color[9]; * 0 = backgroundColor </br>
c[0] = backgroundColor; * 1 = cellColor </br>
c[1] = cellColor; * 2 = interactableForegroundColor </br>
c[2] = interactableForegroundColor; * 3 = interactableBackgroundColor </br>
c[3] = interactableBackgroundColor; * 4 = messageColorChat </br>
c[4] = messageColorChat; * 5 = dateColorChat </br>
c[5] = dateColorChat; * 6 = selectionColor </br>
c[6] = selectionColor; * 7 = typingMessageColor </br>
c[7] = typingMessageColor; * 8 = userNameColor </br>
c[8] = userNameColor; * </br>
*
return c; * @param newColor - new {@link Color} to be set
} * @since Envoy 0.2-alpha
*/
/** public void setColor(int index, Color newColor) {
* Sets the a specific {@link Color} in this theme to a new {@link Color} switch (index) {
* case 0:
* @param index - index of the color </br> this.backgroundColor = newColor;
* 0 = backgroundColor </br> break;
* 1 = cellColor </br> case 1:
* 2 = interactableForegroundColor </br> this.cellColor = newColor;
* 3 = interactableBackgroundColor </br> break;
* 4 = messageColorChat </br> case 2:
* 5 = dateColorChat </br> this.interactableForegroundColor = newColor;
* 6 = selectionColor </br> break;
* 7 = typingMessageColor </br> case 3:
* 8 = userNameColor </br> this.interactableBackgroundColor = newColor;
* </br> break;
* case 4:
* @param newColor - new {@link Color} to be set this.messageColorChat = newColor;
* @since Envoy 0.2-alpha break;
*/ case 5:
public void setColor(int index, Color newColor) { this.dateColorChat = newColor;
switch (index) { break;
case 0: case 6:
this.backgroundColor = newColor; this.selectionColor = newColor;
break; break;
case 1: case 7:
this.cellColor = newColor; this.typingMessageColor = newColor;
break; break;
case 2: case 8:
this.interactableForegroundColor = newColor; this.userNameColor = newColor;
break; break;
case 3: }
this.interactableBackgroundColor = newColor; }
break;
case 4: }
this.messageColorChat = newColor;
break;
case 5:
this.dateColorChat = newColor;
break;
case 6:
this.selectionColor = newColor;
break;
case 7:
this.typingMessageColor = newColor;
break;
case 8:
this.userNameColor = newColor;
break;
}
}
}