Merge branch 'develop' into f/logger
This commit is contained in:
		| @@ -1,6 +1,7 @@ | ||||
| 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.Entity; | ||||
| @@ -10,7 +11,7 @@ import javax.xml.bind.JAXBContext; | ||||
| import javax.xml.bind.JAXBException; | ||||
| import javax.xml.bind.Marshaller; | ||||
|  | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.exception.EnvoyException; | ||||
| import envoy.schema.ObjectFactory; | ||||
| import envoy.schema.Sync; | ||||
| import envoy.schema.User; | ||||
| @@ -30,14 +31,28 @@ public class Client { | ||||
| 	private ObjectFactory	objectFactory	= new ObjectFactory(); | ||||
| 	private Config			config; | ||||
| 	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; | ||||
| 		sender		= getUser(username); | ||||
|  | ||||
| 		logger.info("ID: " + sender.getID()); | ||||
| 	/** | ||||
| 	 * Enters the online mode by acquiring a user ID from the server. | ||||
| 	 *  | ||||
| 	 * @param userName the name of the client user | ||||
| 	 * @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) { | ||||
| @@ -49,26 +64,26 @@ public class Client { | ||||
| 		client.close(); | ||||
|  | ||||
| 		return responseBody; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Returns a {@link Sync} with all users on the server. | ||||
| 	 *  | ||||
| 	 * @return Sync - List of all users on the server. | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 * @return a {@code Map<String, User>} of all users on the server with their | ||||
| 	 *         user names as keys | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Sync getUsersListXml() { | ||||
| 	public Map<String, User> getUsers() { | ||||
| 		Sync	sendSync	= objectFactory.createSync(); | ||||
| 		User	user		= objectFactory.createUser(); | ||||
| 		user.setID(-1); | ||||
| 		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, | ||||
| 				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} | ||||
| 	 * @return a {@link User} with the specified name | ||||
| 	 * @throws EnvoyException if the server does not return the requested ID | ||||
| 	 * @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(); | ||||
| 		User	user		= objectFactory.createUser(); | ||||
| 		user.setName(name); | ||||
| 		senderSync.getUsers().add(user); | ||||
|  | ||||
| 		Sync returnSenderSync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), | ||||
| 				senderSync, | ||||
| 				Sync.class); | ||||
| 		try { | ||||
| 			Sync sync = post(String.format("%s:%d/envoy-server/rest/sync/syncData?userId=%d", config.getServer(), config.getPort(), 0), | ||||
| 					senderSync, | ||||
| 					Sync.class); | ||||
|  | ||||
| 		User returnSender = objectFactory.createUser(); | ||||
|  | ||||
| 		if (returnSenderSync.getUsers().size() == 1) { | ||||
| 			returnSender = returnSenderSync.getUsers().get(0); | ||||
| 		} else { | ||||
| 			logger.warning("ERROR exiting..."); | ||||
| 			// Expecting a single user with an ID | ||||
| 			if (sync.getUsers().size() == 1) { | ||||
| 				online = true; | ||||
| 				return sync.getUsers().get(0); | ||||
| 			} else throw new EnvoyException("Unexpected response from Envoy Server"); | ||||
| 		} 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 | ||||
| 	 *               sync.xml) | ||||
| 	 * @return a returnSync.xml file | ||||
| 	 * @throws EnvoyException if the client is not in online mode | ||||
| 	 * @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 | ||||
| 		JAXBContext jc; | ||||
| 		try { | ||||
| @@ -158,6 +178,14 @@ public class Client { | ||||
| 	 */ | ||||
| 	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. | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| @@ -167,7 +195,7 @@ public class Client { | ||||
| 	/** | ||||
| 	 * Sets the recipient. | ||||
| 	 *  | ||||
| 	 * @param recipient - the recipient to set | ||||
| 	 * @param recipient the recipient to set | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void setRecipient(User recipient) { this.recipient = recipient; } | ||||
| @@ -177,4 +205,10 @@ public class Client { | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	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; } | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,8 @@ package envoy.client; | ||||
| import java.io.File; | ||||
| import java.util.Properties; | ||||
|  | ||||
| import envoy.exception.EnvoyException; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>Config.java</strong><br> | ||||
| @@ -29,17 +31,26 @@ public class Config { | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 *                   the server and port, as well as the path to the local | ||||
| 	 *                   database and the synchronization timeout | ||||
| 	 * @throws EnvoyException if the {@code client.properties} file could not be | ||||
| 	 *                        loaded | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void load(Properties 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")); | ||||
| 	public void load() throws EnvoyException { | ||||
| 		ClassLoader loader = getClass().getClassLoader(); | ||||
| 		try { | ||||
| 			Properties properties = new Properties(); | ||||
| 			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. | ||||
| 	 *  | ||||
| 	 * @param args the command line arguments to parse | ||||
| 	 * @throws EnvoyException if the command line arguments contain an unknown token | ||||
| 	 * @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++) | ||||
| 			switch (args[i]) { | ||||
| 				case "--server": | ||||
| @@ -64,6 +76,8 @@ public class Config { | ||||
| 				case "-db": | ||||
| 					localDB = new File(args[++i]); | ||||
| 					break; | ||||
| 				default: | ||||
| 					throw new EnvoyException("Unknown token " + args[i] + " found"); | ||||
| 			} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,9 @@ import java.io.ObjectInputStream; | ||||
| import java.io.ObjectOutputStream; | ||||
| import java.time.Instant; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.logging.Logger; | ||||
|  | ||||
| import javax.xml.datatype.DatatypeConfigurationException; | ||||
| @@ -35,9 +37,11 @@ import envoy.schema.User; | ||||
|  */ | ||||
| public class LocalDB { | ||||
|  | ||||
| 	private File			localDB; | ||||
| 	private User			sender; | ||||
| 	private List<Chat>		chats			= new ArrayList<>(); | ||||
| 	private File				localDBDir, localDBFile, usersFile; | ||||
| 	private User				user; | ||||
| 	private Map<String, User>	users	= new HashMap<>(); | ||||
| 	private List<Chat>			chats	= new ArrayList<>(); | ||||
|  | ||||
| 	private ObjectFactory	objectFactory	= new ObjectFactory(); | ||||
| 	private DatatypeFactory	datatypeFactory; | ||||
|  | ||||
| @@ -45,67 +49,94 @@ public class LocalDB { | ||||
| 	private Sync	sync				= 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 | ||||
| 	 */ | ||||
| 	public LocalDB(User sender) { | ||||
| 		this.sender = sender; | ||||
| 	public LocalDB(File localDBDir) throws IOException { | ||||
| 		this.localDBDir = localDBDir; | ||||
|  | ||||
| 		try { | ||||
| 			datatypeFactory = DatatypeFactory.newInstance(); | ||||
| 		} catch (DatatypeConfigurationException e) { | ||||
| 			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 | ||||
| 	 * if the user has already sent or received messages. | ||||
| 	 * Creates a database file for a user-specific list of chats. | ||||
| 	 * | ||||
| 	 * @param localDBDir the directory where we wish to save/load the database from. | ||||
| 	 * @throws EnvoyException if the directory selected is not an actual directory. | ||||
| 	 * @throws NullPointerException if the client user is not yet specified | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void initializeDBFile(File localDBDir) throws EnvoyException { | ||||
| 		if (localDBDir.exists() && !localDBDir.isDirectory()) | ||||
| 			throw new EnvoyException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath())); | ||||
| 		localDB = new File(localDBDir, sender.getID() + ".db"); | ||||
| 		if (localDB.exists()) loadFromLocalDB(); | ||||
| 	public void initializeDBFile() { | ||||
| 		if (user == null) throw new NullPointerException("Client user is null"); | ||||
| 		localDBFile = new File(localDBDir, user.getID() + ".db"); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void saveToLocalDB() throws IOException { | ||||
| 		localDB.getParentFile().mkdirs(); | ||||
| 		localDB.createNewFile(); | ||||
| 		try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { | ||||
| 			out.writeObject(chats); | ||||
| 		} catch (IOException ex) { | ||||
| 			throw ex; | ||||
| 		} | ||||
| 	public void save() throws IOException { | ||||
| 		// Save users | ||||
| 		write(usersFile, users); | ||||
|  | ||||
| 		// Save chats | ||||
| 		write(localDBFile, chats); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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. | ||||
| 	 * | ||||
| 	 * @throws EnvoyException if something fails while loading. | ||||
| 	 * @throws EnvoyException if the loading process failed | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	@SuppressWarnings("unchecked") | ||||
| 	private void loadFromLocalDB() throws EnvoyException { | ||||
| 		try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(localDB))) { | ||||
| 			Object obj = in.readObject(); | ||||
| 			if (obj instanceof ArrayList<?>) chats = (ArrayList<Chat>) obj; | ||||
| 	public void loadChats() throws EnvoyException { chats = read(localDBFile, ArrayList.class); } | ||||
|  | ||||
| 	private <T> T read(File file, Class<T> serializedClass) throws EnvoyException { | ||||
| 		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) { | ||||
| 			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) { | ||||
| 		Message.Metadata metaData = objectFactory.createMessageMetadata(); | ||||
| 		metaData.setSender(sender.getID()); | ||||
| 		metaData.setSender(user.getID()); | ||||
| 		metaData.setRecipient(recipientID); | ||||
| 		metaData.setState(MessageState.WAITING); | ||||
| 		metaData.setDate(datatypeFactory.newXMLGregorianCalendar(Instant.now().toString())); | ||||
| @@ -135,13 +166,13 @@ public class LocalDB { | ||||
| 		return message; | ||||
| 	} | ||||
|  | ||||
|     /** | ||||
| 	/** | ||||
| 	 * Creates a {@link Sync} object filled with the changes that occurred to the | ||||
| 	 * local database since the last synchronization. | ||||
| 	 *  | ||||
| 	 * @param userId the ID of the user that is synchronized by this client | ||||
| 	 * @return {@link Sync} object filled with the current changes | ||||
|      * @since Envoy v0.1-alpha | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public Sync fillSync(long userId) { | ||||
| 		addWaitingMessagesToSync(); | ||||
| @@ -157,7 +188,7 @@ public class LocalDB { | ||||
| 	 * Applies the changes carried by a {@link Sync} object to the local database | ||||
| 	 *  | ||||
| 	 * @param returnSync the {@link Sync} object to apply | ||||
|      * @since Envoy v0.1-alpha | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void applySync(Sync returnSync) { | ||||
| 		for (int i = 0; i < returnSync.getMessages().size(); i++) { | ||||
| @@ -281,6 +312,17 @@ public class LocalDB { | ||||
| 	 */ | ||||
| 	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 | ||||
| 	 *         sender | ||||
| @@ -289,8 +331,19 @@ public class LocalDB { | ||||
| 	public List<Chat> getChats() { return chats; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the {@link User} who initialized the local database | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 * @param chats the chats to set | ||||
| 	 */ | ||||
| 	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; } | ||||
| } | ||||
|   | ||||
| @@ -26,8 +26,6 @@ import envoy.client.ui.Theme; | ||||
| public class Settings { | ||||
|  | ||||
| 	// Actual settings accessible by the rest of the application | ||||
| 	private String				username; | ||||
| 	private String				email; | ||||
| 	private boolean				enterToSend	= true; | ||||
| 	private Map<String, Theme>	themes; | ||||
| 	private String				currentTheme; | ||||
| @@ -65,8 +63,6 @@ public class Settings { | ||||
|  | ||||
| 	@SuppressWarnings("unchecked") | ||||
| 	private void load() { | ||||
| 		setUsername(prefs.get("username", "")); | ||||
| 		setEmail(prefs.get("email", "")); | ||||
| 		setEnterToSend(prefs.getBoolean("enterToSend", true)); | ||||
| 		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 | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public void save() throws IOException { | ||||
| 		prefs.put("username", getUsername()); | ||||
| 		prefs.put("email", getEmail()); | ||||
| 		prefs.put("theme", currentTheme); | ||||
| 		prefs.putBoolean("enterToSend", isEnterToSend()); | ||||
|  | ||||
| @@ -116,7 +110,7 @@ public class Settings { | ||||
| 	 */ | ||||
| 	public void addNewThemeToMap(Theme 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; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @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" | ||||
| 	 *         + "enter" | ||||
|   | ||||
| @@ -1,10 +1,10 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-clientChess</strong><br> | ||||
|  * File: <strong>Event.javaEvent.java</strong><br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>Event.java</strong><br> | ||||
|  * Created: <strong>04.12.2019</strong><br> | ||||
|  *  | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @param <T> the type of our Event | ||||
|  * @since Envoy v0.2-alpha | ||||
|   | ||||
| @@ -1,8 +1,9 @@ | ||||
| package envoy.client.event; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * This class handles events by allowing {@link EventHandler} object to register | ||||
| @@ -10,11 +11,12 @@ import java.util.List; | ||||
|  * bus.<br> | ||||
|  * <br> | ||||
|  * 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> | ||||
|  * File: <strong>EventBus.java</strong><br> | ||||
|  * Created: <strong>04.12.2019</strong><br> | ||||
|  *  | ||||
|  * | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @since Envoy v0.2-alpha | ||||
|  */ | ||||
| @@ -22,9 +24,10 @@ public class EventBus { | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| @@ -46,26 +49,33 @@ public class EventBus { | ||||
| 	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 | ||||
| 	 * Registers an {@link EventHandler} to be notified when a | ||||
| 	 * {@link Event} of a certain type is dispatched. | ||||
| 	 * | ||||
| 	 * @param eventClass the class which the {@link EventHandler} is subscribed to | ||||
| 	 * @param handler    the {@link EventHandler} to register | ||||
| 	 * @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. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @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)); } | ||||
| 	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 | ||||
| 	 *         this {@link EventBus} | ||||
| 	 * @return a map of all {@link EventHandler} instances currently registered at | ||||
| 	 *         this {@link EventBus} with the {@link Event} classes they are | ||||
| 	 *         subscribed to as keys | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public List<EventHandler> getHandlers() { return handlers; } | ||||
| 	public Map<Class<? extends Event<?>>, List<EventHandler>> getHandlers() { return handlers; } | ||||
| } | ||||
|   | ||||
| @@ -1,25 +1,18 @@ | ||||
| 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(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										20
									
								
								src/main/java/envoy/client/event/ThemeChangeEvent.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/main/java/envoy/client/event/ThemeChangeEvent.java
									
									
									
									
									
										Normal 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; } | ||||
| } | ||||
| @@ -15,13 +15,10 @@ import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
|  | ||||
| import javax.swing.DefaultListModel; | ||||
| import javax.swing.JButton; | ||||
| import javax.swing.JFrame; | ||||
| import javax.swing.JList; | ||||
| import javax.swing.JOptionPane; | ||||
| import javax.swing.JPanel; | ||||
| import javax.swing.JScrollPane; | ||||
| import javax.swing.JTextArea; | ||||
| import javax.swing.JTextPane; | ||||
| import javax.swing.ListSelectionModel; | ||||
| import javax.swing.SwingUtilities; | ||||
| @@ -34,8 +31,10 @@ import envoy.client.Config; | ||||
| import envoy.client.LocalDB; | ||||
| import envoy.client.Settings; | ||||
| import envoy.client.util.EnvoyLog; | ||||
| import envoy.client.event.EventBus; | ||||
| import envoy.client.event.ThemeChangeEvent; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
| import envoy.schema.Sync; | ||||
| import envoy.schema.User; | ||||
|  | ||||
| /** | ||||
| @@ -52,20 +51,20 @@ public class ChatWindow extends JFrame { | ||||
|  | ||||
| 	private static final long serialVersionUID = 6865098428255463649L; | ||||
|  | ||||
| 	// user specific objects | ||||
| 	// User specific objects | ||||
| 	private Client	client; | ||||
| 	private LocalDB	localDB; | ||||
|  | ||||
| 	// GUI components | ||||
| 	private JPanel			contentPane				= new JPanel(); | ||||
| 	private JTextArea		messageEnterTextArea	= new JTextArea(); | ||||
| 	private JList<User>		userList				= new JList<>(); | ||||
| 	private Chat			currentChat; | ||||
| 	private JList<Message>	messageList				= new JList<>(); | ||||
| 	private JScrollPane		scrollPane				= new JScrollPane(); | ||||
| 	private JTextPane		textPane				= new JTextPane(); | ||||
| 	// private JCheckBox jCbChangeMode; | ||||
| 	private JButton	postButton		= new JButton("Post"); | ||||
| 	private JButton	settingsButton	= new JButton("Settings"); | ||||
| 	private JPanel				contentPane				= new JPanel(); | ||||
| 	private PrimaryTextArea		messageEnterTextArea	= new PrimaryTextArea(space); | ||||
| 	private JList<User>			userList				= new JList<>(); | ||||
| 	private Chat				currentChat; | ||||
| 	private JList<Message>		messageList				= new JList<>(); | ||||
| 	private PrimaryScrollPane	scrollPane				= new PrimaryScrollPane(); | ||||
| 	private JTextPane			textPane				= new JTextPane(); | ||||
| 	private PrimaryButton		postButton				= new PrimaryButton("Post"); | ||||
| 	private PrimaryButton		settingsButton			= new PrimaryButton("Settings"); | ||||
|  | ||||
| 	private static int space = 4; | ||||
|  | ||||
| @@ -87,7 +86,7 @@ public class ChatWindow extends JFrame { | ||||
| 			@Override | ||||
| 			public void windowClosing(WindowEvent evt) { | ||||
| 				try { | ||||
| 					localDB.saveToLocalDB(); | ||||
| 					localDB.save(); | ||||
| 					Settings.getInstance().save(); | ||||
| 				} catch (IOException e1) { | ||||
| 					e1.printStackTrace(); | ||||
| @@ -116,7 +115,6 @@ public class ChatWindow extends JFrame { | ||||
| 		messageList.setBorder(new EmptyBorder(space, space, space, space)); | ||||
|  | ||||
| 		scrollPane.setViewportView(messageList); | ||||
| 		scrollPane.setBorder(null); | ||||
|  | ||||
| 		GridBagConstraints gbc_scrollPane = new GridBagConstraints(); | ||||
| 		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(); | ||||
| 		gbc_messageEnterTextfield.fill	= GridBagConstraints.BOTH; | ||||
| @@ -155,7 +147,6 @@ public class ChatWindow extends JFrame { | ||||
| 		contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); | ||||
|  | ||||
| 		// Post Button | ||||
| 		postButton.setBorderPainted(false); | ||||
| 		GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionPostButton.fill	= GridBagConstraints.BOTH; | ||||
| @@ -168,8 +159,6 @@ public class ChatWindow extends JFrame { | ||||
| 		contentPane.add(postButton, gbc_moveSelectionPostButton); | ||||
|  | ||||
| 		// Settings Button | ||||
| 		settingsButton.setBorderPainted(false); | ||||
|  | ||||
| 		GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionSettingsButton.fill	= GridBagConstraints.BOTH; | ||||
| @@ -208,7 +197,6 @@ public class ChatWindow extends JFrame { | ||||
| 				@SuppressWarnings("unchecked") | ||||
| 				final JList<User>	selectedUserList	= (JList<User>) listSelectionEvent.getSource(); | ||||
| 				final User			user				= selectedUserList.getSelectedValue(); | ||||
| 				client.setRecipient(user); | ||||
|  | ||||
| 				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()); | ||||
|  | ||||
| 				messageList.setModel(currentChat.getModel()); | ||||
| 				scrollPane.setChatOpened(true); | ||||
| 				contentPane.revalidate(); | ||||
| 			} | ||||
| 		}); | ||||
| @@ -233,25 +222,27 @@ public class ChatWindow extends JFrame { | ||||
| 		gbc_userList.anchor	= GridBagConstraints.PAGE_START; | ||||
| 		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.revalidate(); | ||||
|  | ||||
| 		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> changeChatWindowColors((Theme) evt.get())); | ||||
|  | ||||
| 		loadUsersAndChats(); | ||||
| 		startSyncThread(Config.getInstance().getSyncTimeout()); | ||||
|  | ||||
| 		if (client.isOnline()) startSyncThread(Config.getInstance().getSyncTimeout()); | ||||
|  | ||||
| 		contentPane.revalidate(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 */ | ||||
| 	public void changeChatWindowColors(String themeName) { | ||||
| 		Theme theme = Settings.getInstance().getThemes().get(themeName); | ||||
|  | ||||
| 	private void changeChatWindowColors(Theme theme) { | ||||
| 		// contentPane | ||||
| 		contentPane.setBackground(theme.getBackgroundColor()); | ||||
| 		contentPane.setForeground(theme.getUserNameColor()); | ||||
| @@ -261,8 +252,9 @@ public class ChatWindow extends JFrame { | ||||
| 		messageList.setForeground(theme.getMessageColorChat()); | ||||
| 		messageList.setBackground(theme.getCellColor()); | ||||
| 		// scrollPane | ||||
| 		scrollPane.setForeground(theme.getBackgroundColor()); | ||||
| 		scrollPane.setBackground(theme.getCellColor()); | ||||
| 		scrollPane.applyTheme(theme); | ||||
| 		scrollPane.autoscroll(); | ||||
|  | ||||
| 		// messageEnterTextArea | ||||
| 		messageEnterTextArea.setCaretColor(theme.getTypingMessageColor()); | ||||
| 		messageEnterTextArea.setForeground(theme.getTypingMessageColor()); | ||||
| @@ -316,9 +308,8 @@ public class ChatWindow extends JFrame { | ||||
| 	 */ | ||||
| 	private void loadUsersAndChats() { | ||||
| 		new Thread(() -> { | ||||
| 			Sync					users			= client.getUsersListXml(); | ||||
| 			DefaultListModel<User>	userListModel	= new DefaultListModel<>(); | ||||
| 			users.getUsers().forEach(user -> { | ||||
| 			DefaultListModel<User> userListModel = new DefaultListModel<>(); | ||||
| 			localDB.getUsers().values().forEach(user -> { | ||||
| 				userListModel.addElement(user); | ||||
|  | ||||
| 				// Check if user exists in local DB | ||||
| @@ -342,7 +333,11 @@ public class ChatWindow extends JFrame { | ||||
| 			new Thread(() -> { | ||||
|  | ||||
| 				// 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 | ||||
| 				localDB.addUnreadMessagesToLocalDB(); | ||||
|   | ||||
							
								
								
									
										63
									
								
								src/main/java/envoy/client/ui/PrimaryButton.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/main/java/envoy/client/ui/PrimaryButton.java
									
									
									
									
									
										Normal 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ä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; } | ||||
| } | ||||
							
								
								
									
										115
									
								
								src/main/java/envoy/client/ui/PrimaryScrollBar.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/main/java/envoy/client/ui/PrimaryScrollBar.java
									
									
									
									
									
										Normal 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ä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(); | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										83
									
								
								src/main/java/envoy/client/ui/PrimaryScrollPane.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/main/java/envoy/client/ui/PrimaryScrollPane.java
									
									
									
									
									
										Normal 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ä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; } | ||||
| } | ||||
							
								
								
									
										67
									
								
								src/main/java/envoy/client/ui/PrimaryTextArea.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								src/main/java/envoy/client/ui/PrimaryTextArea.java
									
									
									
									
									
										Normal 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ä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; } | ||||
| } | ||||
| @@ -28,14 +28,16 @@ import javax.swing.ListSelectionModel; | ||||
|  | ||||
| import envoy.client.Settings; | ||||
| 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. | ||||
|  *  | ||||
|  * | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>SettingsScreen.java</strong><br> | ||||
|  * Created: <strong>31 Oct 2019</strong><br> | ||||
|  *  | ||||
|  * | ||||
|  * @author Leon Hofmeister | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Kai S. K. Engelbart | ||||
| @@ -46,12 +48,12 @@ public class SettingsScreen extends JDialog { | ||||
| 	private final JPanel		contentPanel		= new JPanel(); | ||||
|  | ||||
| 	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				themeContent	= new JPanel(); | ||||
| 	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(); | ||||
|  | ||||
| @@ -61,11 +63,13 @@ public class SettingsScreen extends JDialog { | ||||
| 	private JButton	cancelButton			= new JButton("Cancel"); | ||||
|  | ||||
| 	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 SettingsScreen settingsScreen; | ||||
|  | ||||
| 	// TODO: Add a JPanel with all the Information necessary: | ||||
| 	// change (Picture,Username, Email, Password) and toggle(light/dark mode, | ||||
| 	// "ctrl+enter"/"enter" | ||||
| @@ -73,7 +77,7 @@ public class SettingsScreen extends JDialog { | ||||
|  | ||||
| 	/** | ||||
| 	 * Builds the settings screen. | ||||
| 	 *  | ||||
| 	 * | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public SettingsScreen() { | ||||
| @@ -121,11 +125,6 @@ public class SettingsScreen extends JDialog { | ||||
|  | ||||
| 			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(); | ||||
| 			gbc_optionsList.fill	= GridBagConstraints.BOTH; | ||||
| 			gbc_optionsList.gridx	= 0; | ||||
| @@ -147,9 +146,6 @@ public class SettingsScreen extends JDialog { | ||||
|  | ||||
| 			GridBagLayout gbl_themeLayout = new GridBagLayout(); | ||||
|  | ||||
| 			themeContent.setForeground(theme.getUserNameColor()); | ||||
| 			themeContent.setBackground(theme.getCellColor()); | ||||
|  | ||||
| 			gbl_themeLayout.columnWidths	= new int[] { 1, 1 }; | ||||
| 			gbl_themeLayout.rowHeights		= new int[] { 1, 1 }; | ||||
| 			gbl_themeLayout.columnWeights	= new double[] { 1.0, 1.0 }; | ||||
| @@ -157,8 +153,6 @@ public class SettingsScreen extends JDialog { | ||||
|  | ||||
| 			themeContent.setLayout(gbl_themeLayout); | ||||
|  | ||||
| 			themes.setBackground(theme.getUserNameColor()); | ||||
| 			themes.setForeground(theme.getBackgroundColor()); | ||||
| 			themes.setSelectedItem(Settings.getInstance().getCurrentTheme()); | ||||
|  | ||||
| 			themes.addItemListener(new ItemListener() { | ||||
| @@ -183,27 +177,27 @@ public class SettingsScreen extends JDialog { | ||||
| 			colorsPanel.setLayout(new BoxLayout(colorsPanel, BoxLayout.Y_AXIS)); | ||||
| 			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.getCellColor(), "Cells", 2); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getBackgroundColor(), "Background", 0); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getCellColor(), "Cells", 1); | ||||
| 			buildCustomizeElement(new JPanel(), | ||||
| 					new JButton(), | ||||
| 					new JTextPane(), | ||||
| 					theme, | ||||
| 					theme.getInteractableForegroundColor(), | ||||
| 					"Interactable Foreground", | ||||
| 					3); | ||||
| 					2); | ||||
| 			buildCustomizeElement(new JPanel(), | ||||
| 					new JButton(), | ||||
| 					new JTextPane(), | ||||
| 					theme, | ||||
| 					theme.getInteractableBackgroundColor(), | ||||
| 					"Interactable Background", | ||||
| 					4); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getMessageColorChat(), "Messages Chat", 5); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getDateColorChat(), "Date Chat", 6); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getSelectionColor(), "Selection", 7); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getTypingMessageColor(), "Typing Message", 8); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getUserNameColor(), "User Names", 9); | ||||
| 					3); | ||||
| 			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", 5); | ||||
| 			buildCustomizeElement(new JPanel(), new JButton(), new JTextPane(), theme, theme.getSelectionColor(), "Selection", 6); | ||||
| 			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", 8); | ||||
|  | ||||
| 			GridBagConstraints gbc_colorsPanel = new GridBagConstraints(); | ||||
| 			gbc_colorsPanel.fill		= GridBagConstraints.HORIZONTAL; | ||||
| @@ -239,8 +233,6 @@ public class SettingsScreen extends JDialog { | ||||
| 					contentPanel.revalidate(); | ||||
| 					contentPanel.repaint(); | ||||
|  | ||||
| 					// TODO: Create new Theme | ||||
|  | ||||
| 				} catch (Exception e) { | ||||
| 					logger.info("New theme couldn't be created! " + e); | ||||
| 					e.printStackTrace(); | ||||
| @@ -287,18 +279,15 @@ public class SettingsScreen extends JDialog { | ||||
| 				getRootPane().setDefaultButton(okButton); | ||||
| 				okButton.addActionListener((evt) -> { | ||||
| 					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().setCurrentTheme(selectedTheme.getThemeName()); | ||||
| 						logger.log(Level.FINER, selectedTheme.getThemeName()); | ||||
|  | ||||
| 						changeSettingsScreenColors(Settings.getInstance().getCurrentTheme()); | ||||
| 						updateColorVariables(Settings.getInstance().getCurrentTheme()); | ||||
|  | ||||
| 						final Theme currentTheme = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()); | ||||
| 						changeSettingsScreenColors(currentTheme); | ||||
| 						updateColorVariables(currentTheme); | ||||
| 						EventBus.getInstance().dispatch(new ThemeChangeEvent(currentTheme)); | ||||
| 						Settings.getInstance().save(); | ||||
|  | ||||
| 						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); | ||||
| 	} | ||||
|  | ||||
| 	private void changeSettingsScreenColors(String key) { | ||||
| 		Theme theme = Settings.getInstance().getThemes().get(key); | ||||
| 	private void changeSettingsScreenColors(Theme theme) { | ||||
| 		// whole JDialog | ||||
| 		setBackground(theme.getBackgroundColor()); | ||||
| 		// contentPanel | ||||
| @@ -340,8 +329,8 @@ public class SettingsScreen extends JDialog { | ||||
| 		themeContent.setForeground(theme.getUserNameColor()); | ||||
| 		themeContent.setBackground(theme.getCellColor()); | ||||
| 		// themes | ||||
| 		themes.setBackground(theme.getUserNameColor()); | ||||
| 		themes.setForeground(theme.getBackgroundColor()); | ||||
| 		themes.setBackground(theme.getBackgroundColor()); | ||||
| 		themes.setForeground(getInvertedColor(theme.getBackgroundColor())); | ||||
|  | ||||
| 		createNewThemeButton.setBackground(theme.getInteractableBackgroundColor()); | ||||
| 		createNewThemeButton.setForeground(theme.getInteractableForegroundColor()); | ||||
| @@ -349,19 +338,8 @@ public class SettingsScreen extends JDialog { | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	private void updateColorVariables(String key) { | ||||
| 		Theme theme = Settings.getInstance().getThemes().get(key); | ||||
|  | ||||
| 		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()); | ||||
| 	private void updateColorVariables(Theme theme) { | ||||
| 		temporaryTheme = new Theme("temporaryTheme", theme); | ||||
|  | ||||
| 		colorsPanel.removeAll(); | ||||
|  | ||||
| @@ -372,7 +350,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getBackgroundColor(), | ||||
| 				"Background", | ||||
| 				1); | ||||
| 				0); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -380,7 +358,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getCellColor(), | ||||
| 				"Cells", | ||||
| 				2); | ||||
| 				1); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -388,7 +366,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getInteractableForegroundColor(), | ||||
| 				"Interactable Foreground", | ||||
| 				3); | ||||
| 				2); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -396,7 +374,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getInteractableBackgroundColor(), | ||||
| 				"Interactable Background", | ||||
| 				4); | ||||
| 				3); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -404,7 +382,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getMessageColorChat(), | ||||
| 				"Messages Chat", | ||||
| 				5); | ||||
| 				4); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -412,7 +390,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getDateColorChat(), | ||||
| 				"Date Chat", | ||||
| 				6); | ||||
| 				5); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -420,7 +398,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getSelectionColor(), | ||||
| 				"Selection", | ||||
| 				7); | ||||
| 				6); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -428,7 +406,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getTypingMessageColor(), | ||||
| 				"Typing Message", | ||||
| 				8); | ||||
| 				7); | ||||
| 		buildCustomizeElement(new JPanel(), | ||||
|  | ||||
| 				new JButton(), | ||||
| @@ -436,7 +414,7 @@ public class SettingsScreen extends JDialog { | ||||
| 				theme, | ||||
| 				theme.getUserNameColor(), | ||||
| 				"User Names", | ||||
| 				9); | ||||
| 				8); | ||||
|  | ||||
| 		GridBagConstraints gbc_createNewTheme = new GridBagConstraints(); | ||||
| 		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) { | ||||
| 		textPane.setFont(new Font("Arial", Font.PLAIN, 14)); | ||||
| 		textPane.setBackground(theme.getBackgroundColor()); | ||||
| 		textPane.setForeground(theme.getUserNameColor()); | ||||
| 		textPane.setForeground(getInvertedColor(theme.getBackgroundColor())); | ||||
| 		textPane.setText(name); | ||||
| 		textPane.setEditable(false); | ||||
|  | ||||
| @@ -461,18 +439,13 @@ public class SettingsScreen extends JDialog { | ||||
| 			try { | ||||
| 				Color newColor = JColorChooser.showDialog(null, "Choose a color", color); | ||||
| 				if (newColor.getRGB() != color.getRGB()) { | ||||
| 					logger.log(Level.FINEST, String.valueOf(color.getRGB())); | ||||
| 					Color[] colorsArray = temporaryTheme.getAllColors(); | ||||
| 					for (int i = 0; i < colorsArray.length; i++) { | ||||
| 						if (color.getRGB() == colorsArray[i].getRGB()) { | ||||
| 							temporaryTheme.setColor(i, newColor); | ||||
| 							createNewThemeButton.setEnabled(true); | ||||
| 							break; | ||||
| 						} | ||||
|  | ||||
| 					} | ||||
| 					button.setBackground(newColor); | ||||
| 					logger.log(Level.FINEST, "New Color: " + String.valueOf(color.getRGB())); | ||||
| 					// TODO: When Theme changed in same settings screen, color variable doesnt | ||||
| 					// update. | ||||
| 					temporaryTheme.setColor(yIndex, newColor); | ||||
| 					createNewThemeButton.setEnabled(true); | ||||
| 				} | ||||
| 				button.setBackground(newColor); | ||||
|  | ||||
| 			} catch (Exception e) { | ||||
| 				logger.info("An error occured while opening Color Chooser: " + e); | ||||
| @@ -488,4 +461,5 @@ public class SettingsScreen extends JDialog { | ||||
| 		colorsPanel.add(panel); | ||||
| 	} | ||||
|  | ||||
| 	private Color getInvertedColor(Color color) { return new Color(255 - color.getRed(), 255 - color.getGreen(), 255 - color.getBlue()); } | ||||
| } | ||||
|   | ||||
| @@ -2,9 +2,9 @@ package envoy.client.ui; | ||||
|  | ||||
| import java.awt.EventQueue; | ||||
| import java.io.IOException; | ||||
| import java.util.Properties; | ||||
| import java.util.logging.Logger; | ||||
|  | ||||
| import javax.swing.JFrame; | ||||
| import javax.swing.JOptionPane; | ||||
|  | ||||
| import envoy.client.Client; | ||||
| @@ -12,11 +12,13 @@ import envoy.client.Config; | ||||
| import envoy.client.LocalDB; | ||||
| import envoy.client.Settings; | ||||
| import envoy.client.util.EnvoyLog; | ||||
|  | ||||
| import envoy.exception.EnvoyException; | ||||
| import envoy.schema.User; | ||||
|  | ||||
| /** | ||||
|  * Starts the Envoy client and prompts the user to enter their name. | ||||
|  *  | ||||
|  * <br> | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>Startup.java</strong><br> | ||||
|  * Created: <strong>12 Oct 2019</strong><br> | ||||
| @@ -33,34 +35,69 @@ public class Startup { | ||||
| 	public static void main(String[] args) { | ||||
| 		Config config = Config.getInstance(); | ||||
|  | ||||
| 		// Load the configuration from client.properties first | ||||
| 		ClassLoader loader = Thread.currentThread().getContextClassLoader(); | ||||
| 		try { | ||||
| 			Properties configProperties = new Properties(); | ||||
| 			configProperties.load(loader.getResourceAsStream("client.properties")); | ||||
| 			config.load(configProperties); | ||||
| 		} catch (IOException e) { | ||||
| 			// Load the configuration from client.properties first | ||||
| 			config.load(); | ||||
|  | ||||
| 			// 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(); | ||||
| 		} | ||||
|  | ||||
| 		// Override configuration values with command line arguments | ||||
| 		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); | ||||
| 		} | ||||
|  | ||||
| 		// Ask the user for their user name | ||||
| 		String userName = JOptionPane.showInputDialog("Please enter your username"); | ||||
| 		if (userName == null || userName.isEmpty()) { | ||||
| 			logger.severe("User name is not set or empty. Exiting..."); | ||||
| 			System.exit(1); | ||||
| 		} | ||||
| 		Client	client	= new Client(config, userName); | ||||
| 		LocalDB	localDB	= new LocalDB(client.getSender()); | ||||
| 		 | ||||
| 		// Initialize the local database | ||||
| 		LocalDB localDB; | ||||
| 		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) { | ||||
| 			e.printStackTrace(); | ||||
| 			JOptionPane.showMessageDialog(null, | ||||
| @@ -68,8 +105,13 @@ public class Startup { | ||||
| 					"Local DB error", | ||||
| 					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(() -> { | ||||
| 			try { | ||||
| 				ChatWindow chatWindow = new ChatWindow(client, localDB); | ||||
| @@ -77,6 +119,9 @@ public class Startup { | ||||
|  | ||||
| 				try { | ||||
| 					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) { | ||||
| 					logger.warning("The StatusTrayIcon is not supported on this platform!"); | ||||
| 				} | ||||
|   | ||||
| @@ -11,12 +11,8 @@ 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; | ||||
| @@ -29,7 +25,7 @@ import envoy.schema.Message; | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @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 | ||||
| @@ -81,8 +77,14 @@ public class StatusTrayIcon implements EventHandler { | ||||
| 			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 | ||||
| 		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); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,179 +1,161 @@ | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Color; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>Theme.java</strong><br> | ||||
|  * Created: <strong>23 Nov 2019</strong><br> | ||||
|  *  | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.2-alpha | ||||
|  */ | ||||
| public class Theme implements Serializable { | ||||
|  | ||||
| 	private static final long serialVersionUID = 141727847527060352L; | ||||
|  | ||||
| 	private String	themeName; | ||||
| 	private Color	backgroundColor; | ||||
| 	private Color	cellColor; | ||||
| 	private Color	interactableBackgroundColor; | ||||
| 	private Color	userNameColor; | ||||
| 	private Color	interactableForegroundColor; | ||||
| 	private Color	messageColorChat; | ||||
| 	private Color	dateColorChat; | ||||
| 	private Color	selectionColor; | ||||
| 	private Color	typingMessageColor; | ||||
|  | ||||
| 	public Theme(String themeName, Color backgroundColor, Color cellColor, Color interactableForegroundColor, Color interactableBackgroundColor, | ||||
| 			Color messageColorChat, Color dateColorChat, Color selectionColor, Color typingMessageColor, Color userNameColor) { | ||||
|  | ||||
| 		this.themeName = themeName; | ||||
|  | ||||
| 		this.backgroundColor				= backgroundColor; | ||||
| 		this.cellColor						= cellColor; | ||||
| 		this.interactableForegroundColor	= interactableForegroundColor; | ||||
| 		this.interactableBackgroundColor	= interactableBackgroundColor; | ||||
| 		this.messageColorChat				= messageColorChat; | ||||
| 		this.dateColorChat					= dateColorChat; | ||||
| 		this.selectionColor					= selectionColor; | ||||
| 		this.typingMessageColor				= typingMessageColor; | ||||
| 		this.userNameColor					= userNameColor; | ||||
| 	} | ||||
|  | ||||
| 	public Theme(String name, Theme other) { | ||||
| 		this(name, other.backgroundColor, other.cellColor, other.interactableBackgroundColor, other.interactableForegroundColor, | ||||
| 				other.messageColorChat, other.dateColorChat, other.selectionColor, other.typingMessageColor, other.userNameColor); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return name of the theme | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public String getThemeName() { return themeName; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return interactableForegroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getInteractableForegroundColor() { return interactableForegroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return messageColorChat | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getMessageColorChat() { return messageColorChat; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return dateColorChat | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getDateColorChat() { return dateColorChat; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return selectionColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getSelectionColor() { return selectionColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return typingMessageColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getTypingMessageColor() { return typingMessageColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return backgroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getBackgroundColor() { return backgroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return cellColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getCellColor() { return cellColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return interactableBackgroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getInteractableBackgroundColor() { return interactableBackgroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return userNameColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getUserNameColor() { return userNameColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return a color array containing all colors of this theme | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color[] getAllColors() { | ||||
| 		Color[] c = new Color[9]; | ||||
| 		c[0]	= backgroundColor; | ||||
| 		c[1]	= cellColor; | ||||
| 		c[2]	= interactableForegroundColor; | ||||
| 		c[3]	= interactableBackgroundColor; | ||||
| 		c[4]	= messageColorChat; | ||||
| 		c[5]	= dateColorChat; | ||||
| 		c[6]	= selectionColor; | ||||
| 		c[7]	= typingMessageColor; | ||||
| 		c[8]	= userNameColor; | ||||
|  | ||||
| 		return c; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the a specific {@link Color} in this theme to a new {@link Color} | ||||
| 	 *  | ||||
| 	 * @param index    - index of the color </br> | ||||
| 	 *                 0 = backgroundColor </br> | ||||
| 	 *                 1 = cellColor </br> | ||||
| 	 *                 2 = interactableForegroundColor </br> | ||||
| 	 *                 3 = interactableBackgroundColor </br> | ||||
| 	 *                 4 = messageColorChat </br> | ||||
| 	 *                 5 = dateColorChat </br> | ||||
| 	 *                 6 = selectionColor </br> | ||||
| 	 *                 7 = typingMessageColor </br> | ||||
| 	 *                 8 = userNameColor </br> | ||||
| 	 *                 </br> | ||||
| 	 *  | ||||
| 	 * @param newColor - new {@link Color} to be set | ||||
| 	 * @since Envoy 0.2-alpha | ||||
| 	 */ | ||||
| 	public void setColor(int index, Color newColor) { | ||||
| 		switch (index) { | ||||
| 			case 0: | ||||
| 				this.backgroundColor = newColor; | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				this.cellColor = newColor; | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				this.interactableForegroundColor = newColor; | ||||
| 				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; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Color; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>Theme.java</strong><br> | ||||
|  * Created: <strong>23 Nov 2019</strong><br> | ||||
|  *  | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.2-alpha | ||||
|  */ | ||||
| public class Theme implements Serializable { | ||||
|  | ||||
| 	private static final long serialVersionUID = 141727847527060352L; | ||||
|  | ||||
| 	private String	themeName; | ||||
| 	private Color	backgroundColor; | ||||
| 	private Color	cellColor; | ||||
| 	private Color	interactableBackgroundColor; | ||||
| 	private Color	userNameColor; | ||||
| 	private Color	interactableForegroundColor; | ||||
| 	private Color	messageColorChat; | ||||
| 	private Color	dateColorChat; | ||||
| 	private Color	selectionColor; | ||||
| 	private Color	typingMessageColor; | ||||
|  | ||||
| 	public Theme(String themeName, Color backgroundColor, Color cellColor, Color interactableForegroundColor, Color interactableBackgroundColor, | ||||
| 			Color messageColorChat, Color dateColorChat, Color selectionColor, Color typingMessageColor, Color userNameColor) { | ||||
|  | ||||
| 		this.themeName = themeName; | ||||
|  | ||||
| 		this.backgroundColor				= backgroundColor; | ||||
| 		this.cellColor						= cellColor; | ||||
| 		this.interactableForegroundColor	= interactableForegroundColor; | ||||
| 		this.interactableBackgroundColor	= interactableBackgroundColor; | ||||
| 		this.messageColorChat				= messageColorChat; | ||||
| 		this.dateColorChat					= dateColorChat; | ||||
| 		this.selectionColor					= selectionColor; | ||||
| 		this.typingMessageColor				= typingMessageColor; | ||||
| 		this.userNameColor					= userNameColor; | ||||
| 	} | ||||
|  | ||||
| 	public Theme(String name, Theme other) { | ||||
| 		this(name, other.backgroundColor, other.cellColor, other.interactableForegroundColor, | ||||
| 				other.interactableBackgroundColor, other.messageColorChat, other.dateColorChat, other.selectionColor, | ||||
| 				other.typingMessageColor, other.userNameColor); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return name of the theme | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public String getThemeName() { return themeName; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return interactableForegroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getInteractableForegroundColor() { return interactableForegroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return messageColorChat | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getMessageColorChat() { return messageColorChat; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return dateColorChat | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getDateColorChat() { return dateColorChat; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return selectionColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getSelectionColor() { return selectionColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return typingMessageColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getTypingMessageColor() { return typingMessageColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return backgroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getBackgroundColor() { return backgroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return cellColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getCellColor() { return cellColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return interactableBackgroundColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getInteractableBackgroundColor() { return interactableBackgroundColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @return userNameColor | ||||
| 	 * @since Envoy v0.2-alpha | ||||
| 	 */ | ||||
| 	public Color getUserNameColor() { return userNameColor; } | ||||
|  | ||||
| 	/** | ||||
| 	 * Sets the a specific {@link Color} in this theme to a new {@link Color} | ||||
| 	 *  | ||||
| 	 * @param index    - index of the color </br> | ||||
| 	 *                 0 = backgroundColor </br> | ||||
| 	 *                 1 = cellColor </br> | ||||
| 	 *                 2 = interactableForegroundColor </br> | ||||
| 	 *                 3 = interactableBackgroundColor </br> | ||||
| 	 *                 4 = messageColorChat </br> | ||||
| 	 *                 5 = dateColorChat </br> | ||||
| 	 *                 6 = selectionColor </br> | ||||
| 	 *                 7 = typingMessageColor </br> | ||||
| 	 *                 8 = userNameColor </br> | ||||
| 	 *                 </br> | ||||
| 	 *  | ||||
| 	 * @param newColor - new {@link Color} to be set | ||||
| 	 * @since Envoy 0.2-alpha | ||||
| 	 */ | ||||
| 	public void setColor(int index, Color newColor) { | ||||
| 		switch (index) { | ||||
| 			case 0: | ||||
| 				this.backgroundColor = newColor; | ||||
| 				break; | ||||
| 			case 1: | ||||
| 				this.cellColor = newColor; | ||||
| 				break; | ||||
| 			case 2: | ||||
| 				this.interactableForegroundColor = newColor; | ||||
| 				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; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 delvh
					delvh