Merge pull request #93 from informatik-ag-ngl/f/component_list
Component List
This commit is contained in:
		@@ -28,11 +28,5 @@
 | 
				
			|||||||
			<attribute name="maven.pomderived" value="true"/>
 | 
								<attribute name="maven.pomderived" value="true"/>
 | 
				
			||||||
		</attributes>
 | 
							</attributes>
 | 
				
			||||||
	</classpathentry>
 | 
						</classpathentry>
 | 
				
			||||||
	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
 | 
					 | 
				
			||||||
		<attributes>
 | 
					 | 
				
			||||||
			<attribute name="maven.pomderived" value="true"/>
 | 
					 | 
				
			||||||
			<attribute name="test" value="true"/>
 | 
					 | 
				
			||||||
		</attributes>
 | 
					 | 
				
			||||||
	</classpathentry>
 | 
					 | 
				
			||||||
	<classpathentry kind="output" path="target/classes"/>
 | 
						<classpathentry kind="output" path="target/classes"/>
 | 
				
			||||||
</classpath>
 | 
					</classpath>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								pom.xml
									
									
									
									
									
								
							@@ -28,11 +28,16 @@
 | 
				
			|||||||
		<dependency>
 | 
							<dependency>
 | 
				
			||||||
			<groupId>com.github.informatik-ag-ngl</groupId>
 | 
								<groupId>com.github.informatik-ag-ngl</groupId>
 | 
				
			||||||
			<artifactId>envoy-common</artifactId>
 | 
								<artifactId>envoy-common</artifactId>
 | 
				
			||||||
			<version>e5c67b8</version>
 | 
								<version>develop-SNAPSHOT</version>
 | 
				
			||||||
		</dependency>
 | 
							</dependency>
 | 
				
			||||||
	</dependencies>
 | 
						</dependencies>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<build>
 | 
						<build>
 | 
				
			||||||
		<finalName>envoy-client</finalName>
 | 
							<finalName>envoy-client</finalName>
 | 
				
			||||||
 | 
							<resources>
 | 
				
			||||||
 | 
								<resource>
 | 
				
			||||||
 | 
									<directory>src/main/resources</directory>
 | 
				
			||||||
 | 
								</resource>
 | 
				
			||||||
 | 
							</resources>
 | 
				
			||||||
	</build>
 | 
						</build>
 | 
				
			||||||
</project>
 | 
					</project>
 | 
				
			||||||
@@ -2,9 +2,9 @@ package envoy.client;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.io.Serializable;
 | 
					import java.io.Serializable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.swing.DefaultListModel;
 | 
					import envoy.client.ui.list.ComponentListModel;
 | 
				
			||||||
 | 
					 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
 | 
					import envoy.data.Message.MessageStatus;
 | 
				
			||||||
