(IMPORTANT! read description) Merge pull request #166 from informatik-ag-ngl/f/clearable_textfield
Implemented ClearableTextField and redesigned UI. TAKE CARE: in order to use SceneBuilder further, you have to import the attached JAR "CustomComponents.jar" into the SceneBuilder. If you don't do this, Scenebuilder no longer can load FXML files that depend on a custom component. If you are implementing another custom component, feel free to add it to the jar. Note however that SceneBuilder cannot load any components that rely on libraries other than the standard Java library or the JavaFX standard. Meaning that even if you are referencing another Envoy file, the component will not be importable. Because of this, the ClearableTextField is also present only in a slimmed down version, as SceneBuilder additionally has problems when dealing with loading resources.
This commit is contained in:
commit
4f877d3d5b
174
src/main/java/envoy/client/ui/ClearableTextField.java
Normal file
174
src/main/java/envoy/client/ui/ClearableTextField.java
Normal file
@ -0,0 +1,174 @@
|
||||
package envoy.client.ui;
|
||||
|
||||
import javafx.beans.property.BooleanProperty;
|
||||
import javafx.beans.property.ObjectProperty;
|
||||
import javafx.beans.property.StringProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.Background;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
import envoy.client.data.Settings;
|
||||
|
||||
/**
|
||||
* This class offers a text field that is automatically equipped with a clear
|
||||
* button.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>ClearableTextField.java</strong><br>
|
||||
* Created: <strong>25.06.2020</strong><br>
|
||||
*
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class ClearableTextField extends GridPane {
|
||||
|
||||
private final TextField textField;
|
||||
|
||||
private final Button clearButton;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClearableTextField} with no initial text and icon
|
||||
* size 16.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public ClearableTextField() { this("", 16); }
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ClearableTextField} with initial text and a
|
||||
* predetermined icon size.
|
||||
*
|
||||
* @param text the text that should be displayed by default
|
||||
* @param size the size of the icon
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public ClearableTextField(String text, int size) {
|
||||
// initializing the textField and the button
|
||||
textField = new TextField(text);
|
||||
clearButton = new Button("",
|
||||
new ImageView(IconUtil.load(
|
||||
Settings.getInstance().getCurrentTheme().equals("dark") ? "/icons/clear_button_white.png" : "/icons/clear_button_black.png",
|
||||
size)));
|
||||
clearButton.setOnAction(e -> textField.clear());
|
||||
clearButton.setFocusTraversable(false);
|
||||
clearButton.getStyleClass().clear();
|
||||
clearButton.setBackground(Background.EMPTY);
|
||||
// Adding the two elements to the GridPane
|
||||
add(textField, 0, 0, 2, 1);
|
||||
add(clearButton, 1, 0, 1, 1);
|
||||
// Setting the percent - widths of the two columns.
|
||||
// Used to locate the button on the right.
|
||||
final var columnConstraints = new ColumnConstraints();
|
||||
columnConstraints.setPercentWidth(90);
|
||||
getColumnConstraints().add(columnConstraints);
|
||||
final var columnConstraints2 = new ColumnConstraints();
|
||||
columnConstraints2.setPercentWidth(10);
|
||||
getColumnConstraints().add(columnConstraints2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the underlying {@code textField}
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public TextField getTextField() { return textField; }
|
||||
|
||||
/**
|
||||
* This method offers the freedom to perform custom actions when the
|
||||
* {@code clearButton} has been pressed.
|
||||
* <p>
|
||||
* The default is
|
||||
* <b><code> e -> {clearableTextField.getTextField().clear();}</code></b>
|
||||
*
|
||||
* @param onClearButtonAction the action that should be performed
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public void setClearButtonListener(EventHandler<ActionEvent> onClearButtonAction) { clearButton.setOnAction(onClearButtonAction); }
|
||||
|
||||
/**
|
||||
* @return the current property of the prompt text
|
||||
* @see javafx.scene.control.TextInputControl#promptTextProperty()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final StringProperty promptTextProperty() { return textField.promptTextProperty(); }
|
||||
|
||||
/**
|
||||
* @return the current prompt text
|
||||
* @see javafx.scene.control.TextInputControl#getPromptText()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final String getPromptText() { return textField.getPromptText(); }
|
||||
|
||||
/**
|
||||
* @param value the prompt text to display
|
||||
* @see javafx.scene.control.TextInputControl#setPromptText(java.lang.String)
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final void setPromptText(String value) { textField.setPromptText(value); }
|
||||
|
||||
/**
|
||||
* @return the current property of the tooltip
|
||||
* @see javafx.scene.control.Control#tooltipProperty()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final ObjectProperty<Tooltip> tooltipProperty() { return textField.tooltipProperty(); }
|
||||
|
||||
/**
|
||||
* @param value the new tooltip
|
||||
* @see javafx.scene.control.Control#setTooltip(javafx.scene.control.Tooltip)
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final void setTooltip(Tooltip value) { textField.setTooltip(value); }
|
||||
|
||||
/**
|
||||
* @return the current tooltip
|
||||
* @see javafx.scene.control.Control#getTooltip()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final Tooltip getTooltip() { return textField.getTooltip(); }
|
||||
|
||||
/**
|
||||
* @return the current property of the context menu
|
||||
* @see javafx.scene.control.Control#contextMenuProperty()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final ObjectProperty<ContextMenu> contextMenuProperty() { return textField.contextMenuProperty(); }
|
||||
|
||||
/**
|
||||
* @param value the new context menu
|
||||
* @see javafx.scene.control.Control#setContextMenu(javafx.scene.control.ContextMenu)
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final void setContextMenu(ContextMenu value) { textField.setContextMenu(value); }
|
||||
|
||||
/**
|
||||
* @return the current context menu
|
||||
* @see javafx.scene.control.Control#getContextMenu()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final ContextMenu getContextMenu() { return textField.getContextMenu(); }
|
||||
|
||||
/**
|
||||
* @param value whether this ClearableTextField should be editable
|
||||
* @see javafx.scene.control.TextInputControl#setEditable(boolean)
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final void setEditable(boolean value) { textField.setEditable(value); }
|
||||
|
||||
/**
|
||||
* @return the current property whether this ClearableTextField is editable
|
||||
* @see javafx.scene.control.TextInputControl#editableProperty()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final BooleanProperty editableProperty() { return textField.editableProperty(); }
|
||||
|
||||
/**
|
||||
* @return whether this {@code ClearableTextField} is editable
|
||||
* @see javafx.scene.control.TextInputControl#isEditable()
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public final boolean isEditable() { return textField.isEditable(); }
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package envoy.client.ui;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.stage.PopupWindow.AnchorLocation;
|
||||
|
||||
import envoy.data.Message;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.data.User;
|
||||
|
||||
/**
|
||||
* Displays a single message inside the message list.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>MessageListCell.java</strong><br>
|
||||
* Created: <strong>28.03.2020</strong><br>
|
||||
*
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class MessageListCell extends ListCell<Message> {
|
||||
|
||||
private final ListView<Message> listView;
|
||||
|
||||
private static User client;
|
||||
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
|
||||
private static final Map<MessageStatus, Image> statusImages = IconUtil.loadByEnum(MessageStatus.class, 16);
|
||||
|
||||
/**
|
||||
* @param listView the list view inside which this cell is contained
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public MessageListCell(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 {
|
||||
// Creating the underlying VBox, the dateLabel and the textLabel
|
||||
final var cell = new VBox(new Label(dateFormat.format(message.getCreationDate())));
|
||||
final var textLabel = new Label(message.getText());
|
||||
textLabel.setWrapText(true);
|
||||
cell.getChildren().add(textLabel);
|
||||
// Setting the message status icon and background color
|
||||
if (message.getRecipientID() != client.getID()) {
|
||||
final var statusIcon = new Label("", new ImageView(statusImages.get(message.getStatus())));
|
||||
statusIcon.setPadding(new Insets(1, 0, 5, 5));
|
||||
cell.getChildren().add(statusIcon);
|
||||
cell.getStyleClass().add("own-message");
|
||||
} else cell.getStyleClass().add("received-message");
|
||||
// Adjusting height and weight of the cell to the corresponding ListView
|
||||
cell.paddingProperty().setValue(new Insets(5, 20, 5, 20));
|
||||
cell.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(cell);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client the user who chats with another person
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public static void setUser(User client) { MessageListCell.client = client; }
|
||||
}
|
@ -40,21 +40,21 @@ public final class SceneContext {
|
||||
public enum SceneInfo {
|
||||
|
||||
/**
|
||||
* The main scene in which chats are displayed.
|
||||
* The main scene in which the chat screen is displayed.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
CHAT_SCENE("/fxml/ChatScene.fxml"),
|
||||
|
||||
/**
|
||||
* The scene in which settings are displayed.
|
||||
* The scene in which the settings screen is displayed.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
SETTINGS_SCENE("/fxml/SettingsScene.fxml"),
|
||||
|
||||
/**
|
||||
* The scene in which the contact search is displayed.
|
||||
* The scene in which the contact search screen is displayed.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
@ -72,7 +72,14 @@ public final class SceneContext {
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
LOGIN_SCENE("/fxml/LoginScene.fxml");
|
||||
LOGIN_SCENE("/fxml/LoginScene.fxml"),
|
||||
|
||||
/**
|
||||
* The scene in which the info screen is displayed.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
MESSAGE_INFO_SCENE("/fxml/MessageInfoScene.fxml");
|
||||
|
||||
/**
|
||||
* The path to the FXML resource.
|
||||
|
@ -16,7 +16,6 @@ import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
|
||||
import envoy.client.data.Chat;
|
||||
import envoy.client.data.LocalDB;
|
||||
@ -24,7 +23,11 @@ import envoy.client.data.Settings;
|
||||
import envoy.client.event.MessageCreationEvent;
|
||||
import envoy.client.net.Client;
|
||||
import envoy.client.net.WriteProxy;
|
||||
import envoy.client.ui.*;
|
||||
import envoy.client.ui.IconUtil;
|
||||
import envoy.client.ui.SceneContext;
|
||||
import envoy.client.ui.listcell.ContactListCellFactory;
|
||||
import envoy.client.ui.listcell.MessageControl;
|
||||
import envoy.client.ui.listcell.MessageListCellFactory;
|
||||
import envoy.data.*;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.MessageStatusChange;
|
||||
@ -92,8 +95,8 @@ public final class ChatScene {
|
||||
private void initialize() {
|
||||
|
||||
// Initialize message and user rendering
|
||||
messageList.setCellFactory(MessageListCell::new);
|
||||
userList.setCellFactory(ContactListCell::new);
|
||||
messageList.setCellFactory(MessageListCellFactory::new);
|
||||
userList.setCellFactory(ContactListCellFactory::new);
|
||||
|
||||
settingsButton.setGraphic(new ImageView(IconUtil.load("/icons/settings.png", 16)));
|
||||
|
||||
@ -166,8 +169,8 @@ public final class ChatScene {
|
||||
|
||||
userList.setItems(FXCollections.observableList(localDB.getChats().stream().map(Chat::getRecipient).collect(Collectors.toList())));
|
||||
contactLabel.setText(localDB.getUser().getName());
|
||||
MessageListCell.setUser(localDB.getUser());
|
||||
if (!client.isOnline()) updateInfoLabel("You are offline", Color.YELLOW);
|
||||
MessageControl.setUser(localDB.getUser());
|
||||
if (!client.isOnline()) updateInfoLabel("You are offline", "infoLabel-info");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,7 +182,6 @@ public final class ChatScene {
|
||||
private void userListClicked() {
|
||||
final Contact user = userList.getSelectionModel().getSelectedItem();
|
||||
if (user != null && (currentChat == null || !user.equals(currentChat.getRecipient()))) {
|
||||
logger.log(Level.FINEST, "Loading chat with " + user);
|
||||
|
||||
// LEON: JFC <===> JAVA FRIED CHICKEN <=/=> Java Foundation Classes
|
||||
|
||||
@ -187,6 +189,9 @@ public final class ChatScene {
|
||||
currentChat = localDB.getChat(user.getID()).get();
|
||||
|
||||
messageList.setItems(FXCollections.observableList(currentChat.getMessages()));
|
||||
final var scrollIndex = messageList.getItems().size() - 1;
|
||||
messageList.scrollTo(scrollIndex);
|
||||
logger.log(Level.FINEST, "Loading chat with " + user + " at index " + scrollIndex);
|
||||
deleteContactMenuItem.setText("Delete " + user.getName());
|
||||
|
||||
// Read the current chat
|
||||
@ -257,7 +262,7 @@ public final class ChatScene {
|
||||
if (!infoLabel.getText().equals(noMoreMessaging))
|
||||
// Informing the user that he is a f*cking moron and should use Envoy online
|
||||
// because he ran out of messageIDs to use
|
||||
updateInfoLabel(noMoreMessaging, Color.RED);
|
||||
updateInfoLabel(noMoreMessaging, "infoLabel-error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,7 +307,7 @@ public final class ChatScene {
|
||||
postButton.setDisable(true);
|
||||
messageTextArea.setDisable(true);
|
||||
messageTextArea.clear();
|
||||
updateInfoLabel("You need to go online to send more messages", Color.RED);
|
||||
updateInfoLabel("You need to go online to send more messages", "infoLabel-error");
|
||||
return;
|
||||
}
|
||||
final var text = messageTextArea.getText().strip();
|
||||
@ -346,12 +351,13 @@ public final class ChatScene {
|
||||
* Updates the {@code infoLabel}.
|
||||
*
|
||||
* @param text the text to use
|
||||
* @param textfill the color in which to display information
|
||||
* @param infoLabelID the id the the {@code infoLabel} should have so that it
|
||||
* can be styled accordingly in CSS
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
private void updateInfoLabel(String text, Paint textfill) {
|
||||
private void updateInfoLabel(String text, String infoLabelID) {
|
||||
infoLabel.setText(text);
|
||||
infoLabel.setTextFill(textfill);
|
||||
infoLabel.setId(infoLabelID);
|
||||
infoLabel.setVisible(true);
|
||||
}
|
||||
|
||||
@ -387,4 +393,7 @@ public final class ChatScene {
|
||||
updateRemainingCharsLabel();
|
||||
postButton.setDisable(messageText.isBlank());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void loadMessageInfoScene() { try {} catch (final NullPointerException e) {} }
|
||||
}
|
||||
|
@ -5,13 +5,16 @@ import java.util.logging.Logger;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.ListView;
|
||||
|
||||
import envoy.client.data.LocalDB;
|
||||
import envoy.client.event.SendEvent;
|
||||
import envoy.client.ui.ContactListCell;
|
||||
import envoy.client.ui.ClearableTextField;
|
||||
import envoy.client.ui.SceneContext;
|
||||
import envoy.client.ui.listcell.ContactListCellFactory;
|
||||
import envoy.data.Contact;
|
||||
import envoy.event.ElementOperation;
|
||||
import envoy.event.EventBus;
|
||||
@ -31,19 +34,7 @@ import envoy.util.EnvoyLog;
|
||||
public class ContactSearchScene {
|
||||
|
||||
@FXML
|
||||
private Button backButton;
|
||||
|
||||
@FXML
|
||||
private Button clearButton;
|
||||
|
||||
@FXML
|
||||
private Button searchButton;
|
||||
|
||||
@FXML
|
||||
private Button newGroupButton;
|
||||
|
||||
@FXML
|
||||
private TextField searchBar;
|
||||
private ClearableTextField searchBar;
|
||||
|
||||
@FXML
|
||||
private ListView<Contact> contactList;
|
||||
@ -67,7 +58,8 @@ public class ContactSearchScene {
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
contactList.setCellFactory(ContactListCell::new);
|
||||
contactList.setCellFactory(ContactListCellFactory::new);
|
||||
searchBar.setClearButtonListener(e -> { searchBar.getTextField().clear(); contactList.getItems().clear(); });
|
||||
eventBus.register(ContactSearchResult.class,
|
||||
response -> Platform.runLater(() -> { contactList.getItems().clear(); contactList.getItems().addAll(response.get()); }));
|
||||
}
|
||||
@ -78,20 +70,12 @@ public class ContactSearchScene {
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
@FXML
|
||||
private void checkClearButton() {
|
||||
final var containsContent = searchBar.getText().strip().isEmpty();
|
||||
clearButton.setDisable(containsContent);
|
||||
searchButton.setDisable(containsContent);
|
||||
private void sendRequest() {
|
||||
final var text = searchBar.getTextField().getText().strip();
|
||||
if (!text.isBlank()) eventBus.dispatch(new SendEvent(new ContactSearchRequest(text)));
|
||||
else contactList.getItems().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a {@link ContactSearchRequest} to the server.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
@FXML
|
||||
private void suggestContacts() { eventBus.dispatch(new SendEvent(new ContactSearchRequest(searchBar.getText()))); }
|
||||
|
||||
/**
|
||||
* Clears the text in the search bar and the items shown in the list.
|
||||
* Additionally disables both clear and search button.
|
||||
@ -100,10 +84,8 @@ public class ContactSearchScene {
|
||||
*/
|
||||
@FXML
|
||||
private void clear() {
|
||||
searchBar.setText(null);
|
||||
searchBar.getTextField().setText(null);
|
||||
contactList.getItems().clear();
|
||||
clearButton.setDisable(true);
|
||||
searchButton.setDisable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,8 +9,9 @@ import javafx.scene.control.Alert.AlertType;
|
||||
|
||||
import envoy.client.data.LocalDB;
|
||||
import envoy.client.event.SendEvent;
|
||||
import envoy.client.ui.ContactListCell;
|
||||
import envoy.client.ui.ClearableTextField;
|
||||
import envoy.client.ui.SceneContext;
|
||||
import envoy.client.ui.listcell.ContactListCellFactory;
|
||||
import envoy.data.Contact;
|
||||
import envoy.event.EventBus;
|
||||
import envoy.event.GroupCreation;
|
||||
@ -30,7 +31,7 @@ public class GroupCreationScene {
|
||||
private Button createButton;
|
||||
|
||||
@FXML
|
||||
private TextField groupNameField;
|
||||
private ClearableTextField groupNameField;
|
||||
|
||||
@FXML
|
||||
private ListView<Contact> contactList;
|
||||
@ -41,8 +42,9 @@ public class GroupCreationScene {
|
||||
|
||||
@FXML
|
||||
private void initialize() {
|
||||
contactList.setCellFactory(ContactListCell::new);
|
||||
contactList.setCellFactory(ContactListCellFactory::new);
|
||||
contactList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
groupNameField.setClearButtonListener(e -> { groupNameField.getTextField().clear(); createButton.setDisable(true); });
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +65,18 @@ public class GroupCreationScene {
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
@FXML
|
||||
private void contactListClicked() { createButton.setDisable(contactList.getSelectionModel().isEmpty()); }
|
||||
private void contactListClicked() {
|
||||
createButton.setDisable(contactList.getSelectionModel().isEmpty() || groupNameField.getTextField().getText().isBlank());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, whether the {@code createButton} can be enabled because text is
|
||||
* present in the textfield.
|
||||
*
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
@FXML
|
||||
private void textUpdated() { createButton.setDisable(groupNameField.getTextField().getText().isBlank()); }
|
||||
|
||||
/**
|
||||
* Sends a {@link GroupCreation} to the server and closes this scene.
|
||||
@ -74,10 +87,10 @@ public class GroupCreationScene {
|
||||
*/
|
||||
@FXML
|
||||
private void createButtonClicked() {
|
||||
final var name = groupNameField.getText();
|
||||
final var name = groupNameField.getTextField().getText();
|
||||
if (!Bounds.isValidContactName(name)) {
|
||||
new Alert(AlertType.ERROR, "The entered group name is not valid (" + Bounds.CONTACT_NAME_PATTERN + ")").showAndWait();
|
||||
groupNameField.clear();
|
||||
groupNameField.getTextField().clear();
|
||||
} else {
|
||||
eventBus.dispatch(new SendEvent(new GroupCreation(name,
|
||||
contactList.getSelectionModel().getSelectedItems().stream().map(Contact::getID).collect(Collectors.toSet()))));
|
||||
|
@ -13,6 +13,7 @@ import javafx.scene.control.Alert.AlertType;
|
||||
|
||||
import envoy.client.data.*;
|
||||
import envoy.client.net.Client;
|
||||
import envoy.client.ui.ClearableTextField;
|
||||
import envoy.client.ui.SceneContext;
|
||||
import envoy.client.ui.Startup;
|
||||
import envoy.data.LoginCredentials;
|
||||
@ -38,7 +39,7 @@ import envoy.util.EnvoyLog;
|
||||
public final class LoginScene {
|
||||
|
||||
@FXML
|
||||
private TextField userTextField;
|
||||
private ClearableTextField userTextField;
|
||||
|
||||
@FXML
|
||||
private PasswordField passwordField;
|
||||
@ -116,17 +117,17 @@ public final class LoginScene {
|
||||
if (registerCheckBox.isSelected() && !passwordField.getText().equals(repeatPasswordField.getText())) {
|
||||
new Alert(AlertType.ERROR, "The entered password is unequal to the repeated one").showAndWait();
|
||||
repeatPasswordField.clear();
|
||||
} else if (!Bounds.isValidContactName(userTextField.getText())) {
|
||||
} else if (!Bounds.isValidContactName(userTextField.getTextField().getText())) {
|
||||
new Alert(AlertType.ERROR, "The entered user name is not valid (" + Bounds.CONTACT_NAME_PATTERN + ")").showAndWait();
|
||||
userTextField.clear();
|
||||
} else
|
||||
performHandshake(
|
||||
new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(), registerCheckBox.isSelected(), Startup.VERSION));
|
||||
userTextField.getTextField().clear();
|
||||
} else performHandshake(new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText().toCharArray(),
|
||||
registerCheckBox.isSelected(), Startup.VERSION));
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void offlineModeButtonPressed() {
|
||||
attemptOfflineMode(new LoginCredentials(userTextField.getText(), passwordField.getText().toCharArray(), false, Startup.VERSION));
|
||||
attemptOfflineMode(
|
||||
new LoginCredentials(userTextField.getTextField().getText(), passwordField.getText().toCharArray(), false, Startup.VERSION));
|
||||
}
|
||||
|
||||
@FXML
|
||||
|
40
src/main/java/envoy/client/ui/listcell/ContactControl.java
Normal file
40
src/main/java/envoy/client/ui/listcell/ContactControl.java
Normal file
@ -0,0 +1,40 @@
|
||||
package envoy.client.ui.listcell;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import envoy.data.Contact;
|
||||
import envoy.data.Group;
|
||||
import envoy.data.User;
|
||||
|
||||
/**
|
||||
* This class formats a single {@link Contact} into a UI component.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>ContactControl.java</strong><br>
|
||||
* Created: <strong>01.07.2020</strong><br>
|
||||
*
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class ContactControl extends VBox {
|
||||
|
||||
/**
|
||||
* @param contact the contact that should be formatted
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public ContactControl(Contact contact) {
|
||||
// Container with contact name
|
||||
final var nameLabel = new Label(contact.getName());
|
||||
nameLabel.setWrapText(true);
|
||||
getChildren().add(nameLabel);
|
||||
if (contact instanceof User) {
|
||||
// Online status
|
||||
final var user = (User) contact;
|
||||
final var statusLabel = new Label(user.getStatus().toString());
|
||||
statusLabel.getStyleClass().add(user.getStatus().toString().toLowerCase());
|
||||
getChildren().add(statusLabel);
|
||||
} else // Member count
|
||||
getChildren().add(new Label(((Group) contact).getContacts().size() + " members"));
|
||||
}
|
||||
}
|
@ -1,13 +1,9 @@
|
||||
package envoy.client.ui;
|
||||
package envoy.client.ui.listcell;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import envoy.data.Contact;
|
||||
import envoy.data.Group;
|
||||
import envoy.data.User;
|
||||
|
||||
/**
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
@ -17,7 +13,7 @@ import envoy.data.User;
|
||||
* @author Kai S. K. Engelbart
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class ContactListCell extends ListCell<Contact> {
|
||||
public class ContactListCellFactory extends ListCell<Contact> {
|
||||
|
||||
private final ListView<Contact> listView;
|
||||
|
||||
@ -25,7 +21,7 @@ public class ContactListCell extends ListCell<Contact> {
|
||||
* @param listView the list view inside which this cell is contained
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public ContactListCell(ListView<Contact> listView) { this.listView = listView; }
|
||||
public ContactListCellFactory(ListView<Contact> listView) { this.listView = listView; }
|
||||
|
||||
/**
|
||||
* Displays the name of a contact. If the contact is a user, their online status
|
||||
@ -40,20 +36,9 @@ public class ContactListCell extends ListCell<Contact> {
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
} else {
|
||||
// Container with contact name
|
||||
final var nameLabel = new Label(contact.getName());
|
||||
nameLabel.setWrapText(true);
|
||||
final var vbox = new VBox(nameLabel);
|
||||
if (contact instanceof User) {
|
||||
// Online status
|
||||
final var user = (User) contact;
|
||||
final var statusLabel = new Label(user.getStatus().toString());
|
||||
statusLabel.getStyleClass().add(user.getStatus().toString().toLowerCase());
|
||||
vbox.getChildren().add(statusLabel);
|
||||
} else // Member count
|
||||
vbox.getChildren().add(new Label(((Group) contact).getContacts().size() + " members"));
|
||||
final var control = new ContactControl(contact);
|
||||
prefWidthProperty().bind(listView.widthProperty().subtract(40));
|
||||
setGraphic(vbox);
|
||||
setGraphic(control);
|
||||
}
|
||||
}
|
||||
}
|
60
src/main/java/envoy/client/ui/listcell/MessageControl.java
Normal file
60
src/main/java/envoy/client/ui/listcell/MessageControl.java
Normal file
@ -0,0 +1,60 @@
|
||||
package envoy.client.ui.listcell;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import envoy.client.ui.IconUtil;
|
||||
import envoy.data.Message;
|
||||
import envoy.data.Message.MessageStatus;
|
||||
import envoy.data.User;
|
||||
|
||||
/**
|
||||
* This class formats a single {@link Message} into a UI component.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>MessageControl.java</strong><br>
|
||||
* Created: <strong>01.07.2020</strong><br>
|
||||
*
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public class MessageControl extends VBox {
|
||||
|
||||
private static User client;
|
||||
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
|
||||
private static final Map<MessageStatus, Image> statusImages = IconUtil.loadByEnum(MessageStatus.class, 16);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param message the message that should be formatted
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public MessageControl(Message message) {
|
||||
// Creating the underlying VBox, the dateLabel and the textLabel
|
||||
super(new Label(dateFormat.format(message.getCreationDate())));
|
||||
final var textLabel = new Label(message.getText());
|
||||
textLabel.setWrapText(true);
|
||||
getChildren().add(textLabel);
|
||||
// Setting the message status icon and background color
|
||||
if (message.getRecipientID() != client.getID()) {
|
||||
final var statusIcon = new ImageView(statusImages.get(message.getStatus()));
|
||||
statusIcon.setPreserveRatio(true);
|
||||
getChildren().add(statusIcon);
|
||||
getStyleClass().add("own-message");
|
||||
} else getStyleClass().add("received-message");
|
||||
// Adjusting height and weight of the cell to the corresponding ListView
|
||||
paddingProperty().setValue(new Insets(5, 20, 5, 20));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client the user who has logged in
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
public static void setUser(User client) { MessageControl.client = client; }
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
12
src/main/java/envoy/client/ui/listcell/package-info.java
Normal file
12
src/main/java/envoy/client/ui/listcell/package-info.java
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* This package contains custom list cells that are used to display certain
|
||||
* things.
|
||||
* <p>
|
||||
* Project: <strong>envoy-client</strong><br>
|
||||
* File: <strong>package-info.java</strong><br>
|
||||
* Created: <strong>30.06.2020</strong><br>
|
||||
*
|
||||
* @author Leon Hofmeister
|
||||
* @since Envoy Client v0.1-beta
|
||||
*/
|
||||
package envoy.client.ui.listcell;
|
BIN
src/main/other/CustomComponents.jar
Normal file
BIN
src/main/other/CustomComponents.jar
Normal file
Binary file not shown.
@ -3,7 +3,7 @@
|
||||
}
|
||||
|
||||
.context-menu, .context-menu > * {
|
||||
-fx-background-radius: 15px;
|
||||
-fx-background-radius: 15.0px;
|
||||
/*TODO: solution below does not work */
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
@ -58,3 +58,19 @@
|
||||
-fx-text-fill: #00FF00;
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
|
||||
#infoLabel-success {
|
||||
-fx-text-fill: #00FF00;
|
||||
}
|
||||
|
||||
#infoLabel-info {
|
||||
-fx-text-fill: yellow;
|
||||
}
|
||||
|
||||
#infoLabel-warning {
|
||||
-fx-text-fill: orange;
|
||||
}
|
||||
|
||||
#infoLabel-error {
|
||||
-fx-text-fill: red;
|
||||
}
|
||||
|
@ -12,9 +12,9 @@
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
|
||||
<GridPane maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
<GridPane hgap="5.0" maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
minHeight="400.0" minWidth="350.0" prefHeight="400.0" prefWidth="600.0"
|
||||
xmlns="http://javafx.com/javafx/11.0.1"
|
||||
vgap="2.0" xmlns="http://javafx.com/javafx/11.0.1"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="envoy.client.ui.controller.ChatScene">
|
||||
<columnConstraints>
|
||||
@ -47,7 +47,7 @@
|
||||
prefHeight="211.0" prefWidth="300.0" GridPane.rowIndex="1"
|
||||
GridPane.rowSpan="2147483647">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="10.0" left="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -64,7 +64,7 @@
|
||||
<Label fx:id="contactLabel" prefHeight="16.0" prefWidth="250.0"
|
||||
text="Select a contact to chat with" GridPane.columnSpan="2">
|
||||
<GridPane.margin>
|
||||
<Insets left="15.0" right="5.0" top="5.0" />
|
||||
<Insets left="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -75,17 +75,18 @@
|
||||
GridPane.columnIndex="1" GridPane.columnSpan="2"
|
||||
GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="10.0" top="10.0" />
|
||||
<Insets bottom="10.0" right="10.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<ListView fx:id="messageList" prefHeight="257.0"
|
||||
prefWidth="465.0" GridPane.columnIndex="1" GridPane.columnSpan="2"
|
||||
GridPane.rowIndex="1" GridPane.rowSpan="2">
|
||||
prefWidth="465.0" GridPane.columnIndex="1"
|
||||
GridPane.columnSpan="2147483647" GridPane.rowIndex="1"
|
||||
GridPane.rowSpan="2">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="10.0" top="5.0" />
|
||||
<Insets left="5.0" right="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -101,6 +102,8 @@
|
||||
onAction="#forwardMessage" text="Forward" />
|
||||
<MenuItem mnemonicParsing="false"
|
||||
onAction="#quoteMessage" text="Quote" />
|
||||
<MenuItem mnemonicParsing="false"
|
||||
onAction="#loadMessageInfoScene" text="Info" />
|
||||
</items>
|
||||
</ContextMenu>
|
||||
</contextMenu>
|
||||
@ -111,11 +114,8 @@
|
||||
GridPane.halignment="CENTER" GridPane.rowIndex="4"
|
||||
GridPane.valignment="BOTTOM">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="10.0" />
|
||||
<Insets bottom="10.0" right="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip anchorLocation="WINDOW_TOP_LEFT" autoHide="true"
|
||||
maxWidth="350.0"
|
||||
@ -130,6 +130,9 @@
|
||||
</items>
|
||||
</ContextMenu>
|
||||
</contextMenu>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<TextArea fx:id="messageTextArea" disable="true"
|
||||
onInputMethodTextChanged="#messageTextUpdated"
|
||||
@ -137,7 +140,7 @@
|
||||
prefHeight="200.0" prefWidth="200.0" wrapText="true"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="4">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="10.0" left="5.0" top="3.0" />
|
||||
</GridPane.margin>
|
||||
<opaqueInsets>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -163,7 +166,7 @@
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="5.0" top="5.0" />
|
||||
</padding>
|
||||
<opaqueInsets>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -175,8 +178,8 @@
|
||||
</tooltip>
|
||||
</Label>
|
||||
<Label fx:id="infoLabel" text="Something happened"
|
||||
textFill="#faa007" visible="false" GridPane.columnIndex="1"
|
||||
GridPane.rowIndex="1">
|
||||
wrapText="true" textFill="#faa007" visible="false"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
|
@ -1,53 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import envoy.client.ui.ClearableTextField?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.control.Tooltip?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.ContactSearchScene">
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="envoy.client.ui.controller.ContactSearchScene">
|
||||
<children>
|
||||
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
|
||||
<children>
|
||||
<TextField fx:id="searchBar" onInputMethodTextChanged="#checkClearButton" onKeyTyped="#checkClearButton" prefColumnCount="22" promptText="Enter username to search for">
|
||||
<ClearableTextField fx:id="searchBar"
|
||||
prefWidth="310.0">
|
||||
<textField onInputMethodTextChanged="#sendRequest"
|
||||
onKeyTyped="#sendRequest" prefColumnCount="22"
|
||||
promptText="Enter username to search for">
|
||||
</textField>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="15.0" />
|
||||
</HBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Enter a name. If an account by that name exists, it will be displayed below." wrapText="true" />
|
||||
</tooltip>
|
||||
</TextField>
|
||||
<Button fx:id="clearButton" disable="true" mnemonicParsing="true" onAction="#clear" prefHeight="26.0" prefWidth="110.0" text="Clea_r">
|
||||
<tooltip>
|
||||
<Tooltip autoHide="true" text="Clears the text to the left and the elements below" wrapText="true" />
|
||||
<Tooltip
|
||||
text="Enter a name. If an account by that name exists, it will be displayed below."
|
||||
wrapText="true" />
|
||||
</tooltip>
|
||||
</ClearableTextField>
|
||||
<Button mnemonicParsing="false"
|
||||
onAction="#newGroupButtonClicked" prefHeight="26.0"
|
||||
prefWidth="139.0" text="New Group">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="10.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="searchButton" defaultButton="true" disable="true" mnemonicParsing="true" onAction="#suggestContacts" prefHeight="26.0" prefWidth="124.0" text="_Search" textOverrun="LEADING_WORD_ELLIPSIS">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" right="20.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
<tooltip>
|
||||
<Tooltip autoHide="true" text="Search for accounts with the name entered to the left" wrapText="true" />
|
||||
</tooltip>
|
||||
</Button>
|
||||
<Button mnemonicParsing="false" onAction="#newGroupButtonClicked" prefHeight="26.0" prefWidth="139.0" text="New Group">
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="20.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="5.0" left="30.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
@ -55,22 +46,28 @@
|
||||
</Button>
|
||||
</children>
|
||||
</HBox>
|
||||
<ListView fx:id="contactList" onMouseClicked="#contactListClicked" prefHeight="314.0" prefWidth="600.0">
|
||||
<ListView fx:id="contactList"
|
||||
onMouseClicked="#contactListClicked" prefHeight="314.0"
|
||||
prefWidth="600.0">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<VBox.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</VBox.margin></ListView>
|
||||
<Button fx:id="backButton" cancelButton="true" mnemonicParsing="true" onAction="#backButtonClicked" text="_Back">
|
||||
</VBox.margin>
|
||||
</ListView>
|
||||
<Button cancelButton="true" mnemonicParsing="true"
|
||||
onAction="#backButtonClicked" text="_Back">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
<Insets bottom="10.0" left="10.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip autoHide="true" text="Takes you back to the screen where you can chat with others" wrapText="true" />
|
||||
<Tooltip autoHide="true"
|
||||
text="Takes you back to the screen where you can chat with others"
|
||||
wrapText="true" />
|
||||
</tooltip>
|
||||
</Button>
|
||||
</children>
|
||||
|
@ -1,20 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import envoy.client.ui.ClearableTextField?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ListView?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.control.Tooltip?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.GroupCreationScene">
|
||||
<VBox maxHeight="-Infinity" maxWidth="-Infinity"
|
||||
minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
|
||||
prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="envoy.client.ui.controller.GroupCreationScene">
|
||||
<children>
|
||||
<HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
|
||||
<children>
|
||||
<TextField fx:id="groupNameField" prefColumnCount="22" promptText="Enter Group Name">
|
||||
<ClearableTextField fx:id="groupNameField">
|
||||
<textField prefColumnCount="22"
|
||||
promptText="Enter Group Name"
|
||||
onInputMethodTextChanged="#textUpdated" onKeyTyped="#textUpdated" />
|
||||
<HBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</HBox.margin>
|
||||
@ -22,46 +30,62 @@
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip text="Enter a name. If an account by that name exists, it will be displayed below." wrapText="true" />
|
||||
<Tooltip
|
||||
text="Enter something. A group with this name will be created."
|
||||
wrapText="true" />
|
||||
</tooltip>
|
||||
</TextField>
|
||||
</ClearableTextField>
|
||||
</children>
|
||||
</HBox>
|
||||
<Label text="Choose Members:">
|
||||
<font>
|
||||
<Font size="16.0" />
|
||||
</font>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<ListView fx:id="contactList" onMouseClicked="#contactListClicked" prefHeight="314.0" prefWidth="600.0">
|
||||
<ListView fx:id="contactList"
|
||||
onMouseClicked="#contactListClicked" prefHeight="314.0"
|
||||
prefWidth="600.0">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="10.0" right="10.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></ListView>
|
||||
<Button fx:id="createButton" defaultButton="true" disable="true" mnemonicParsing="false" onAction="#createButtonClicked" text="Create">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></Button>
|
||||
<Button cancelButton="true" mnemonicParsing="true" onAction="#backButtonClicked" text="_Back">
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</padding>
|
||||
</ListView>
|
||||
<BorderPane prefHeight="50.0">
|
||||
<left>
|
||||
<Button cancelButton="true" mnemonicParsing="true"
|
||||
onAction="#backButtonClicked" text="_Back"
|
||||
BorderPane.alignment="CENTER">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<tooltip>
|
||||
<Tooltip autoHide="true" text="Takes you back to the screen where you can chat with others" wrapText="true" />
|
||||
<Tooltip autoHide="true"
|
||||
text="Takes you back to the screen where you can chat with others"
|
||||
wrapText="true" />
|
||||
</tooltip>
|
||||
<BorderPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</BorderPane.margin>
|
||||
</Button>
|
||||
</left>
|
||||
<right>
|
||||
<Button fx:id="createButton" alignment="CENTER_RIGHT"
|
||||
defaultButton="true" disable="true" mnemonicParsing="false"
|
||||
onAction="#createButtonClicked" text="Create"
|
||||
BorderPane.alignment="CENTER">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<BorderPane.margin>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</BorderPane.margin>
|
||||
</Button>
|
||||
</right>
|
||||
</BorderPane>
|
||||
</children>
|
||||
</VBox>
|
||||
|
@ -1,19 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import envoy.client.ui.ClearableTextField?>
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.ButtonBar?>
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.PasswordField?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox prefHeight="206.0" prefWidth="440.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.LoginScene">
|
||||
<VBox prefHeight="206.0" prefWidth="440.0"
|
||||
xmlns="http://javafx.com/javafx/11.0.1"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="envoy.client.ui.controller.LoginScene">
|
||||
<children>
|
||||
<Label text="User Login">
|
||||
<font>
|
||||
@ -26,15 +29,20 @@
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<GridPane>
|
||||
<GridPane hgap="5.0" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES"
|
||||
minWidth="10.0" percentWidth="40.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES"
|
||||
minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0"
|
||||
vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<Label text="User Name:">
|
||||
@ -43,62 +51,99 @@
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
|
||||
</padding></Label>
|
||||
<Label text="Password" GridPane.rowIndex="1">
|
||||
</padding>
|
||||
</Label>
|
||||
<Label text="Password:" GridPane.rowIndex="1">
|
||||
<padding>
|
||||
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
|
||||
</padding>
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin></Label>
|
||||
<Label fx:id="repeatPasswordLabel" text="Repeat Password:" visible="false" GridPane.rowIndex="2">
|
||||
</GridPane.margin>
|
||||
</Label>
|
||||
<Label fx:id="repeatPasswordLabel" text="Repeat Password:"
|
||||
visible="false" GridPane.rowIndex="2">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
|
||||
</padding></Label>
|
||||
<TextField fx:id="userTextField" GridPane.columnIndex="1">
|
||||
</padding>
|
||||
</Label>
|
||||
<ClearableTextField fx:id="userTextField"
|
||||
GridPane.columnIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></TextField>
|
||||
<PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
</ClearableTextField>
|
||||
<PasswordField fx:id="passwordField"
|
||||
GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="5.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></PasswordField>
|
||||
<PasswordField fx:id="repeatPasswordField" visible="false" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
</padding>
|
||||
</PasswordField>
|
||||
<PasswordField fx:id="repeatPasswordField"
|
||||
visible="false" GridPane.columnIndex="1" GridPane.rowIndex="2">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></PasswordField>
|
||||
</children>
|
||||
</GridPane>
|
||||
<CheckBox fx:id="registerCheckBox" mnemonicParsing="true" onAction="#registerCheckboxChanged" prefHeight="17.0" prefWidth="181.0" text="_Register">
|
||||
<padding>
|
||||
<Insets bottom="2.0" left="2.0" right="2.0" top="2.0" />
|
||||
</padding>
|
||||
</PasswordField>
|
||||
</children>
|
||||
<VBox.margin>
|
||||
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
|
||||
</VBox.margin></CheckBox>
|
||||
<Label fx:id="connectionLabel" />
|
||||
<ButtonBar prefHeight="40.0" prefWidth="200.0">
|
||||
<buttons>
|
||||
<Button mnemonicParsing="false" onAction="#abortLogin" text="Close">
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</VBox.margin>
|
||||
</GridPane>
|
||||
<CheckBox fx:id="registerCheckBox" mnemonicParsing="true"
|
||||
onAction="#registerCheckboxChanged" prefHeight="17.0"
|
||||
prefWidth="181.0" text="_Register">
|
||||
<VBox.margin>
|
||||
<Insets left="5.0" right="3.0" />
|
||||
</VBox.margin>
|
||||
</CheckBox>
|
||||
<Label fx:id="connectionLabel">
|
||||
<VBox.margin>
|
||||
<Insets left="5.0" />
|
||||
</VBox.margin>
|
||||
</Label>
|
||||
<BorderPane prefWidth="200.0">
|
||||
<left>
|
||||
<Button cancelButton="true" mnemonicParsing="false"
|
||||
onAction="#abortLogin" text="Close" BorderPane.alignment="CENTER">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding>
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
</Button>
|
||||
<Button mnemonicParsing="false" onAction="#offlineModeButtonPressed" text="Offline mode" />
|
||||
<Button defaultButton="true" mnemonicParsing="false" onAction="#loginButtonPressed" text="Login" />
|
||||
</buttons>
|
||||
</ButtonBar>
|
||||
</left>
|
||||
<center>
|
||||
<Button mnemonicParsing="false"
|
||||
onAction="#offlineModeButtonPressed" text="Offline mode"
|
||||
BorderPane.alignment="CENTER">
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
</Button>
|
||||
</center>
|
||||
<right>
|
||||
<Button defaultButton="true" mnemonicParsing="false"
|
||||
onAction="#loginButtonPressed" text="Login"
|
||||
BorderPane.alignment="CENTER">
|
||||
<BorderPane.margin>
|
||||
<Insets />
|
||||
</BorderPane.margin>
|
||||
</Button>
|
||||
</right>
|
||||
<VBox.margin>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" />
|
||||
</VBox.margin>
|
||||
</BorderPane>
|
||||
</children>
|
||||
</VBox>
|
||||
|
@ -7,11 +7,18 @@
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
|
||||
<VBox alignment="TOP_RIGHT" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="envoy.client.ui.controller.SettingsScene">
|
||||
<VBox alignment="TOP_RIGHT" maxHeight="-Infinity"
|
||||
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
|
||||
prefHeight="400.0" prefWidth="600.0"
|
||||
xmlns="http://javafx.com/javafx/11.0.1"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="envoy.client.ui.controller.SettingsScene">
|
||||
<children>
|
||||
<HBox prefHeight="389.0" prefWidth="600.0">
|
||||
<children>
|
||||
<ListView fx:id="settingsList" onMouseClicked="#settingsListClicked" prefHeight="200.0" prefWidth="200.0">
|
||||
<ListView fx:id="settingsList"
|
||||
onMouseClicked="#settingsListClicked" prefHeight="200.0"
|
||||
prefWidth="200.0">
|
||||
<opaqueInsets>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</opaqueInsets>
|
||||
@ -20,17 +27,21 @@
|
||||
</HBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></ListView>
|
||||
<TitledPane fx:id="titledPane" collapsible="false" prefHeight="325.0" prefWidth="300.0">
|
||||
</padding>
|
||||
</ListView>
|
||||
<TitledPane fx:id="titledPane" collapsible="false"
|
||||
prefHeight="325.0" prefWidth="300.0">
|
||||
<HBox.margin>
|
||||
<Insets bottom="10.0" left="5.0" right="10.0" top="10.0" />
|
||||
</HBox.margin>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</padding></TitledPane>
|
||||
</padding>
|
||||
</TitledPane>
|
||||
</children>
|
||||
</HBox>
|
||||
<Button defaultButton="true" mnemonicParsing="true" onMouseClicked="#backButtonClicked" text="_Back">
|
||||
<Button defaultButton="true" mnemonicParsing="true"
|
||||
onMouseClicked="#backButtonClicked" text="_Back">
|
||||
<opaqueInsets>
|
||||
<Insets />
|
||||
</opaqueInsets>
|
||||
|
BIN
src/main/resources/icons/clear_button_black.png
Normal file
BIN
src/main/resources/icons/clear_button_black.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
src/main/resources/icons/clear_button_white.png
Normal file
BIN
src/main/resources/icons/clear_button_white.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
Reference in New Issue
Block a user