Add Generic ListViewFactory
This commit is contained in:
		@@ -34,9 +34,9 @@ import envoy.client.net.WriteProxy;
 | 
			
		||||
import envoy.client.ui.IconUtil;
 | 
			
		||||
import envoy.client.ui.Restorable;
 | 
			
		||||
import envoy.client.ui.SceneContext;
 | 
			
		||||
import envoy.client.ui.listcell.ChatListCellFactory;
 | 
			
		||||
import envoy.client.ui.listcell.ChatControl;
 | 
			
		||||
import envoy.client.ui.listcell.ListCellFactory;
 | 
			
		||||
import envoy.client.ui.listcell.MessageControl;
 | 
			
		||||
import envoy.client.ui.listcell.MessageListCellFactory;
 | 
			
		||||
import envoy.data.*;
 | 
			
		||||
import envoy.data.Attachment.AttachmentType;
 | 
			
		||||
import envoy.event.*;
 | 
			
		||||
@@ -124,8 +124,8 @@ public final class ChatScene implements Restorable {
 | 
			
		||||
	private void initialize() {
 | 
			
		||||
 | 
			
		||||
		// Initialize message and user rendering
 | 
			
		||||
		messageList.setCellFactory(MessageListCellFactory::new);
 | 
			
		||||
		chatList.setCellFactory(ChatListCellFactory::new);
 | 
			
		||||
		messageList.setCellFactory(new ListCellFactory<>(MessageControl::new));
 | 
			
		||||
		chatList.setCellFactory(new ListCellFactory<>(ChatControl::new));
 | 
			
		||||
 | 
			
		||||
		settingsButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("settings", DEFAULT_ICON_SIZE)));
 | 
			
		||||
		voiceButton.setGraphic(new ImageView(IconUtil.loadIconThemeSensitive("microphone", DEFAULT_ICON_SIZE)));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@ import envoy.client.data.LocalDB;
 | 
			
		||||
import envoy.client.event.SendEvent;
 | 
			
		||||
import envoy.client.ui.ClearableTextField;
 | 
			
		||||
import envoy.client.ui.SceneContext;
 | 
			
		||||
import envoy.client.ui.listcell.ContactListCellFactory;
 | 
			
		||||
import envoy.client.ui.listcell.ContactControl;
 | 
			
		||||
import envoy.client.ui.listcell.ListCellFactory;
 | 
			
		||||
import envoy.data.User;
 | 
			
		||||
import envoy.event.ElementOperation;
 | 
			
		||||
import envoy.event.EventBus;
 | 
			
		||||
