Improved logging and code readability
This commit is contained in:
		| @@ -36,14 +36,14 @@ public class Client { | ||||
| 		this.config	= config; | ||||
| 		sender		= getUser(username); | ||||
|  | ||||
| 		logger.info("ID: " +  sender.getID()); | ||||
| 		logger.info("ID: " + sender.getID()); | ||||
| 	} | ||||
|  | ||||
| 	private <T, R> R post(String uri, T body, Class<R> responseBodyClass) { | ||||
| 		javax.ws.rs.client.Client	client	= ClientBuilder.newClient(); | ||||
| 		WebTarget					target	= client.target(uri); | ||||
| 		Response	response		= target.request().post(Entity.entity(body, "application/xml")); | ||||
| 		R			responseBody	= response.readEntity(responseBodyClass); | ||||
| 		javax.ws.rs.client.Client	client			= ClientBuilder.newClient(); | ||||
| 		WebTarget					target			= client.target(uri); | ||||
| 		Response					response		= target.request().post(Entity.entity(body, "application/xml")); | ||||
| 		R							responseBody	= response.readEntity(responseBodyClass); | ||||
| 		response.close(); | ||||
| 		client.close(); | ||||
|  | ||||
| @@ -133,7 +133,9 @@ public class Client { | ||||
| 	 * Updating UserStatus of all users in LocalDB. (Server sends all users with | ||||
| 	 * their updated UserStatus to the client.) <br> | ||||
| 	 *  | ||||
| 	 * @param userId | ||||
| 	 * @param userId the id of the {@link Client} who sends the {@link Sync} | ||||
| 	 * @param sync   the {@link Sync} to send | ||||
| 	 * @return a sync | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public Sync sendSync(long userId, Sync sync) { | ||||
| @@ -168,16 +170,16 @@ public class Client { | ||||
| 	public User getRecipient() { return recipient; } | ||||
|  | ||||
| 	/** | ||||
|      * Sets the recipient. | ||||
| 	 * Sets the recipient. | ||||
| 	 *  | ||||
| 	 * @param recipient - the recipient to set | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void setRecipient(User recipient) { this.recipient = recipient; } | ||||
|  | ||||
|     /** | ||||
| 	/** | ||||
| 	 * @return true, if a recipient is selected | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public boolean hasRecipient() { return recipient != null; } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -114,7 +114,7 @@ public class Config { | ||||
| 	 * Changes the default local database. | ||||
| 	 * Exclusively intended for development purposes. | ||||
| 	 * | ||||
| 	 * @param the file containing the local database | ||||
| 	 * @param localDB the file containing the local database | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 **/ | ||||
| 	public void setLocalDB(File localDB) { this.localDB = localDB; } | ||||
|   | ||||
| @@ -39,7 +39,7 @@ public class LocalDB { | ||||
| 	private DatatypeFactory	datatypeFactory; | ||||
|  | ||||
| 	private static final Logger logger = Logger.getLogger(LocalDB.class.getSimpleName()); | ||||
| 	 | ||||
|  | ||||
| 	private Sync	unreadMessagesSync	= objectFactory.createSync(); | ||||
| 	private Sync	sync				= objectFactory.createSync(); | ||||
| 	private Sync	readMessages		= objectFactory.createSync(); | ||||
| @@ -80,19 +80,13 @@ public class LocalDB { | ||||
| 	 * @throws IOException if something went wrong during saving | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void saveToLocalDB() { | ||||
| 		try { | ||||
| 			localDB.getParentFile().mkdirs(); | ||||
| 			localDB.createNewFile(); | ||||
| 		} catch (IOException e) { | ||||
| 			e.printStackTrace(); | ||||
| 			logger.warning("unable to save the messages"); | ||||
| 		} | ||||
| 	public void saveToLocalDB() throws IOException { | ||||
| 		localDB.getParentFile().mkdirs(); | ||||
| 		localDB.createNewFile(); | ||||
| 		try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(localDB))) { | ||||
| 			out.writeObject(chats); | ||||
| 		} catch (IOException ex) { | ||||
| 			ex.printStackTrace(); | ||||
| 			logger.warning("unable to save the messages"); | ||||
| 			throw ex; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -116,7 +110,7 @@ public class LocalDB { | ||||
| 	 * Creates a {@link Message} object serializable to XML. | ||||
| 	 *  | ||||
| 	 * @param textContent The content (text) of the message | ||||
| 	 * @param recipient The recipient of the message | ||||
| 	 * @param recipient   The recipient of the message | ||||
| 	 * @return prepared {@link Message} object | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| @@ -144,7 +138,7 @@ public class LocalDB { | ||||
| 		sync.getMessages().addAll(readMessages.getMessages()); | ||||
| 		readMessages.getMessages().clear(); | ||||
|  | ||||
| 		logger.info(String.format("Filled sync with %d messages.", sync.getMessages().size())); | ||||
| 		logger.finest(String.format("Filled sync with %d messages.", sync.getMessages().size())); | ||||
| 		return sync; | ||||
| 	} | ||||
|  | ||||
| @@ -189,28 +183,20 @@ public class LocalDB { | ||||
| 			if (returnSync.getMessages().get(i).getMetadata().getMessageId() != 0 | ||||
| 					&& returnSync.getMessages().get(i).getMetadata().getState() == MessageState.READ) { | ||||
| 				// Update local Messages to state READ | ||||
| 				logger.info("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | ||||
| 				logger.finest("Message with ID: " + returnSync.getMessages().get(i).getMetadata().getMessageId() | ||||
| 						+ "was initialized to be set to READ in localDB."); | ||||
| 				for (int j = 0; j < getChats().size(); j++) { | ||||
| 					if (getChats().get(j) | ||||
| 						.getRecipient() | ||||
| 						.getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | ||||
| 						logger.info("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected."); | ||||
| 					if (getChats().get(j).getRecipient().getID() == returnSync.getMessages().get(i).getMetadata().getRecipient()) { | ||||
| 						logger.fine("Chat with: " + getChats().get(j).getRecipient().getID() + "was selected."); | ||||
| 						for (int k = 0; k < getChats().get(j).getModel().getSize(); k++) { | ||||
| 							if (getChats().get(j).getModel().get(k).getMetadata().getMessageId() == returnSync.getMessages() | ||||
| 								.get(i) | ||||
| 								.getMetadata() | ||||
| 								.getMessageId()) { | ||||
| 								logger.info("Message with ID: " | ||||
| 										+ getChats().get(j).getModel().get(k).getMetadata().getMessageId() | ||||
| 										+ "was selected."); | ||||
| 								getChats().get(j) | ||||
| 									.getModel() | ||||
| 									.get(k) | ||||
| 									.getMetadata() | ||||
| 									.setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 								logger.info("Message State is now: " | ||||
| 										+ getChats().get(j).getModel().get(k).getMetadata().getState().toString()); | ||||
| 								logger | ||||
| 									.finest("Message with ID: " + getChats().get(j).getModel().get(k).getMetadata().getMessageId() + "was selected."); | ||||
| 								getChats().get(j).getModel().get(k).getMetadata().setState(returnSync.getMessages().get(i).getMetadata().getState()); | ||||
| 								logger.finest("Message State is now: " + getChats().get(j).getModel().get(k).getMetadata().getState().toString()); | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
| @@ -237,7 +223,6 @@ public class LocalDB { | ||||
| 	 * Adds the unread messages returned from the server in the latest sync to the | ||||
| 	 * right chats in the LocalDB. | ||||
| 	 *  | ||||
| 	 * @param localDB | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void addUnreadMessagesToLocalDB() { | ||||
| @@ -255,7 +240,7 @@ public class LocalDB { | ||||
| 	 * <br> | ||||
| 	 * Adds these messages to the {@code readMessages} {@link Sync} object. | ||||
| 	 *  | ||||
| 	 * @param currentChat | ||||
| 	 * @param currentChat the {@link Chat} that was just opened | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public void setMessagesToRead(Chat currentChat) { | ||||
|   | ||||
| @@ -1,352 +1,352 @@ | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Color; | ||||
| import java.awt.ComponentOrientation; | ||||
| import java.awt.Font; | ||||
| import java.awt.GridBagConstraints; | ||||
| import java.awt.GridBagLayout; | ||||
| import java.awt.Insets; | ||||
| import java.awt.event.KeyAdapter; | ||||
| import java.awt.event.KeyEvent; | ||||
| import java.awt.event.WindowAdapter; | ||||
| import java.awt.event.WindowEvent; | ||||
| 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; | ||||
| import javax.swing.Timer; | ||||
| import javax.swing.border.EmptyBorder; | ||||
|  | ||||
| import envoy.client.Chat; | ||||
| import envoy.client.Client; | ||||
| import envoy.client.Config; | ||||
| import envoy.client.LocalDB; | ||||
| import envoy.schema.Message; | ||||
| import envoy.schema.Sync; | ||||
| import envoy.schema.User; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>ChatWindow.java</strong><br> | ||||
|  * Created: <strong>28 Sep 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Leon Hofmeister | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class ChatWindow extends JFrame { | ||||
|  | ||||
| 	private static final long serialVersionUID = 6865098428255463649L; | ||||
|  | ||||
| 	private JPanel contentPane = new JPanel(); | ||||
|  | ||||
| 	private Client	client; | ||||
| 	private LocalDB	localDB; | ||||
|  | ||||
| 	private JList<User>	userList	= new JList<>(); | ||||
| 	private Chat		currentChat; | ||||
|  | ||||
| 	private JTextArea messageEnterTextArea; | ||||
| 	 | ||||
| 	private static final Logger logger = Logger.getLogger(ChatWindow.class.getSimpleName()); | ||||
|  | ||||
| 	public ChatWindow(Client client, LocalDB localDB) { | ||||
| 		this.client		= client; | ||||
| 		this.localDB	= localDB; | ||||
|  | ||||
| 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||||
| 		setBounds(100, 100, 600, 800); | ||||
| 		setTitle("Envoy"); | ||||
| 		setLocationRelativeTo(null); | ||||
|  | ||||
| 		// Save chats when window closes | ||||
| 		addWindowListener(new WindowAdapter() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void windowClosing(WindowEvent e) { localDB.saveToLocalDB(); } | ||||
| 		}); | ||||
|  | ||||
| 		contentPane.setBackground(new Color(0, 0, 0)); | ||||
| 		contentPane.setForeground(Color.white); | ||||
| 		contentPane.setBorder(new EmptyBorder(0, 5, 0, 0)); | ||||
| 		setContentPane(contentPane); | ||||
| 		GridBagLayout gbl_contentPane = new GridBagLayout(); | ||||
| 		gbl_contentPane.columnWidths	= new int[] { 1, 1, 1 }; | ||||
| 		gbl_contentPane.rowHeights		= new int[] { 1, 1, 1 }; | ||||
| 		gbl_contentPane.columnWeights	= new double[] { 0.3, 1.0, 0.1 }; | ||||
| 		gbl_contentPane.rowWeights		= new double[] { 0.05, 1.0, 0.07 }; | ||||
| 		contentPane.setLayout(gbl_contentPane); | ||||
|  | ||||
| 		JList<Message> messageList = new JList<>(); | ||||
| 		messageList.setCellRenderer(new MessageListRenderer()); | ||||
|  | ||||
| 		messageList.setFocusTraversalKeysEnabled(false); | ||||
| 		messageList.setSelectionForeground(new Color(255, 255, 255)); | ||||
| 		messageList.setSelectionBackground(new Color(102, 0, 153)); | ||||
| 		messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); | ||||
| 		messageList.setForeground(new Color(255, 255, 255)); | ||||
| 		messageList.setBackground(new Color(51, 51, 51)); | ||||
|  | ||||
| 		DefaultListModel<Message> messageListModel = new DefaultListModel<>(); | ||||
| 		messageList.setModel(messageListModel); | ||||
| 		messageList.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		messageList.setFixedCellHeight(60); | ||||
| 		messageList.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		JScrollPane scrollPane = new JScrollPane(); | ||||
| 		scrollPane.setForeground(new Color(0, 0, 0)); | ||||
| 		scrollPane.setBackground(new Color(51, 51, 51)); | ||||
| 		scrollPane.setViewportView(messageList); | ||||
| 		scrollPane.setBorder(null); | ||||
|  | ||||
| 		GridBagConstraints gbc_scrollPane = new GridBagConstraints(); | ||||
| 		gbc_scrollPane.fill			= GridBagConstraints.BOTH; | ||||
| 		gbc_scrollPane.gridwidth	= 2; | ||||
| 		gbc_scrollPane.gridx		= 1; | ||||
| 		gbc_scrollPane.gridy		= 1; | ||||
|  | ||||
| 		gbc_scrollPane.insets = new Insets(0, 10, 10, 10); | ||||
|  | ||||
| 		contentPane.add(scrollPane, gbc_scrollPane); | ||||
|  | ||||
| 		// Message enter field | ||||
| 		messageEnterTextArea = new JTextArea(); | ||||
| 		messageEnterTextArea.addKeyListener(new KeyAdapter() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void keyReleased(KeyEvent e) { | ||||
|  | ||||
| 				if (e.getKeyCode() == KeyEvent.VK_ENTER && ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) | ||||
| 						|| (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) { | ||||
|  | ||||
| 					postMessage(messageList); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		}); | ||||
| 		// Checks for changed Message | ||||
| 		messageEnterTextArea.setWrapStyleWord(true); | ||||
| 		messageEnterTextArea.setCaretColor(new Color(255, 255, 255)); | ||||
| 		messageEnterTextArea.setForeground(new Color(255, 255, 255)); | ||||
| 		messageEnterTextArea.setBackground(new Color(51, 51, 51)); | ||||
| 		messageEnterTextArea.setLineWrap(true); | ||||
| 		messageEnterTextArea.setBorder(null); | ||||
| 		messageEnterTextArea.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		messageEnterTextArea.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints(); | ||||
| 		gbc_messageEnterTextfield.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_messageEnterTextfield.gridx	= 1; | ||||
| 		gbc_messageEnterTextfield.gridy	= 2; | ||||
|  | ||||
| 		gbc_messageEnterTextfield.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); | ||||
|  | ||||
| 		// Post Button | ||||
| 		JButton postButton = new JButton("Post"); | ||||
| 		postButton.setForeground(new Color(255, 255, 255)); | ||||
| 		postButton.setBackground(new Color(102, 51, 153)); | ||||
| 		postButton.setBorderPainted(false); | ||||
|  | ||||
| 		GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionPostButton.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_moveSelectionPostButton.gridx	= 2; | ||||
| 		gbc_moveSelectionPostButton.gridy	= 2; | ||||
|  | ||||
| 		gbc_moveSelectionPostButton.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		postButton.addActionListener((evt) -> { postMessage(messageList); }); | ||||
| 		contentPane.add(postButton, gbc_moveSelectionPostButton); | ||||
|  | ||||
| 		// Settings Button | ||||
| 		JButton settingsButton = new JButton("Settings"); | ||||
| 		settingsButton.setForeground(new Color(255, 255, 255)); | ||||
| 		settingsButton.setBackground(new Color(102, 51, 153)); | ||||
| 		settingsButton.setBorderPainted(false); | ||||
|  | ||||
| 		GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionSettingsButton.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_moveSelectionSettingsButton.gridx	= 2; | ||||
| 		gbc_moveSelectionSettingsButton.gridy	= 0; | ||||
|  | ||||
| 		gbc_moveSelectionSettingsButton.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		settingsButton.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 				SettingsScreen.open(localDB.getUser().getName()); | ||||
| 			} catch (Exception e) { | ||||
| 				SettingsScreen.open(); | ||||
| 				logger.warning("An error occured while opening the settings screen: " + e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		}); | ||||
| 		contentPane.add(settingsButton, gbc_moveSelectionSettingsButton); | ||||
|  | ||||
| 		// Partner name display | ||||
| 		JTextPane textPane = new JTextPane(); | ||||
| 		textPane.setBackground(new Color(0, 0, 0)); | ||||
| 		textPane.setForeground(new Color(255, 255, 255)); | ||||
|  | ||||
| 		textPane.setFont(new Font("Arial", Font.PLAIN, 20)); | ||||
|  | ||||
| 		GridBagConstraints gbc_partnerName = new GridBagConstraints(); | ||||
| 		gbc_partnerName.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 		gbc_partnerName.gridx	= 1; | ||||
| 		gbc_partnerName.gridy	= 0; | ||||
|  | ||||
| 		gbc_partnerName.insets = new Insets(0, 10, 0, 10); | ||||
| 		contentPane.add(textPane, gbc_partnerName); | ||||
|  | ||||
| 		userList.setCellRenderer(new UserListRenderer()); | ||||
| 		userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | ||||
| 		userList.addListSelectionListener((listSelectionEvent) -> { | ||||
| 			if (!listSelectionEvent.getValueIsAdjusting()) { | ||||
| 				@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(); | ||||
|  | ||||
| 				// Set all unread messages in the chat to read | ||||
| 				readCurrentChat(); | ||||
|  | ||||
| 				client.setRecipient(user); | ||||
|  | ||||
| 				textPane.setText(currentChat.getRecipient().getName()); | ||||
|  | ||||
| 				messageList.setModel(currentChat.getModel()); | ||||
| 				contentPane.revalidate(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		userList.setSelectionForeground(new Color(255, 255, 255)); | ||||
| 		userList.setSelectionBackground(new Color(102, 0, 153)); | ||||
| 		userList.setForeground(new Color(255, 255, 255)); | ||||
| 		userList.setBackground(new Color(51, 51, 51)); | ||||
| 		userList.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		userList.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		GridBagConstraints gbc_userList = new GridBagConstraints(); | ||||
| 		gbc_userList.fill	= GridBagConstraints.VERTICAL; | ||||
| 		gbc_userList.gridx	= 0; | ||||
| 		gbc_userList.gridy	= 1; | ||||
| 		gbc_userList.anchor	= GridBagConstraints.PAGE_START; | ||||
| 		gbc_userList.insets	= new Insets(0, 0, 10, 0); | ||||
|  | ||||
| 		contentPane.add(userList, gbc_userList); | ||||
| 		contentPane.revalidate(); | ||||
|  | ||||
| 		loadUsersAndChats(); | ||||
| 		startSyncThread(Config.getInstance().getSyncTimeout()); | ||||
|  | ||||
| 		contentPane.revalidate(); | ||||
| 	} | ||||
|  | ||||
| 	private void postMessage(JList<Message> messageList) { | ||||
| 		if (!client.hasRecipient()) { | ||||
| 			JOptionPane.showMessageDialog(this, | ||||
| 					"Please select a recipient!", | ||||
| 					"Cannot send message", | ||||
| 					JOptionPane.INFORMATION_MESSAGE); | ||||
| 		} | ||||
|  | ||||
| 		if (!messageEnterTextArea.getText().isEmpty()) try { | ||||
|  | ||||
| 			// Create and send message object | ||||
| 			final Message message = localDB.createMessage(messageEnterTextArea.getText(), currentChat.getRecipient()); | ||||
| 			currentChat.appendMessage(message); | ||||
| 			messageList.setModel(currentChat.getModel()); | ||||
|  | ||||
| 			// Clear text field | ||||
| 			messageEnterTextArea.setText(""); | ||||
| 			contentPane.revalidate(); | ||||
| 		} catch (Exception e) { | ||||
| 			JOptionPane.showMessageDialog(this, | ||||
| 					"An exception occured while sending a message. See the log for more details.", | ||||
| 					"Exception occured", | ||||
| 					JOptionPane.ERROR_MESSAGE); | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes the elements of the user list by downloading them from the | ||||
| 	 * server. | ||||
| 	 *  | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void loadUsersAndChats() { | ||||
| 		new Thread(() -> { | ||||
| 			Sync					users			= client.getUsersListXml(); | ||||
| 			DefaultListModel<User>	userListModel	= new DefaultListModel<>(); | ||||
| 			users.getUsers().forEach(user -> { | ||||
| 				userListModel.addElement(user); | ||||
|  | ||||
| 				// Check if user exists in local DB | ||||
| 				if (localDB.getChats().stream().filter(c -> c.getRecipient().getID() == user.getID()).count() == 0) | ||||
| 					localDB.getChats().add(new Chat(user)); | ||||
| 			}); | ||||
| 			SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); | ||||
| 		}).start(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Updates the data model and the UI repeatedly after a certain amount of | ||||
| 	 * time. | ||||
| 	 *  | ||||
| 	 * @param timeout the amount of time that passes between two requests sent to | ||||
| 	 *                the server | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void startSyncThread(int timeout) { | ||||
| 		new Timer(timeout, (evt) -> { | ||||
| 			new Thread(() -> { | ||||
|  | ||||
| 				// Synchronize | ||||
| 				localDB.applySync( | ||||
| 						client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID()))); | ||||
|  | ||||
| 				// 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) { localDB.setMessagesToRead(currentChat); } } | ||||
| } | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Color; | ||||
| import java.awt.ComponentOrientation; | ||||
| import java.awt.Font; | ||||
| import java.awt.GridBagConstraints; | ||||
| import java.awt.GridBagLayout; | ||||
| import java.awt.Insets; | ||||
| import java.awt.event.KeyAdapter; | ||||
| import java.awt.event.KeyEvent; | ||||
| import java.awt.event.WindowAdapter; | ||||
| import java.awt.event.WindowEvent; | ||||
| import java.io.IOException; | ||||
| 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; | ||||
| import javax.swing.Timer; | ||||
| import javax.swing.border.EmptyBorder; | ||||
|  | ||||
| import envoy.client.Chat; | ||||
| import envoy.client.Client; | ||||
| import envoy.client.Config; | ||||
| import envoy.client.LocalDB; | ||||
| import envoy.schema.Message; | ||||
| import envoy.schema.Sync; | ||||
| import envoy.schema.User; | ||||
|  | ||||
| /** | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>ChatWindow.java</strong><br> | ||||
|  * Created: <strong>28 Sep 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @author Leon Hofmeister | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class ChatWindow extends JFrame { | ||||
|  | ||||
| 	private static final long serialVersionUID = 6865098428255463649L; | ||||
|  | ||||
| 	private JPanel contentPane = new JPanel(); | ||||
|  | ||||
| 	private Client	client; | ||||
| 	private LocalDB	localDB; | ||||
|  | ||||
| 	private JList<User>	userList	= new JList<>(); | ||||
| 	private Chat		currentChat; | ||||
|  | ||||
| 	private JTextArea messageEnterTextArea; | ||||
|  | ||||
| 	private static final Logger logger = Logger.getLogger(ChatWindow.class.getSimpleName()); | ||||
|  | ||||
| 	public ChatWindow(Client client, LocalDB localDB) { | ||||
| 		this.client		= client; | ||||
| 		this.localDB	= localDB; | ||||
|  | ||||
| 		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | ||||
| 		setBounds(100, 100, 600, 800); | ||||
| 		setTitle("Envoy"); | ||||
| 		setLocationRelativeTo(null); | ||||
|  | ||||
| 		// Save chats when window closes | ||||
| 		addWindowListener(new WindowAdapter() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void windowClosing(WindowEvent evt) { | ||||
| 				try { | ||||
| 					localDB.saveToLocalDB(); | ||||
| 				} catch (IOException e1) { | ||||
| 					e1.printStackTrace(); | ||||
| 					logger.log(Level.WARNING, "Unable to save the messages", e1); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		contentPane.setBackground(new Color(0, 0, 0)); | ||||
| 		contentPane.setForeground(Color.white); | ||||
| 		contentPane.setBorder(new EmptyBorder(0, 5, 0, 0)); | ||||
| 		setContentPane(contentPane); | ||||
| 		GridBagLayout gbl_contentPane = new GridBagLayout(); | ||||
| 		gbl_contentPane.columnWidths	= new int[] { 1, 1, 1 }; | ||||
| 		gbl_contentPane.rowHeights		= new int[] { 1, 1, 1 }; | ||||
| 		gbl_contentPane.columnWeights	= new double[] { 0.3, 1.0, 0.1 }; | ||||
| 		gbl_contentPane.rowWeights		= new double[] { 0.05, 1.0, 0.07 }; | ||||
| 		contentPane.setLayout(gbl_contentPane); | ||||
|  | ||||
| 		JList<Message> messageList = new JList<>(); | ||||
| 		messageList.setCellRenderer(new MessageListRenderer()); | ||||
|  | ||||
| 		messageList.setFocusTraversalKeysEnabled(false); | ||||
| 		messageList.setSelectionForeground(new Color(255, 255, 255)); | ||||
| 		messageList.setSelectionBackground(new Color(102, 0, 153)); | ||||
| 		messageList.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT); | ||||
| 		messageList.setForeground(new Color(255, 255, 255)); | ||||
| 		messageList.setBackground(new Color(51, 51, 51)); | ||||
|  | ||||
| 		DefaultListModel<Message> messageListModel = new DefaultListModel<>(); | ||||
| 		messageList.setModel(messageListModel); | ||||
| 		messageList.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		messageList.setFixedCellHeight(60); | ||||
| 		messageList.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		JScrollPane scrollPane = new JScrollPane(); | ||||
| 		scrollPane.setForeground(new Color(0, 0, 0)); | ||||
| 		scrollPane.setBackground(new Color(51, 51, 51)); | ||||
| 		scrollPane.setViewportView(messageList); | ||||
| 		scrollPane.setBorder(null); | ||||
|  | ||||
| 		GridBagConstraints gbc_scrollPane = new GridBagConstraints(); | ||||
| 		gbc_scrollPane.fill			= GridBagConstraints.BOTH; | ||||
| 		gbc_scrollPane.gridwidth	= 2; | ||||
| 		gbc_scrollPane.gridx		= 1; | ||||
| 		gbc_scrollPane.gridy		= 1; | ||||
|  | ||||
| 		gbc_scrollPane.insets = new Insets(0, 10, 10, 10); | ||||
|  | ||||
| 		contentPane.add(scrollPane, gbc_scrollPane); | ||||
|  | ||||
| 		// Message enter field | ||||
| 		messageEnterTextArea = new JTextArea(); | ||||
| 		messageEnterTextArea.addKeyListener(new KeyAdapter() { | ||||
|  | ||||
| 			@Override | ||||
| 			public void keyReleased(KeyEvent e) { | ||||
|  | ||||
| 				if (e.getKeyCode() == KeyEvent.VK_ENTER | ||||
| 						&& ((SettingsScreen.enterToSend && e.getModifiersEx() == 0) || (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK))) { | ||||
|  | ||||
| 					postMessage(messageList); | ||||
| 				} | ||||
|  | ||||
| 			} | ||||
| 		}); | ||||
| 		// Checks for changed Message | ||||
| 		messageEnterTextArea.setWrapStyleWord(true); | ||||
| 		messageEnterTextArea.setCaretColor(new Color(255, 255, 255)); | ||||
| 		messageEnterTextArea.setForeground(new Color(255, 255, 255)); | ||||
| 		messageEnterTextArea.setBackground(new Color(51, 51, 51)); | ||||
| 		messageEnterTextArea.setLineWrap(true); | ||||
| 		messageEnterTextArea.setBorder(null); | ||||
| 		messageEnterTextArea.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		messageEnterTextArea.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		GridBagConstraints gbc_messageEnterTextfield = new GridBagConstraints(); | ||||
| 		gbc_messageEnterTextfield.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_messageEnterTextfield.gridx	= 1; | ||||
| 		gbc_messageEnterTextfield.gridy	= 2; | ||||
|  | ||||
| 		gbc_messageEnterTextfield.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		contentPane.add(messageEnterTextArea, gbc_messageEnterTextfield); | ||||
|  | ||||
| 		// Post Button | ||||
| 		JButton postButton = new JButton("Post"); | ||||
| 		postButton.setForeground(new Color(255, 255, 255)); | ||||
| 		postButton.setBackground(new Color(102, 51, 153)); | ||||
| 		postButton.setBorderPainted(false); | ||||
|  | ||||
| 		GridBagConstraints gbc_moveSelectionPostButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionPostButton.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_moveSelectionPostButton.gridx	= 2; | ||||
| 		gbc_moveSelectionPostButton.gridy	= 2; | ||||
|  | ||||
| 		gbc_moveSelectionPostButton.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		postButton.addActionListener((evt) -> { postMessage(messageList); }); | ||||
| 		contentPane.add(postButton, gbc_moveSelectionPostButton); | ||||
|  | ||||
| 		// Settings Button | ||||
| 		JButton settingsButton = new JButton("Settings"); | ||||
| 		settingsButton.setForeground(new Color(255, 255, 255)); | ||||
| 		settingsButton.setBackground(new Color(102, 51, 153)); | ||||
| 		settingsButton.setBorderPainted(false); | ||||
|  | ||||
| 		GridBagConstraints gbc_moveSelectionSettingsButton = new GridBagConstraints(); | ||||
|  | ||||
| 		gbc_moveSelectionSettingsButton.fill	= GridBagConstraints.BOTH; | ||||
| 		gbc_moveSelectionSettingsButton.gridx	= 2; | ||||
| 		gbc_moveSelectionSettingsButton.gridy	= 0; | ||||
|  | ||||
| 		gbc_moveSelectionSettingsButton.insets = new Insets(10, 10, 10, 10); | ||||
|  | ||||
| 		settingsButton.addActionListener((evt) -> { | ||||
| 			try { | ||||
| 				SettingsScreen.open(localDB.getUser().getName()); | ||||
| 			} catch (Exception e) { | ||||
| 				SettingsScreen.open(); | ||||
| 				logger.log(Level.WARNING, "An error occured while opening the settings screen", e); | ||||
| 				e.printStackTrace(); | ||||
| 			} | ||||
| 		}); | ||||
| 		contentPane.add(settingsButton, gbc_moveSelectionSettingsButton); | ||||
|  | ||||
| 		// Partner name display | ||||
| 		JTextPane textPane = new JTextPane(); | ||||
| 		textPane.setBackground(new Color(0, 0, 0)); | ||||
| 		textPane.setForeground(new Color(255, 255, 255)); | ||||
|  | ||||
| 		textPane.setFont(new Font("Arial", Font.PLAIN, 20)); | ||||
|  | ||||
| 		GridBagConstraints gbc_partnerName = new GridBagConstraints(); | ||||
| 		gbc_partnerName.fill	= GridBagConstraints.HORIZONTAL; | ||||
| 		gbc_partnerName.gridx	= 1; | ||||
| 		gbc_partnerName.gridy	= 0; | ||||
|  | ||||
| 		gbc_partnerName.insets = new Insets(0, 10, 0, 10); | ||||
| 		contentPane.add(textPane, gbc_partnerName); | ||||
|  | ||||
| 		userList.setCellRenderer(new UserListRenderer()); | ||||
| 		userList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); | ||||
| 		userList.addListSelectionListener((listSelectionEvent) -> { | ||||
| 			if (!listSelectionEvent.getValueIsAdjusting()) { | ||||
| 				@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(); | ||||
|  | ||||
| 				// Set all unread messages in the chat to read | ||||
| 				readCurrentChat(); | ||||
|  | ||||
| 				client.setRecipient(user); | ||||
|  | ||||
| 				textPane.setText(currentChat.getRecipient().getName()); | ||||
|  | ||||
| 				messageList.setModel(currentChat.getModel()); | ||||
| 				contentPane.revalidate(); | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		userList.setSelectionForeground(new Color(255, 255, 255)); | ||||
| 		userList.setSelectionBackground(new Color(102, 0, 153)); | ||||
| 		userList.setForeground(new Color(255, 255, 255)); | ||||
| 		userList.setBackground(new Color(51, 51, 51)); | ||||
| 		userList.setFont(new Font("Arial", Font.PLAIN, 17)); | ||||
| 		userList.setBorder(new EmptyBorder(5, 5, 5, 5)); | ||||
|  | ||||
| 		GridBagConstraints gbc_userList = new GridBagConstraints(); | ||||
| 		gbc_userList.fill	= GridBagConstraints.VERTICAL; | ||||
| 		gbc_userList.gridx	= 0; | ||||
| 		gbc_userList.gridy	= 1; | ||||
| 		gbc_userList.anchor	= GridBagConstraints.PAGE_START; | ||||
| 		gbc_userList.insets	= new Insets(0, 0, 10, 0); | ||||
|  | ||||
| 		contentPane.add(userList, gbc_userList); | ||||
| 		contentPane.revalidate(); | ||||
|  | ||||
| 		loadUsersAndChats(); | ||||
| 		startSyncThread(Config.getInstance().getSyncTimeout()); | ||||
|  | ||||
| 		contentPane.revalidate(); | ||||
| 	} | ||||
|  | ||||
| 	private void postMessage(JList<Message> messageList) { | ||||
| 		if (!client.hasRecipient()) { | ||||
| 			JOptionPane.showMessageDialog(this, "Please select a recipient!", "Cannot send message", JOptionPane.INFORMATION_MESSAGE); | ||||
| 		} | ||||
|  | ||||
| 		if (!messageEnterTextArea.getText().isEmpty()) try { | ||||
|  | ||||
| 			// Create and send message object | ||||
| 			final Message message = localDB.createMessage(messageEnterTextArea.getText(), currentChat.getRecipient()); | ||||
| 			currentChat.appendMessage(message); | ||||
| 			messageList.setModel(currentChat.getModel()); | ||||
|  | ||||
| 			// Clear text field | ||||
| 			messageEnterTextArea.setText(""); | ||||
| 			contentPane.revalidate(); | ||||
| 		} catch (Exception e) { | ||||
| 			JOptionPane.showMessageDialog(this, | ||||
| 					"An exception occured while sending a message. See the log for more details.", | ||||
| 					"Exception occured", | ||||
| 					JOptionPane.ERROR_MESSAGE); | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Initializes the elements of the user list by downloading them from the | ||||
| 	 * server. | ||||
| 	 *  | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void loadUsersAndChats() { | ||||
| 		new Thread(() -> { | ||||
| 			Sync					users			= client.getUsersListXml(); | ||||
| 			DefaultListModel<User>	userListModel	= new DefaultListModel<>(); | ||||
| 			users.getUsers().forEach(user -> { | ||||
| 				userListModel.addElement(user); | ||||
|  | ||||
| 				// Check if user exists in local DB | ||||
| 				if (localDB.getChats().stream().filter(c -> c.getRecipient().getID() == user.getID()).count() == 0) | ||||
| 					localDB.getChats().add(new Chat(user)); | ||||
| 			}); | ||||
| 			SwingUtilities.invokeLater(() -> userList.setModel(userListModel)); | ||||
| 		}).start(); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * Updates the data model and the UI repeatedly after a certain amount of | ||||
| 	 * time. | ||||
| 	 *  | ||||
| 	 * @param timeout the amount of time that passes between two requests sent to | ||||
| 	 *                the server | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	private void startSyncThread(int timeout) { | ||||
| 		new Timer(timeout, (evt) -> { | ||||
| 			new Thread(() -> { | ||||
|  | ||||
| 				// Synchronize | ||||
| 				localDB.applySync(client.sendSync(client.getSender().getID(), localDB.fillSync(client.getSender().getID()))); | ||||
|  | ||||
| 				// 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) { localDB.setMessagesToRead(currentChat); } } | ||||
| } | ||||
|   | ||||
| @@ -1,54 +1,49 @@ | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Component; | ||||
| import java.text.SimpleDateFormat; | ||||
|  | ||||
| import javax.swing.JLabel; | ||||
| import javax.swing.JList; | ||||
| import javax.swing.ListCellRenderer; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Defines how a message is displayed.<br> | ||||
|  * <br> | ||||
|  *  | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>UserListRenderer.java</strong><br> | ||||
|  * Created: <strong>19 Oct 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class MessageListRenderer extends JLabel implements ListCellRenderer<Message> { | ||||
|  | ||||
| 	private static final long serialVersionUID = 5164417379767181198L; | ||||
|  | ||||
| 	@Override | ||||
| 	public Component getListCellRendererComponent(JList<? extends Message> list, Message value, int index, | ||||
| 			boolean isSelected, boolean cellHasFocus) { | ||||
| 		if (isSelected) { | ||||
| 			setBackground(list.getSelectionBackground()); | ||||
| 			setForeground(list.getSelectionForeground()); | ||||
| 		} else { | ||||
| 			setBackground(list.getBackground()); | ||||
| 			setForeground(list.getForeground()); | ||||
| 		} | ||||
|  | ||||
| 		setOpaque(true); | ||||
|  | ||||
| 		final String	text	= value.getContent().get(0).getText(); | ||||
| 		final String 	state 	= value.getMetadata().getState().toString(); | ||||
| 		final String	date	= value.getMetadata().getDate() == null ? "" | ||||
| 				: new SimpleDateFormat("dd.MM.yyyy HH:mm ") | ||||
| 					.format(value.getMetadata().getDate().toGregorianCalendar().getTime()); | ||||
|  | ||||
| 		setText(String.format( | ||||
| 				"<html><p style=\"color:#d2d235\"><b><small>%s</b></small><br><p style=\"color:white\">%s :%s</html>", | ||||
| 				date, | ||||
| 				text, | ||||
| 				state)); | ||||
| 		return this; | ||||
| 	} | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Component; | ||||
| import java.text.SimpleDateFormat; | ||||
|  | ||||
| import javax.swing.JLabel; | ||||
| import javax.swing.JList; | ||||
| import javax.swing.ListCellRenderer; | ||||
|  | ||||
| import envoy.schema.Message; | ||||
|  | ||||
| /** | ||||
|  * Defines how a message is displayed.<br> | ||||
|  * <br> | ||||
|  *  | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>UserListRenderer.java</strong><br> | ||||
|  * Created: <strong>19 Oct 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class MessageListRenderer extends JLabel implements ListCellRenderer<Message> { | ||||
|  | ||||
| 	private static final long serialVersionUID = 5164417379767181198L; | ||||
|  | ||||
| 	@Override | ||||
| 	public Component getListCellRendererComponent(JList<? extends Message> list, Message value, int index, boolean isSelected, boolean cellHasFocus) { | ||||
| 		if (isSelected) { | ||||
| 			setBackground(list.getSelectionBackground()); | ||||
| 			setForeground(list.getSelectionForeground()); | ||||
| 		} else { | ||||
| 			setBackground(list.getBackground()); | ||||
| 			setForeground(list.getForeground()); | ||||
| 		} | ||||
|  | ||||
| 		setOpaque(true); | ||||
|  | ||||
| 		final String	text	= value.getContent().get(0).getText(); | ||||
| 		final String	state	= value.getMetadata().getState().toString(); | ||||
| 		final String	date	= value.getMetadata().getDate() == null ? "" | ||||
| 				: new SimpleDateFormat("dd.MM.yyyy HH:mm ").format(value.getMetadata().getDate().toGregorianCalendar().getTime()); | ||||
|  | ||||
| 		setText(String | ||||
| 			.format("<html><p style=\"color:#d2d235\"><b><small>%s</b></small><br><p style=\"color:white\">%s :%s</html>", date, text, state)); | ||||
| 		return this; | ||||
| 	} | ||||
| } | ||||
| @@ -41,7 +41,6 @@ public class SettingsScreen extends JDialog { | ||||
| 	 * It personalises the screen more. | ||||
| 	 *  | ||||
| 	 * @param username The name of the User | ||||
| 	 * @param Email    The Email that is associated with that Account | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public static void open(String username) {// , String Email) {AUSKLAMMERN, WENN ANMELDUNG PER | ||||
| @@ -101,7 +100,6 @@ public class SettingsScreen extends JDialog { | ||||
| 	 * It personalises the screen more. | ||||
| 	 *  | ||||
| 	 * @param Username The name of the User | ||||
| 	 * @param Email    The Email that is associated with that Account | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public SettingsScreen(String Username) {// , String Email, String hashedPwd) {AUSKLAMMERN, WENN ANMELDUNG PER EMAIL | ||||
| @@ -145,10 +143,10 @@ public class SettingsScreen extends JDialog { | ||||
| 	public static boolean isEnterToSend() { return enterToSend; } | ||||
|  | ||||
| 	/** | ||||
| 	 * @param enterToSend <br> | ||||
| 	 *                    toggles whether a message should be sent via | ||||
| 	 *                    <br> | ||||
| 	 *                    buttonpress "enter" or "ctrl"+"enter" | ||||
| 	 * @param enterForSend <br> | ||||
| 	 *                     toggles whether a message should be sent via | ||||
| 	 *                     <br> | ||||
| 	 *                     buttonpress "enter" or "ctrl"+"enter" | ||||
| 	 * @since Envoy v0.1-alpha | ||||
| 	 */ | ||||
| 	public static void setEnterToSend(boolean enterForSend) { enterToSend = enterForSend; } | ||||
|   | ||||
| @@ -26,11 +26,11 @@ import envoy.exception.EnvoyException; | ||||
|  */ | ||||
| public class Startup { | ||||
|  | ||||
| 	private static final Logger logger = Logger.getLogger(Client.class.getSimpleName()); | ||||
| 	 | ||||
| 	private static final Logger logger = Logger.getLogger(Startup.class.getSimpleName()); | ||||
|  | ||||
| 	public static void main(String[] args) { | ||||
| 		logger.setLevel(Level.ALL); | ||||
| 		 | ||||
|  | ||||
| 		Config config = Config.getInstance(); | ||||
|  | ||||
| 		// Load the configuration from client.properties first | ||||
| @@ -44,30 +44,29 @@ public class Startup { | ||||
| 		} | ||||
|  | ||||
| 		// Override configuration values with command line arguments | ||||
| 		if (args.length > 0) | ||||
| 			config.load(args); | ||||
| 		if (args.length > 0) config.load(args); | ||||
|  | ||||
| 		if (!config.isInitialized()) { | ||||
| 			logger.warning("Server or port are not defined. Exiting..."); | ||||
| 			JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", | ||||
| 					JOptionPane.ERROR_MESSAGE); | ||||
| 			logger.severe("Server or port are not defined. Exiting..."); | ||||
| 			JOptionPane.showMessageDialog(null, "Error loading configuration values.", "Configuration error", JOptionPane.ERROR_MESSAGE); | ||||
| 			System.exit(1); | ||||
| 		} | ||||
|  | ||||
| 		String userName = JOptionPane.showInputDialog("Please enter your username"); | ||||
| 		if (userName == null || userName.isEmpty()) { | ||||
| 			logger.warning("User name is not set or empty. Exiting..."); | ||||
| 			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()); | ||||
| 		Client	client	= new Client(config, userName); | ||||
| 		LocalDB	localDB	= new LocalDB(client.getSender()); | ||||
| 		try { | ||||
| 			localDB.initializeDBFile(config.getLocalDB()); | ||||
| 		} catch (EnvoyException e) { | ||||
| 			e.printStackTrace(); | ||||
| 			JOptionPane.showMessageDialog(null, | ||||
| 					"Error while loading local database: " + e.toString() + "\nChats will not be stored locally.", | ||||
| 					"Local DB error", JOptionPane.WARNING_MESSAGE); | ||||
| 					"Local DB error", | ||||
| 					JOptionPane.WARNING_MESSAGE); | ||||
| 		} | ||||
|  | ||||
| 		EventQueue.invokeLater(() -> { | ||||
|   | ||||
| @@ -1,65 +1,56 @@ | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Component; | ||||
|  | ||||
| import javax.swing.JLabel; | ||||
| import javax.swing.JList; | ||||
| import javax.swing.ListCellRenderer; | ||||
|  | ||||
| import envoy.schema.User; | ||||
| import envoy.schema.User.UserStatus; | ||||
|  | ||||
| /** | ||||
|  * Defines how the {@code UserList} is displayed. | ||||
|  *  | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>UserListRenderer.java</strong><br> | ||||
|  * Created: <strong>12 Oct 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class UserListRenderer extends JLabel implements ListCellRenderer<User> { | ||||
|  | ||||
| 	private static final long serialVersionUID = 5164417379767181198L; | ||||
|  | ||||
| 	@Override | ||||
| 	public Component getListCellRendererComponent(JList<? extends User> list, User value, int index, boolean isSelected, | ||||
| 			boolean cellHasFocus) { | ||||
| 		if (isSelected) { | ||||
| 			setBackground(list.getSelectionBackground()); | ||||
| 			setForeground(list.getSelectionForeground()); | ||||
| 		} else { | ||||
| 			setBackground(list.getBackground()); | ||||
| 			setForeground(list.getForeground()); | ||||
| 		} | ||||
|  | ||||
| 		// Enable background rendering | ||||
| 		setOpaque(true); | ||||
|  | ||||
|  | ||||
| 		final String		name	= value.getName(); | ||||
| 		final UserStatus	status	= value.getStatus(); | ||||
| 		 | ||||
| 		switch (status) { | ||||
| 			case ONLINE: | ||||
| 				setText(String.format( | ||||
| 						"<html><p style=\"color:#03fc20\"><b><small>%s</b></small><br><p style=\"color:white\">%s</html>", | ||||
| 						status, | ||||
| 						name)); | ||||
| 				break; | ||||
|  | ||||
| 			case OFFLINE: | ||||
| 				setText(String.format( | ||||
| 						"<html><p style=\"color:#fc0303\"><b><small>%s</b></small><br><p style=\"color:white\">%s</html>", | ||||
| 						status, | ||||
| 						name)); | ||||
| 				break; | ||||
| 		} | ||||
|  | ||||
| 		 | ||||
|  | ||||
| 		return this; | ||||
| 	} | ||||
| package envoy.client.ui; | ||||
|  | ||||
| import java.awt.Component; | ||||
|  | ||||
| import javax.swing.JLabel; | ||||
| import javax.swing.JList; | ||||
| import javax.swing.ListCellRenderer; | ||||
|  | ||||
| import envoy.schema.User; | ||||
| import envoy.schema.User.UserStatus; | ||||
|  | ||||
| /** | ||||
|  * Defines how the {@code UserList} is displayed. | ||||
|  *  | ||||
|  * Project: <strong>envoy-client</strong><br> | ||||
|  * File: <strong>UserListRenderer.java</strong><br> | ||||
|  * Created: <strong>12 Oct 2019</strong><br> | ||||
|  *  | ||||
|  * @author Kai S. K. Engelbart | ||||
|  * @author Maximilian Käfer | ||||
|  * @since Envoy v0.1-alpha | ||||
|  */ | ||||
| public class UserListRenderer extends JLabel implements ListCellRenderer<User> { | ||||
|  | ||||
| 	private static final long serialVersionUID = 5164417379767181198L; | ||||
|  | ||||
| 	@SuppressWarnings("incomplete-switch") | ||||
| 	@Override | ||||
| 	public Component getListCellRendererComponent(JList<? extends User> list, User value, int index, boolean isSelected, boolean cellHasFocus) { | ||||
| 		if (isSelected) { | ||||
| 			setBackground(list.getSelectionBackground()); | ||||
| 			setForeground(list.getSelectionForeground()); | ||||
| 		} else { | ||||
| 			setBackground(list.getBackground()); | ||||
| 			setForeground(list.getForeground()); | ||||
| 		} | ||||
|  | ||||
| 		// Enable background rendering | ||||
| 		setOpaque(true); | ||||
|  | ||||
| 		final String		name	= value.getName(); | ||||
| 		final UserStatus	status	= value.getStatus(); | ||||
|  | ||||
| 		switch (status) { | ||||
| 			case ONLINE: | ||||
| 				setText(String | ||||
| 					.format("<html><p style=\"color:#03fc20\"><b><small>%s</b></small><br><p style=\"color:white\">%s</html>", status, name)); | ||||
| 				break; | ||||
| 			case OFFLINE: | ||||
| 				setText(String | ||||
| 					.format("<html><p style=\"color:#fc0303\"><b><small>%s</b></small><br><p style=\"color:white\">%s</html>", status, name)); | ||||
| 				break; | ||||
| 		} | ||||
| 		return this; | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 delvh
					delvh