import envoy.data.User;
 | 
					import envoy.data.User;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -25,7 +25,7 @@ public class Chat implements Serializable {
 | 
				
			|||||||
	private static final long serialVersionUID = -7751248474547242056L;
 | 
						private static final long serialVersionUID = -7751248474547242056L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private User						recipient;
 | 
						private User						recipient;
 | 
				
			||||||
	private DefaultListModel<Message>	model	= new DefaultListModel<>();
 | 
						private ComponentListModel<Message>	model	= new ComponentListModel<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Provides the list of messages that the recipient receives.<br>
 | 
						 * Provides the list of messages that the recipient receives.<br>
 | 
				
			||||||
@@ -37,22 +37,34 @@ public class Chat implements Serializable {
 | 
				
			|||||||
	public Chat(User recipient) { this.recipient = recipient; }
 | 
						public Chat(User recipient) { this.recipient = recipient; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the recipient of a message
 | 
						 * Appends a message to the bottom of this chat
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param message the message to append
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public User getRecipient() { return recipient; }
 | 
						public void appendMessage(Message message) { model.add(message); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Adds the received message at the current Point in the current chat
 | 
						 * Sets the status of all chat messages to {@code READ} starting from the bottom
 | 
				
			||||||
 | 
						 * and stopping once a read message is found.
 | 
				
			||||||
	 * 
 | 
						 * 
 | 
				
			||||||
	 * @param message the message to add in said chat
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void appendMessage(Message message) { model.addElement(message); }
 | 
						public void read() {
 | 
				
			||||||
 | 
							for (int i = model.size() - 1; i >= 0; --i)
 | 
				
			||||||
 | 
								if (model.get(i).getStatus() == MessageStatus.READ) break;
 | 
				
			||||||
 | 
								else model.get(i).setStatus(MessageStatus.READ);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return all messages in the current chat
 | 
						 * @return all messages in the current chat
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public DefaultListModel<Message> getModel() { return model; }
 | 
						public ComponentListModel<Message> getModel() { return model; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return the recipient of a message
 | 
				
			||||||
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public User getRecipient() { return recipient; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -11,6 +11,7 @@ import javax.naming.TimeLimitExceededException;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import envoy.client.util.EnvoyLog;
 | 
					import envoy.client.util.EnvoyLog;
 | 
				
			||||||
import envoy.data.*;
 | 
					import envoy.data.*;
 | 
				
			||||||
 | 
					import envoy.event.IdGeneratorRequest;
 | 
				
			||||||
import envoy.util.SerializationUtils;
 | 
					import envoy.util.SerializationUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -45,11 +46,13 @@ public class Client implements Closeable {
 | 
				
			|||||||
	 * an exception is thrown.
 | 
						 * an exception is thrown.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @param credentials the login credentials of the user
 | 
						 * @param credentials the login credentials of the user
 | 
				
			||||||
 | 
						 * @param localDB     the local database used to persist the current
 | 
				
			||||||
 | 
						 *                    {@link IdGenerator}
 | 
				
			||||||
	 * @throws Exception if the online mode could not be entered or the request
 | 
						 * @throws Exception if the online mode could not be entered or the request
 | 
				
			||||||
	 *                   failed for some other reason
 | 
						 *                   failed for some other reason
 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void onlineInit(LoginCredentials credentials) throws Exception {
 | 
						public void onlineInit(LoginCredentials credentials, LocalDB localDB) throws Exception {
 | 
				
			||||||
		// Establish TCP connection
 | 
							// Establish TCP connection
 | 
				
			||||||
		logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
 | 
							logger.info(String.format("Attempting connection to server %s:%d...", config.getServer(), config.getPort()));
 | 
				
			||||||
		socket = new Socket(config.getServer(), config.getPort());
 | 
							socket = new Socket(config.getServer(), config.getPort());
 | 
				
			||||||
@@ -84,6 +87,13 @@ public class Client implements Closeable {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// Register processors for message and status handling
 | 
							// Register processors for message and status handling
 | 
				
			||||||
		receiver.registerProcessor(Message.class, new ReceivedMessageProcessor());
 | 
							receiver.registerProcessor(Message.class, new ReceivedMessageProcessor());
 | 
				
			||||||
 | 
							// TODO: Status handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Process message ID generation
 | 
				
			||||||
 | 
							receiver.registerProcessor(IdGenerator.class, localDB::setIdGenerator);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Request a generator if none is present
 | 
				
			||||||
 | 
							if (!localDB.hasIdGenerator() || !localDB.getIdGenerator().hasNext()) requestIdGenerator();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -94,11 +104,21 @@ public class Client implements Closeable {
 | 
				
			|||||||
	 * @since Envoy v0.3-alpha
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void sendMessage(Message message) throws IOException {
 | 
						public void sendMessage(Message message) throws IOException {
 | 
				
			||||||
		checkOnline();
 | 
							writeObject(message);
 | 
				
			||||||
		SerializationUtils.writeBytesWithLength(message, socket.getOutputStream());
 | 
					 | 
				
			||||||
		message.nextStatus();
 | 
							message.nextStatus();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Requests a new {@link IdGenerator} from the server.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @throws IOException if the request does not reach the server
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void requestIdGenerator() throws IOException {
 | 
				
			||||||
 | 
							logger.info("Requesting new id generator...");
 | 
				
			||||||
 | 
							writeObject(new IdGeneratorRequest());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return a {@code Map<String, User>} of all users on the server with their
 | 
						 * @return a {@code Map<String, User>} of all users on the server with their
 | 
				
			||||||
	 *         user names as keys
 | 
						 *         user names as keys
 | 
				
			||||||
@@ -114,6 +134,11 @@ public class Client implements Closeable {
 | 
				
			|||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void close() throws IOException { if (online) socket.close(); }
 | 
						public void close() throws IOException { if (online) socket.close(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private void writeObject(Object obj) throws IOException {
 | 
				
			||||||
 | 
							checkOnline();
 | 
				
			||||||
 | 
							SerializationUtils.writeBytesWithLength(obj, socket.getOutputStream());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void checkOnline() { if (!online) throw new IllegalStateException("Client is not online"); }
 | 
						private void checkOnline() { if (!online) throw new IllegalStateException("Client is not online"); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,6 @@ public class Config {
 | 
				
			|||||||
		items.put("server", new ConfigItem<>("server", "s", (input) -> input, null));
 | 
							items.put("server", new ConfigItem<>("server", "s", (input) -> input, null));
 | 
				
			||||||
		items.put("port", new ConfigItem<>("port", "p", (input) -> Integer.parseInt(input), null));
 | 
							items.put("port", new ConfigItem<>("port", "p", (input) -> Integer.parseInt(input), null));
 | 
				
			||||||
		items.put("localDB", new ConfigItem<>("localDB", "db", (input) -> new File(input), new File("localDB")));
 | 
							items.put("localDB", new ConfigItem<>("localDB", "db", (input) -> new File(input), new File("localDB")));
 | 
				
			||||||
		items.put("syncTimeout", new ConfigItem<>("syncTimeout", "st", (input) -> Integer.parseInt(input), 1000));
 | 
					 | 
				
			||||||
		items.put("homeDirectory",
 | 
							items.put("homeDirectory",
 | 
				
			||||||
				new ConfigItem<>("homeDirectory", "h", (input) -> new File(input), new File(System.getProperty("user.home"), ".envoy")));
 | 
									new ConfigItem<>("homeDirectory", "h", (input) -> new File(input), new File(System.getProperty("user.home"), ".envoy")));
 | 
				
			||||||
		items.put("fileLevelBarrier", new ConfigItem<>("fileLevelBarrier", "fb", (input) -> Level.parse(input), Level.CONFIG));
 | 
							items.put("fileLevelBarrier", new ConfigItem<>("fileLevelBarrier", "fb", (input) -> Level.parse(input), Level.CONFIG));
 | 
				
			||||||
@@ -112,7 +111,7 @@ public class Config {
 | 
				
			|||||||
	 * @return the port at which the Envoy server is located on the host
 | 
						 * @return the port at which the Envoy server is located on the host
 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
						 * @since Envoy v0.1-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public int getPort() { return (int) items.get("port").get(); }
 | 
						public Integer getPort() { return (Integer) items.get("port").get(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the local database specific to the client user
 | 
						 * @return the local database specific to the client user
 | 
				
			||||||
@@ -120,12 +119,6 @@ public class Config {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public File getLocalDB() { return (File) items.get("localDB").get(); }
 | 
						public File getLocalDB() { return (File) items.get("localDB").get(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * @return the current time (milliseconds) that is waited between Syncs
 | 
					 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public int getSyncTimeout() { return (int) items.get("syncTimeout").get(); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return the directory in which all local files are saves
 | 
						 * @return the directory in which all local files are saves
 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,10 +4,15 @@ import java.io.File;
 | 
				
			|||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.*;
 | 
					import java.util.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import envoy.data.IdGenerator;
 | 
				
			||||||
import envoy.data.User;
 | 
					import envoy.data.User;
 | 
				
			||||||
import envoy.util.SerializationUtils;
 | 
					import envoy.util.SerializationUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 | 
					 * Stored information about the current {@link User} and their {@link Chat}s.
 | 
				
			||||||
 | 
					 * For message ID generation a {@link IdGenerator} is stored as well.
 | 
				
			||||||
 | 
					 * These object are persisted inside a folder of the local file system.<br>
 | 
				
			||||||
 | 
					 * <br>
 | 
				
			||||||
 * Project: <strong>envoy-client</strong><br>
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 * File: <strong>LocalDB.java</strong><br>
 | 
					 * File: <strong>LocalDB.java</strong><br>
 | 
				
			||||||
 * Created: <strong>27.10.2019</strong><br>
 | 
					 * Created: <strong>27.10.2019</strong><br>
 | 
				
			||||||
@@ -18,10 +23,11 @@ import envoy.util.SerializationUtils;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class LocalDB {
 | 
					public class LocalDB {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private File				localDBDir, localDBFile, usersFile;
 | 
						private File				localDBDir, localDBFile, usersFile, idGeneratorFile;
 | 
				
			||||||
	private User				user;
 | 
						private User				user;
 | 
				
			||||||
	private Map<String, User>	users	= new HashMap<>();
 | 
						private Map<String, User>	users	= new HashMap<>();
 | 
				
			||||||
	private List<Chat>			chats	= new ArrayList<>();
 | 
						private List<Chat>			chats	= new ArrayList<>();
 | 
				
			||||||
 | 
						private IdGenerator			idGenerator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Constructs an empty local database. To serialize any chats to the file
 | 
						 * Constructs an empty local database. To serialize any chats to the file
 | 
				
			||||||
@@ -38,6 +44,7 @@ public class LocalDB {
 | 
				
			|||||||
		if (localDBDir.exists() && !localDBDir.isDirectory())
 | 
							if (localDBDir.exists() && !localDBDir.isDirectory())
 | 
				
			||||||
			throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath()));
 | 
								throw new IOException(String.format("LocalDBDir '%s' is not a directory!", localDBDir.getAbsolutePath()));
 | 
				
			||||||
		usersFile		= new File(localDBDir, "users.db");
 | 
							usersFile		= new File(localDBDir, "users.db");
 | 
				
			||||||
 | 
							idGeneratorFile	= new File(localDBDir, "id_generator.db");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -53,7 +60,8 @@ public class LocalDB {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Stores all users to the local database. If the client user is specified, the
 | 
						 * Stores all users to the local database. If the client user is specified, the
 | 
				
			||||||
	 * chats related to this user are stored as well.
 | 
						 * chats related to this user are stored as well. The message id generator will
 | 
				
			||||||
 | 
						 * also be saved if present.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @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
 | 
				
			||||||
@@ -63,7 +71,10 @@ public class LocalDB {
 | 
				
			|||||||
		SerializationUtils.write(usersFile, users);
 | 
							SerializationUtils.write(usersFile, users);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Save chats
 | 
							// Save chats
 | 
				
			||||||
		SerializationUtils.write(localDBFile, chats);
 | 
							if (user != null) SerializationUtils.write(localDBFile, chats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Save id generator
 | 
				
			||||||
 | 
							if (hasIdGenerator()) SerializationUtils.write(idGeneratorFile, idGenerator);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -84,6 +95,18 @@ public class LocalDB {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void loadChats() throws ClassNotFoundException, IOException { chats = SerializationUtils.read(localDBFile, ArrayList.class); }
 | 
						public void loadChats() throws ClassNotFoundException, IOException { chats = SerializationUtils.read(localDBFile, ArrayList.class); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Loads the message ID generator that is stored in the local database. If the
 | 
				
			||||||
 | 
						 * file is not found, the exception is ignored.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void loadIdGenerator() {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								idGenerator = SerializationUtils.read(idGeneratorFile, IdGenerator.class);
 | 
				
			||||||
 | 
							} catch (ClassNotFoundException | IOException e) {}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * @return a {@code Map<String, User>} of all users stored locally with their
 | 
						 * @return a {@code Map<String, User>} of all users stored locally with their
 | 
				
			||||||
	 *         user names as keys
 | 
						 *         user names as keys
 | 
				
			||||||
@@ -119,4 +142,22 @@ public class LocalDB {
 | 
				
			|||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void setUser(User user) { this.user = user; }
 | 
						public void setUser(User user) { this.user = user; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return the message ID generator
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public IdGenerator getIdGenerator() { return idGenerator; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @param idGenerator the message ID generator to set
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void setIdGenerator(IdGenerator idGenerator) { this.idGenerator = idGenerator; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return {@code true} if an {@link IdGenerator} is present
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public boolean hasIdGenerator() { return idGenerator != null; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -135,7 +135,7 @@ public class Settings {
 | 
				
			|||||||
	 *         {@code Control} key.
 | 
						 *         {@code Control} key.
 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public boolean isEnterToSend() { return (boolean) items.get("enterToSend").get(); }
 | 
						public Boolean isEnterToSend() { return (Boolean) items.get("enterToSend").get(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Changes the keystrokes performed by the user to send a message.
 | 
						 * Changes the keystrokes performed by the user to send a message.
 | 
				
			||||||
@@ -152,7 +152,7 @@ public class Settings {
 | 
				
			|||||||
	 * @return the current on close mode.
 | 
						 * @return the current on close mode.
 | 
				
			||||||
	 * @since Envoy v0.3-alpha
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public boolean getCurrentOnCloseMode() { return (boolean) items.get("onCloseMode").get(); }
 | 
						public Boolean getCurrentOnCloseMode() { return (Boolean) items.get("onCloseMode").get(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Sets the current on close mode.
 | 
						 * Sets the current on close mode.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,9 @@ import javax.swing.*;
 | 
				
			|||||||
import javax.swing.border.EmptyBorder;
 | 
					import javax.swing.border.EmptyBorder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.*;
 | 
					import envoy.client.*;
 | 
				
			||||||
 | 
					import envoy.client.event.MessageCreationEvent;
 | 
				
			||||||
import envoy.client.event.ThemeChangeEvent;
 | 
					import envoy.client.event.ThemeChangeEvent;
 | 
				
			||||||
 | 
					import envoy.client.ui.list.ComponentList;
 | 
				
			||||||
import envoy.client.ui.settings.SettingsScreen;
 | 
					import envoy.client.ui.settings.SettingsScreen;
 | 
				
			||||||
import envoy.client.util.EnvoyLog;
 | 
					import envoy.client.util.EnvoyLog;
 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
@@ -30,8 +32,6 @@ import envoy.event.EventBus;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
public class ChatWindow extends JFrame {
 | 
					public class ChatWindow extends JFrame {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static final long serialVersionUID = 6865098428255463649L;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// User specific objects
 | 
						// User specific objects
 | 
				
			||||||
	private Client	client;
 | 
						private Client	client;
 | 
				
			||||||
	private LocalDB	localDB;
 | 
						private LocalDB	localDB;
 | 
				
			||||||
@@ -41,16 +41,20 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
	private PrimaryTextArea			messageEnterTextArea	= new PrimaryTextArea(space);
 | 
						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 ComponentList<Message>	messageList				= new ComponentList<>(new MessageListRenderer());
 | 
				
			||||||
	private PrimaryScrollPane		scrollPane				= new PrimaryScrollPane();
 | 
						private PrimaryScrollPane		scrollPane				= new PrimaryScrollPane();
 | 
				
			||||||
	private JTextPane				textPane				= new JTextPane();
 | 
						private JTextPane				textPane				= new JTextPane();
 | 
				
			||||||
	private PrimaryButton			postButton				= new PrimaryButton("Post");
 | 
						private PrimaryButton			postButton				= new PrimaryButton("Post");
 | 
				
			||||||
	private PrimaryButton			settingsButton			= new PrimaryButton("Settings");
 | 
						private PrimaryButton			settingsButton			= new PrimaryButton("Settings");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private static int space = 4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class.getSimpleName());
 | 
						private static final Logger logger = EnvoyLog.getLogger(ChatWindow.class.getSimpleName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// GUI component spacing
 | 
				
			||||||
 | 
						private final static int	space	= 4;
 | 
				
			||||||
 | 
						private static final Insets	insets	= new Insets(space, space, space, space);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final long serialVersionUID = 6865098428255463649L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Initializes a {@link JFrame} with UI elements used to send and read messages
 | 
						 * Initializes a {@link JFrame} with UI elements used to send and read messages
 | 
				
			||||||
	 * to different users.
 | 
						 * to different users.
 | 
				
			||||||
@@ -73,14 +77,11 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbl_contentPane.rowWeights		= new double[] { 0.05, 1.0, 0.07 };
 | 
							gbl_contentPane.rowWeights		= new double[] { 0.05, 1.0, 0.07 };
 | 
				
			||||||
		contentPane.setLayout(gbl_contentPane);
 | 
							contentPane.setLayout(gbl_contentPane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		messageList.setCellRenderer(new MessageListRenderer());
 | 
							// TODO: messageList.setFocusTraversalKeysEnabled(false);
 | 
				
			||||||
		messageList.setFocusTraversalKeysEnabled(false);
 | 
							// messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
 | 
				
			||||||
		messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DefaultListModel<Message> messageListModel = new DefaultListModel<>();
 | 
							// messageList.setFont(new Font("Arial", Font.PLAIN, 17));
 | 
				
			||||||
		messageList.setModel(messageListModel);
 | 
							// messageList.setFixedCellHeight(60);
 | 
				
			||||||
		messageList.setFont(new Font("Arial", Font.PLAIN, 17));
 | 
					 | 
				
			||||||
		messageList.setFixedCellHeight(60);
 | 
					 | 
				
			||||||
		messageList.setBorder(new EmptyBorder(space, space, space, space));
 | 
							messageList.setBorder(new EmptyBorder(space, space, space, space));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		scrollPane.setViewportView(messageList);
 | 
							scrollPane.setViewportView(messageList);
 | 
				
			||||||
@@ -91,7 +92,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_scrollPane.gridx		= 1;
 | 
							gbc_scrollPane.gridx		= 1;
 | 
				
			||||||
		gbc_scrollPane.gridy		= 1;
 | 
							gbc_scrollPane.gridy		= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gbc_scrollPane.insets = new Insets(space, space, space, space);
 | 
							gbc_scrollPane.insets = insets;
 | 
				
			||||||
		contentPane.add(scrollPane, gbc_scrollPane);
 | 
							contentPane.add(scrollPane, gbc_scrollPane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Message enter field
 | 
							// Message enter field
 | 
				
			||||||
@@ -100,8 +101,8 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
			@Override
 | 
								@Override
 | 
				
			||||||
			public void keyReleased(KeyEvent e) {
 | 
								public void keyReleased(KeyEvent e) {
 | 
				
			||||||
				if (e.getKeyCode() == KeyEvent.VK_ENTER
 | 
									if (e.getKeyCode() == KeyEvent.VK_ENTER
 | 
				
			||||||
						&& ((Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK)))
 | 
											&& (Settings.getInstance().isEnterToSend() && e.getModifiersEx() == 0 || e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))
 | 
				
			||||||
					postMessage(messageList);
 | 
										postMessage();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,7 +111,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_messageEnterTextfield.gridx	= 1;
 | 
							gbc_messageEnterTextfield.gridx	= 1;
 | 
				
			||||||
		gbc_messageEnterTextfield.gridy	= 2;
 | 
							gbc_messageEnterTextfield.gridy	= 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gbc_messageEnterTextfield.insets = new Insets(space, space, space, space);
 | 
							gbc_messageEnterTextfield.insets = insets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
 | 
							contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -121,9 +122,9 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_moveSelectionPostButton.gridx	= 2;
 | 
							gbc_moveSelectionPostButton.gridx	= 2;
 | 
				
			||||||
		gbc_moveSelectionPostButton.gridy	= 2;
 | 
							gbc_moveSelectionPostButton.gridy	= 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gbc_moveSelectionPostButton.insets = new Insets(space, space, space, space);
 | 
							gbc_moveSelectionPostButton.insets = insets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		postButton.addActionListener((evt) -> { postMessage(messageList); });
 | 
							postButton.addActionListener((evt) -> { postMessage(); });
 | 
				
			||||||
		contentPane.add(postButton, gbc_moveSelectionPostButton);
 | 
							contentPane.add(postButton, gbc_moveSelectionPostButton);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Settings Button
 | 
							// Settings Button
 | 
				
			||||||
@@ -133,7 +134,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_moveSelectionSettingsButton.gridx	= 2;
 | 
							gbc_moveSelectionSettingsButton.gridx	= 2;
 | 
				
			||||||
		gbc_moveSelectionSettingsButton.gridy	= 0;
 | 
							gbc_moveSelectionSettingsButton.gridy	= 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gbc_moveSelectionSettingsButton.insets = new Insets(space, space, space, space);
 | 
							gbc_moveSelectionSettingsButton.insets = insets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		settingsButton.addActionListener((evt) -> {
 | 
							settingsButton.addActionListener((evt) -> {
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
@@ -154,7 +155,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_partnerName.gridx	= 1;
 | 
							gbc_partnerName.gridx	= 1;
 | 
				
			||||||
		gbc_partnerName.gridy	= 0;
 | 
							gbc_partnerName.gridy	= 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gbc_partnerName.insets = new Insets(space, space, space, space);
 | 
							gbc_partnerName.insets = insets;
 | 
				
			||||||
		contentPane.add(textPane, gbc_partnerName);
 | 
							contentPane.add(textPane, gbc_partnerName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		userList.setCellRenderer(new UserListRenderer());
 | 
							userList.setCellRenderer(new UserListRenderer());
 | 
				
			||||||
@@ -165,17 +166,22 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
				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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Select current chat
 | 
				
			||||||
				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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// Set all unread messages in the chat to read
 | 
									// Read current Chat
 | 
				
			||||||
				readCurrentChat();
 | 
									currentChat.read();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Set recipient in client and chat title
 | 
				
			||||||
				client.setRecipient(user);
 | 
									client.setRecipient(user);
 | 
				
			||||||
				textPane.setText(currentChat.getRecipient().getName());
 | 
									textPane.setText(currentChat.getRecipient().getName());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Update model and scroll down
 | 
				
			||||||
				messageList.setModel(currentChat.getModel());
 | 
									messageList.setModel(currentChat.getModel());
 | 
				
			||||||
				scrollPane.setChatOpened(true);
 | 
									scrollPane.setChatOpened(true);
 | 
				
			||||||
				contentPane.revalidate();
 | 
					
 | 
				
			||||||
 | 
									revalidate();
 | 
				
			||||||
 | 
									repaint();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -187,20 +193,29 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		gbc_userList.gridx	= 0;
 | 
							gbc_userList.gridx	= 0;
 | 
				
			||||||
		gbc_userList.gridy	= 1;
 | 
							gbc_userList.gridy	= 1;
 | 
				
			||||||
		gbc_userList.anchor	= GridBagConstraints.PAGE_START;
 | 
							gbc_userList.anchor	= GridBagConstraints.PAGE_START;
 | 
				
			||||||
		gbc_userList.insets	= new Insets(space, space, space, space);
 | 
							gbc_userList.insets	= insets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
							applyTheme(Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		contentPane.add(userList, gbc_userList);
 | 
							contentPane.add(userList, gbc_userList);
 | 
				
			||||||
		contentPane.revalidate();
 | 
							contentPane.revalidate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Listen to theme changes
 | 
				
			||||||
		EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme((Theme) evt.get()));
 | 
							EventBus.getInstance().register(ThemeChangeEvent.class, (evt) -> applyTheme((Theme) evt.get()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		contentPane.revalidate();
 | 
							// Listen to received messages
 | 
				
			||||||
 | 
							EventBus.getInstance().register(MessageCreationEvent.class, (evt) -> {
 | 
				
			||||||
 | 
								Message message = ((MessageCreationEvent) evt).get();
 | 
				
			||||||
 | 
								localDB.getChats().stream().filter(c -> c.getRecipient().getId() == message.getSenderId()).findFirst().get().appendMessage(message);
 | 
				
			||||||
 | 
								revalidate();
 | 
				
			||||||
 | 
								repaint();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							revalidate();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Used to immediately reload the ChatWindow when settings were changed.
 | 
						 * Used to immediately reload the {@link ChatWindow} when settings were changed.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @param theme the theme to change colors into
 | 
						 * @param theme the theme to change colors into
 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
@@ -210,8 +225,8 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		contentPane.setBackground(theme.getBackgroundColor());
 | 
							contentPane.setBackground(theme.getBackgroundColor());
 | 
				
			||||||
		contentPane.setForeground(theme.getUserNameColor());
 | 
							contentPane.setForeground(theme.getUserNameColor());
 | 
				
			||||||
		// messageList
 | 
							// messageList
 | 
				
			||||||
		messageList.setSelectionForeground(theme.getUserNameColor());
 | 
							// messageList.setSelectionForeground(theme.getUserNameColor());
 | 
				
			||||||
		messageList.setSelectionBackground(theme.getSelectionColor());
 | 
							// messageList.setSelectionBackground(theme.getSelectionColor());
 | 
				
			||||||
		messageList.setForeground(theme.getMessageColorChat());
 | 
							messageList.setForeground(theme.getMessageColorChat());
 | 
				
			||||||
		messageList.setBackground(theme.getCellColor());
 | 
							messageList.setBackground(theme.getCellColor());
 | 
				
			||||||
		// scrollPane
 | 
							// scrollPane
 | 
				
			||||||
@@ -238,7 +253,7 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		userList.setBackground(theme.getCellColor());
 | 
							userList.setBackground(theme.getCellColor());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void postMessage(JList<Message> messageList) {
 | 
						private void postMessage() {
 | 
				
			||||||
		if (!client.hasRecipient()) {
 | 
							if (!client.hasRecipient()) {
 | 
				
			||||||
			JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE);
 | 
								JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE);
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
@@ -247,24 +262,32 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
		if (!messageEnterTextArea.getText().isEmpty()) try {
 | 
							if (!messageEnterTextArea.getText().isEmpty()) try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Create message
 | 
								// Create message
 | 
				
			||||||
			final Message message = new MessageBuilder(localDB.getUser().getId(), currentChat.getRecipient().getId())
 | 
								final Message message = new MessageBuilder(localDB.getUser().getId(), currentChat.getRecipient().getId(), localDB.getIdGenerator())
 | 
				
			||||||
				.setText(messageEnterTextArea.getText())
 | 
									.setText(messageEnterTextArea.getText())
 | 
				
			||||||
				.build();
 | 
									.build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Send message
 | 
								// Send message
 | 
				
			||||||
 | 
								// TODO: Store offline messages
 | 
				
			||||||
			client.sendMessage(message);
 | 
								client.sendMessage(message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Add message to LocalDB and update UI
 | 
								// Add message to LocalDB and update UI
 | 
				
			||||||
			currentChat.appendMessage(message);
 | 
								currentChat.appendMessage(message);
 | 
				
			||||||
			messageList.setModel(currentChat.getModel());
 | 
								// messageList.setModel(currentChat.getModel());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Clear text field
 | 
								// Clear text field
 | 
				
			||||||
			messageEnterTextArea.setText("");
 | 
								messageEnterTextArea.setText("");
 | 
				
			||||||
			contentPane.revalidate();
 | 
					
 | 
				
			||||||
 | 
								// Update UI
 | 
				
			||||||
 | 
								revalidate();
 | 
				
			||||||
 | 
								repaint();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Request a new id generator if all ids were used
 | 
				
			||||||
 | 
								if (!localDB.getIdGenerator().hasNext()) client.requestIdGenerator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} catch (Exception e) {
 | 
							} catch (Exception e) {
 | 
				
			||||||
			JOptionPane.showMessageDialog(this,
 | 
								JOptionPane.showMessageDialog(this,
 | 
				
			||||||
					"An exception occured while sending a message. See the log for more details.",
 | 
										"Error sending message:\n" + e.toString(),
 | 
				
			||||||
					"Exception occured",
 | 
										"Message sending error",
 | 
				
			||||||
					JOptionPane.ERROR_MESSAGE);
 | 
										JOptionPane.ERROR_MESSAGE);
 | 
				
			||||||
			e.printStackTrace();
 | 
								e.printStackTrace();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -291,64 +314,13 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Updates the data model and the UI repeatedly after a certain amount of
 | 
						 * Sets the {@link Client} used by this {@link ChatWindow}.
 | 
				
			||||||
	 * time.
 | 
					 | 
				
			||||||
	 *
 | 
					 | 
				
			||||||
	 * @param timeout the amount of time that passes between two requests sent to
 | 
					 | 
				
			||||||
	 *                the server
 | 
					 | 
				
			||||||
	 * @since Envoy v0.1-alpha
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	private void startSyncThread(int timeout) {
 | 
					 | 
				
			||||||
		new Timer(timeout, (evt) -> {
 | 
					 | 
				
			||||||
			new Thread(() -> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// Synchronize
 | 
					 | 
				
			||||||
				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);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// TODO: Process unread messages
 | 
					 | 
				
			||||||
				// localDB.addUnreadMessagesToLocalDB();
 | 
					 | 
				
			||||||
				// localDB.clearUnreadMessagesSync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// Mark unread messages as read when they are in the current chat
 | 
					 | 
				
			||||||
				readCurrentChat();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// Update UI
 | 
					 | 
				
			||||||
				SwingUtilities.invokeLater(() -> { updateUserStates(); contentPane.revalidate(); contentPane.repaint(); });
 | 
					 | 
				
			||||||
			}).start();
 | 
					 | 
				
			||||||
		}).start();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private void updateUserStates() {
 | 
					 | 
				
			||||||
		for (int i = 0; i < userList.getModel().getSize(); i++)
 | 
					 | 
				
			||||||
			for (int j = 0; j < localDB.getChats().size(); j++)
 | 
					 | 
				
			||||||
				if (userList.getModel().getElementAt(i).getId() == localDB.getChats().get(j).getRecipient().getId())
 | 
					 | 
				
			||||||
					userList.getModel().getElementAt(i).setStatus(localDB.getChats().get(j).getRecipient().getStatus());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Marks messages in the current chat as {@code READ}.
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	private void readCurrentChat() {
 | 
					 | 
				
			||||||
		if (currentChat != null) {
 | 
					 | 
				
			||||||
			// TODO: localDB.setMessagesToRead(currentChat);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Sets the {@link Client} used by this {@link ChatWindow}. If the client is
 | 
					 | 
				
			||||||
	 * online, the sync thread is started.
 | 
					 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * @param client the {@link Client} used to send and receive messages
 | 
						 * @param client the {@link Client} used to send and receive messages
 | 
				
			||||||
	 * @since Envoy v0.2-alpha
 | 
						 * @since Envoy v0.2-alpha
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void setClient(Client client) {
 | 
						public void setClient(Client client) {
 | 
				
			||||||
		this.client = client;
 | 
							this.client = client;
 | 
				
			||||||
		if (client.isOnline() && localDB != null) startSyncThread(Config.getInstance().getSyncTimeout());
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@@ -361,6 +333,5 @@ public class ChatWindow extends JFrame {
 | 
				
			|||||||
	public void setLocalDB(LocalDB localDB) {
 | 
						public void setLocalDB(LocalDB localDB) {
 | 
				
			||||||
		this.localDB = localDB;
 | 
							this.localDB = localDB;
 | 
				
			||||||
		loadUsersAndChats();
 | 
							loadUsersAndChats();
 | 
				
			||||||
		if (client != null && client.isOnline()) startSyncThread(Config.getInstance().getSyncTimeout());
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
package envoy.client.ui;
 | 
					package envoy.client.ui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.awt.Component;
 | 
					import java.awt.Dimension;
 | 
				
			||||||
import java.text.SimpleDateFormat;
 | 
					import java.text.SimpleDateFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import javax.swing.JLabel;
 | 
					import javax.swing.*;
 | 
				
			||||||
import javax.swing.JList;
 | 
					 | 
				
			||||||
import javax.swing.ListCellRenderer;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import envoy.client.Settings;
 | 
					import envoy.client.Settings;
 | 
				
			||||||
 | 
					import envoy.client.ui.list.ComponentList;
 | 
				
			||||||
 | 
					import envoy.client.ui.list.ComponentListCellRenderer;
 | 
				
			||||||
import envoy.data.Message;
 | 
					import envoy.data.Message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -21,22 +21,22 @@ import envoy.data.Message;
 | 
				
			|||||||
 * @author Maximilian Käfer
 | 
					 * @author Maximilian Käfer
 | 
				
			||||||
 * @since Envoy v0.1-alpha
 | 
					 * @since Envoy v0.1-alpha
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class MessageListRenderer extends JLabel implements ListCellRenderer<Message> {
 | 
					public class MessageListRenderer implements ComponentListCellRenderer<Message> {
 | 
				
			||||||
 | 
					 | 
				
			||||||
	private static final long serialVersionUID = 5164417379767181198L;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public Component getListCellRendererComponent(JList<? extends Message> list, Message value, int index, boolean isSelected, boolean cellHasFocus) {
 | 
						public JComponent getListCellComponent(ComponentList<? extends Message> list, Message value, boolean isSelected) {
 | 
				
			||||||
 | 
							final JPanel panel = new JPanel();
 | 
				
			||||||
		if (isSelected) {
 | 
							if (isSelected) {
 | 
				
			||||||
			setBackground(list.getSelectionBackground());
 | 
								panel.setBackground(Color.DARK_GRAY);
 | 
				
			||||||
			setForeground(list.getSelectionForeground());
 | 
								panel.setForeground(Color.RED);
 | 
				
			||||||
 | 
								// TODO: Selection
 | 
				
			||||||
 | 
								// setBackground(list.getSelectionBackground());
 | 
				
			||||||
 | 
								// setForeground(list.getSelectionForeground());
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			setBackground(list.getBackground());
 | 
								panel.setBackground(list.getBackground());
 | 
				
			||||||
			setForeground(list.getForeground());
 | 
								panel.setForeground(list.getForeground());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setOpaque(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// TODO: Handle message attachments
 | 
							// TODO: Handle message attachments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		final String	text	= value.getText();
 | 
							final String	text	= value.getText();
 | 
				
			||||||
@@ -49,12 +49,22 @@ public class MessageListRenderer extends JLabel implements ListCellRenderer<Mess
 | 
				
			|||||||
		// Getting the DateColor in the Chat of the current theme
 | 
							// Getting the DateColor in the Chat of the current theme
 | 
				
			||||||
		String dateColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat().toHex();
 | 
							String dateColor = Settings.getInstance().getThemes().get(Settings.getInstance().getCurrentTheme()).getDateColorChat().toHex();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setText(String.format("<html><p style=\"color:%s\"><b><small>%s</b></small><br><p style=\"color:%s\">%s :%s</html>",
 | 
							panel.add(new JLabel(String.format("<html><p style=\"color:%s\"><b><small>%s</b></small><br><p style=\"color:%s\">%s :%s</html>",
 | 
				
			||||||
				dateColor,
 | 
									dateColor,
 | 
				
			||||||
				date,
 | 
									date,
 | 
				
			||||||
				textColor,
 | 
									textColor,
 | 
				
			||||||
				text,
 | 
									text,
 | 
				
			||||||
				state));
 | 
									state)));
 | 
				
			||||||
		return this;
 | 
					
 | 
				
			||||||
 | 
							// Define some space to the messages below
 | 
				
			||||||
 | 
							panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 15, 0), BorderFactory.createEtchedBorder()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Define a maximum height of 50px
 | 
				
			||||||
 | 
							Dimension size = new Dimension(list.getWidth() - 25, 50);
 | 
				
			||||||
 | 
							panel.setMaximumSize(size);
 | 
				
			||||||
 | 
							panel.setMinimumSize(size);
 | 
				
			||||||
 | 
							panel.setPreferredSize(size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return panel;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -97,7 +97,8 @@ public class Startup {
 | 
				
			|||||||
		Client client = new Client();
 | 
							Client client = new Client();
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			// Try entering online mode first
 | 
								// Try entering online mode first
 | 
				
			||||||
			client.onlineInit(credentials);
 | 
								localDB.loadIdGenerator();
 | 
				
			||||||
 | 
								client.onlineInit(credentials, localDB);
 | 
				
			||||||
		} catch (Exception e1) {
 | 
							} catch (Exception e1) {
 | 
				
			||||||
			logger.warning("Could not connect to server. Trying offline mode...");
 | 
								logger.warning("Could not connect to server. Trying offline mode...");
 | 
				
			||||||
			e1.printStackTrace();
 | 
								e1.printStackTrace();
 | 
				
			||||||
@@ -152,7 +153,7 @@ public class Startup {
 | 
				
			|||||||
						.getItems()
 | 
											.getItems()
 | 
				
			||||||
						.get("onCloseMode")
 | 
											.get("onCloseMode")
 | 
				
			||||||
						.setChangeHandler((onCloseMode) -> chatWindow
 | 
											.setChangeHandler((onCloseMode) -> chatWindow
 | 
				
			||||||
							.setDefaultCloseOperation((boolean) onCloseMode ? JFrame.HIDE_ON_CLOSE : JFrame.EXIT_ON_CLOSE));
 | 
												.setDefaultCloseOperation((Boolean) onCloseMode ? JFrame.HIDE_ON_CLOSE : JFrame.EXIT_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!");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										91
									
								
								src/main/java/envoy/client/ui/list/ComponentList.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/main/java/envoy/client/ui/list/ComponentList.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					package envoy.client.ui.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.swing.BoxLayout;
 | 
				
			||||||
 | 
					import javax.swing.JPanel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Provides a vertical list layout of components provided in a
 | 
				
			||||||
 | 
					 * {@link ComponentListModel}. Similar to {@link javax.swing.JList} but capable
 | 
				
			||||||
 | 
					 * of rendering {@link JPanel}s.<br>
 | 
				
			||||||
 | 
					 * <br>
 | 
				
			||||||
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 | 
					 * File: <strong>ComponentList.java</strong><br>
 | 
				
			||||||
 | 
					 * Created: <strong>25.01.2020</strong><br>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param <E> the type of object displayed in this list
 | 
				
			||||||
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 | 
					 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public class ComponentList<E> extends JPanel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private ComponentListModel<E>			model;
 | 
				
			||||||
 | 
						private ComponentListCellRenderer<E>	renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final long serialVersionUID = 1759644503942876737L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Creates an instance of {@link ComponentList}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param renderer the list cell renderer used to display elements provided by
 | 
				
			||||||
 | 
						 *                 the {@link ComponentListModel}
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public ComponentList(ComponentListCellRenderer<E> renderer) {
 | 
				
			||||||
 | 
							setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
 | 
				
			||||||
 | 
							this.renderer = renderer;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Creates an instance of {@link ComponentList}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param model    the list model providing the list elements to render
 | 
				
			||||||
 | 
						 * @param renderer the list cell renderer used to display elements provided by
 | 
				
			||||||
 | 
						 *                 the {@link ComponentListModel}
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public ComponentList(ComponentListModel<E> model, ComponentListCellRenderer<E> renderer) {
 | 
				
			||||||
 | 
							this(renderer);
 | 
				
			||||||
 | 
							this.model = model;
 | 
				
			||||||
 | 
							setModel(model);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Sets the list model providing the list elements to render
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param model the list model to set
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void setModel(ComponentListModel<E> model) {
 | 
				
			||||||
 | 
							// Remove old model
 | 
				
			||||||
 | 
							if (this.model != null)
 | 
				
			||||||
 | 
								this.model.setComponentList(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Synchronize with new model
 | 
				
			||||||
 | 
							this.model = model;
 | 
				
			||||||
 | 
							this.model.setComponentList(this);
 | 
				
			||||||
 | 
							synchronizeModel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Adds an object to the list by rendering it with the current
 | 
				
			||||||
 | 
						 * {@link ComponentListCellRenderer}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param elem the element to add
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						void add(E elem) {
 | 
				
			||||||
 | 
							add(renderer.getListCellComponent(this, elem, false));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Removes all child components and then adds all components representing the
 | 
				
			||||||
 | 
						 * elements of the {@link ComponentListModel}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						void synchronizeModel() {
 | 
				
			||||||
 | 
							removeAll();
 | 
				
			||||||
 | 
							if (model != null) for (E elem : model)
 | 
				
			||||||
 | 
								add(elem);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					package envoy.client.ui.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.swing.JComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Allows a {@link ComponentList} convert its elements into Swing components
 | 
				
			||||||
 | 
					 * that can be rendered.<br>
 | 
				
			||||||
 | 
					 * <br>
 | 
				
			||||||
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 | 
					 * File: <strong>ComponentListCellRenderer.java</strong><br>
 | 
				
			||||||
 | 
					 * Created: <strong>25.01.2020</strong><br>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param <E> the type of object displayed in this list
 | 
				
			||||||
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 | 
					 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public interface ComponentListCellRenderer<E> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Provides a Swing component representing a list element.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param list       the list in which the component will be displayed
 | 
				
			||||||
 | 
						 * @param value      the list element that will be converted
 | 
				
			||||||
 | 
						 * @param isSelected {@code true} if the user has selected the list cell in
 | 
				
			||||||
 | 
						 *                   which the list element is rendered
 | 
				
			||||||
 | 
						 * @return the component representing the list element
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						JComponent getListCellComponent(ComponentList<? extends E> list, E value, boolean isSelected);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										111
									
								
								src/main/java/envoy/client/ui/list/ComponentListModel.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/main/java/envoy/client/ui/list/ComponentListModel.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
				
			|||||||
 | 
					package envoy.client.ui.list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.Serializable;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.Iterator;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Stores objects that will be displayed in a {@link ComponentList}.<br>
 | 
				
			||||||
 | 
					 * <br>
 | 
				
			||||||
 | 
					 * Project: <strong>envoy-client</strong><br>
 | 
				
			||||||
 | 
					 * File: <strong>ComponentListModel.java</strong><br>
 | 
				
			||||||
 | 
					 * Created: <strong>25.01.2020</strong><br>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param <E> the type of object displayed in this list
 | 
				
			||||||
 | 
					 * @author Kai S. K. Engelbart
 | 
				
			||||||
 | 
					 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					public final class ComponentListModel<E> implements Iterable<E>, Serializable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private List<E>						elements	= new ArrayList<>();
 | 
				
			||||||
 | 
						transient private ComponentList<E>	componentList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private static final long serialVersionUID = 4815005915255497331L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Adds an element to this model and notifies the associated
 | 
				
			||||||
 | 
						 * {@link ComponentList} to add the corresponding component.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param e the element to add
 | 
				
			||||||
 | 
						 * @return {@code true}
 | 
				
			||||||
 | 
						 * @see java.util.List#add(java.lang.Object)
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public boolean add(E e) {
 | 
				
			||||||
 | 
							if (componentList != null) componentList.add(e);
 | 
				
			||||||
 | 
							return elements.add(e);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Removes all elements from this model and clears the associated
 | 
				
			||||||
 | 
						 * {@link ComponentList}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @see java.util.List#clear()
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public void clear() {
 | 
				
			||||||
 | 
							elements.clear();
 | 
				
			||||||
 | 
							if (componentList != null) componentList.removeAll();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @param index the index to retrieve the element from
 | 
				
			||||||
 | 
						 * @return the element located at the index
 | 
				
			||||||
 | 
						 * @see java.util.List#get(int)
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public E get(int index) { return elements.get(index); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Removes the element at a specific index from this model and the corresponding
 | 
				
			||||||
 | 
						 * component from the {@link ComponentList}.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param index the index of the element to remove
 | 
				
			||||||
 | 
						 * @return the removed element
 | 
				
			||||||
 | 
						 * @see java.util.List#remove(int)
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public E remove(int index) {
 | 
				
			||||||
 | 
							if (componentList != null) componentList.remove(index);
 | 
				
			||||||
 | 
							return elements.remove(index);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return the amount of elements in this list model
 | 
				
			||||||
 | 
						 * @see java.util.List#size()
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						public int size() { return elements.size(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * @return an iterator over the elements of this list model
 | 
				
			||||||
 | 
						 * @see java.util.List#iterator()
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						@Override
 | 
				
			||||||
 | 
						public Iterator<E> iterator() {
 | 
				
			||||||
 | 
							return new Iterator<E>() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Iterator<E> iter = elements.iterator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								public boolean hasNext() { return iter.hasNext(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								public E next() { return iter.next(); }
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * Sets the component list displaying the elements of this model and triggers a
 | 
				
			||||||
 | 
						 * synchronization.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * @param componentList the component list to set
 | 
				
			||||||
 | 
						 * @since Envoy v0.3-alpha
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						void setComponentList(ComponentList<E> componentList) {
 | 
				
			||||||
 | 
							this.componentList = componentList;
 | 
				
			||||||
 | 
							if (componentList != null) componentList.synchronizeModel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user