@@ -67,7 +68,7 @@ public class ContactSearchScene {
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void initialize() {
 | 
			
		||||
		userList.setCellFactory(new ContactListCellFactory<>());
 | 
			
		||||
		userList.setCellFactory(new ListCellFactory<>(ContactControl::new));
 | 
			
		||||
		searchBar.setClearButtonListener(e -> { searchBar.getTextField().clear(); userList.getItems().clear(); });
 | 
			
		||||
		eventBus.register(UserSearchResult.class,
 | 
			
		||||
				response -> Platform.runLater(() -> { userList.getItems().clear(); userList.getItems().addAll(response.get()); }));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,8 @@ import envoy.client.data.LocalDB;
 | 
			
		||||
import envoy.client.event.SendEvent;
 | 
			
		||||
import envoy.client.ui.ClearableTextField;
 | 
			
		||||
import envoy.client.ui.SceneContext;
 | 
			
		||||
import envoy.client.ui.listcell.ContactListCellFactory;
 | 
			
		||||
import envoy.client.ui.listcell.ContactControl;
 | 
			
		||||
import envoy.client.ui.listcell.ListCellFactory;
 | 
			
		||||
import envoy.data.User;
 | 
			
		||||
import envoy.event.EventBus;
 | 
			
		||||
import envoy.event.GroupCreation;
 | 
			
		||||
@@ -53,7 +54,7 @@ public class GroupCreationScene {
 | 
			
		||||
 | 
			
		||||
	@FXML
 | 
			
		||||
	private void initialize() {
 | 
			
		||||
		userList.setCellFactory(new ContactListCellFactory<>());
 | 
			
		||||
		userList.setCellFactory(new ListCellFactory<>(ContactControl::new));
 | 
			
		||||
		userList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
 | 
			
		||||
		groupNameField.setClearButtonListener(e -> { groupNameField.getTextField().clear(); createButton.setDisable(true); });
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,44 +0,0 @@
 | 
			
		||||
package envoy.client.ui.listcell;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.control.ListCell;
 | 
			
		||||
import javafx.scene.control.ListView;
 | 
			
		||||
 | 
			
		||||
import envoy.client.data.Chat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>ChatListCellFactory.java</strong><br>
 | 
			
		||||
 * Created: <strong>28.03.2020</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy Client v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public class ChatListCellFactory extends ListCell<Chat> {
 | 
			
		||||
 | 
			
		||||
	private final ListView<Chat> listView;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param listView the list view inside which this cell is contained
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public ChatListCellFactory(ListView<Chat> listView) { this.listView = listView; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Displays the name of a contact. If the contact is a user, their online status
 | 
			
		||||
	 * is displayed as well.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void updateItem(Chat chat, boolean empty) {
 | 
			
		||||
		super.updateItem(chat, empty);
 | 
			
		||||
		if (empty || chat.getRecipient() == null) {
 | 
			
		||||
			setText(null);
 | 
			
		||||
			setGraphic(null);
 | 
			
		||||
		} else {
 | 
			
		||||
			final var control = new ChatControl(chat);
 | 
			
		||||
			prefWidthProperty().bind(listView.widthProperty().subtract(40));
 | 
			
		||||
			setGraphic(control);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
package envoy.client.ui.listcell;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.control.ListCell;
 | 
			
		||||
import javafx.scene.control.ListView;
 | 
			
		||||
import javafx.util.Callback;
 | 
			
		||||
 | 
			
		||||
import envoy.data.Contact;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>ContactListCellFactory.java</strong><br>
 | 
			
		||||
 * Created: <strong>13.07.2020</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @param <T> the type of contact to display
 | 
			
		||||
 * @since Envoy Client v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public class ContactListCellFactory<T extends Contact> implements Callback<ListView<T>, ListCell<T>> {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Wraps a the {@link ContactControl} inside a list cell.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param <T> the type of contact to display
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public static final class ContactListCell<T extends Contact> extends ListCell<T> {
 | 
			
		||||
 | 
			
		||||
		private final ListView<T> listView;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @param listView the list view containing this list cell
 | 
			
		||||
		 * @since Envoy Client v0.1-beta
 | 
			
		||||
		 */
 | 
			
		||||
		public ContactListCell(ListView<T> listView) { this.listView = listView; }
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void updateItem(T contact, boolean empty) {
 | 
			
		||||
			super.updateItem(contact, empty);
 | 
			
		||||
			if (empty || contact == null) {
 | 
			
		||||
				setText(null);
 | 
			
		||||
				setGraphic(null);
 | 
			
		||||
			} else {
 | 
			
		||||
				final var control = new ContactControl(contact);
 | 
			
		||||
				prefWidthProperty().bind(listView.widthProperty().subtract(40));
 | 
			
		||||
				setGraphic(control);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public ListCell<T> call(ListView<T> listView) { return new ContactListCell<>(listView); }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
package envoy.client.ui.listcell;
 | 
			
		||||
 | 
			
		||||
import java.util.function.Function;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.Node;
 | 
			
		||||
import javafx.scene.control.ListCell;
 | 
			
		||||
import javafx.scene.control.ListView;
 | 
			
		||||
import javafx.util.Callback;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides a creation mechanism for generic list cells given a list view and a
 | 
			
		||||
 * conversion function.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>ListCellFactory.java</strong><br>
 | 
			
		||||
 * Created: <strong>13.07.2020</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @param <T> the type of object to display
 | 
			
		||||
 * @since Envoy Client v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public final class ListCellFactory<T> implements Callback<ListView<T>, ListCell<T>> {
 | 
			
		||||
 | 
			
		||||
	private final class GenericListCell extends ListCell<T> {
 | 
			
		||||
 | 
			
		||||
		private ListView<? extends T> listView;
 | 
			
		||||
 | 
			
		||||
		private GenericListCell(ListView<? extends T> listView) { this.listView = listView; }
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		protected void updateItem(T item, boolean empty) {
 | 
			
		||||
			super.updateItem(item, empty);
 | 
			
		||||
			if (empty || item == null) {
 | 
			
		||||
				setText(null);
 | 
			
		||||
				setGraphic(null);
 | 
			
		||||
			} else {
 | 
			
		||||
				final var control = converter.apply(item);
 | 
			
		||||
				prefWidthProperty().bind(listView.widthProperty().subtract(40));
 | 
			
		||||
				setGraphic(control);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private final Function<? super T, ? extends Node> converter;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param converter a function converting the type to display into a node
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public ListCellFactory(Function<? super T, ? extends Node> converter) { this.converter = converter; }
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public ListCell<T> call(ListView<T> listView) { return new GenericListCell(listView); }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
package envoy.client.ui.listcell;
 | 
			
		||||
 | 
			
		||||
import javafx.scene.control.ListCell;
 | 
			
		||||
import javafx.scene.control.ListView;
 | 
			
		||||
import javafx.scene.control.Tooltip;
 | 
			
		||||
import javafx.stage.PopupWindow.AnchorLocation;
 | 
			
		||||
 | 
			
		||||
import envoy.data.Message;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Displays a single message inside the message list.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Project: <strong>envoy-client</strong><br>
 | 
			
		||||
 * File: <strong>MessageListCellFactory.java</strong><br>
 | 
			
		||||
 * Created: <strong>28.03.2020</strong><br>
 | 
			
		||||
 *
 | 
			
		||||
 * @author Kai S. K. Engelbart
 | 
			
		||||
 * @since Envoy Client v0.1-beta
 | 
			
		||||
 */
 | 
			
		||||
public class MessageListCellFactory extends ListCell<Message> {
 | 
			
		||||
 | 
			
		||||
	private final ListView<Message> listView;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param listView the list view inside which this cell is contained
 | 
			
		||||
	 * @since Envoy Client v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	public MessageListCellFactory(ListView<Message> listView) { this.listView = listView; }
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Displays the text, the data of creation and the status of a message.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @since Envoy v0.1-beta
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void updateItem(Message message, boolean empty) {
 | 
			
		||||
		super.updateItem(message, empty);
 | 
			
		||||
		if (empty || message == null) {
 | 
			
		||||
			setText(null);
 | 
			
		||||
			setGraphic(null);
 | 
			
		||||
		} else {
 | 
			
		||||
			final var control = new MessageControl(message);
 | 
			
		||||
			control.prefWidthProperty().bind(listView.widthProperty().subtract(40));
 | 
			
		||||
			// Creating the Tooltip to deselect a message
 | 
			
		||||
			final var tooltip = new Tooltip("You can select a message by clicking on it \nand deselect it by pressing \"ctrl\" and clicking on it");
 | 
			
		||||
			tooltip.setWrapText(true);
 | 
			
		||||
			tooltip.setAnchorLocation(AnchorLocation.WINDOW_TOP_LEFT);
 | 
			
		||||
			setTooltip(tooltip);
 | 
			
		||||
			setGraphic(control);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user