diff --git a/.idea/cssdialects.xml b/.idea/cssdialects.xml
new file mode 100644
index 000000000..b802b9774
--- /dev/null
+++ b/.idea/cssdialects.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ReadMe.md b/ReadMe.md
index 08e39854c..9fe6b3056 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -1,4 +1,3 @@
-
# Minosoft
Minosoft is an open source minecraft client, written from scratch in java. It aims to bring more functionality and stability.
diff --git a/data/resources/61/61406b8435362ef4ccb88df70d0abf405fddd87b.tar.gz b/data/resources/61/61406b8435362ef4ccb88df70d0abf405fddd87b.tar.gz
deleted file mode 100644
index 497480aa8..000000000
Binary files a/data/resources/61/61406b8435362ef4ccb88df70d0abf405fddd87b.tar.gz and /dev/null differ
diff --git a/data/resources/72/727af3de71ac164b5f0a3ac575d8c338dd077724.tar.gz b/data/resources/72/727af3de71ac164b5f0a3ac575d8c338dd077724.tar.gz
new file mode 100644
index 000000000..bce25cd50
Binary files /dev/null and b/data/resources/72/727af3de71ac164b5f0a3ac575d8c338dd077724.tar.gz differ
diff --git a/data/resources/79/793bcaf8cfe749f90718953675b919aaac8b9bd5.tar.gz b/data/resources/9c/9cf2f31e3aa318ce06f3896cf68ee514d75c685d.tar.gz
similarity index 51%
rename from data/resources/79/793bcaf8cfe749f90718953675b919aaac8b9bd5.tar.gz
rename to data/resources/9c/9cf2f31e3aa318ce06f3896cf68ee514d75c685d.tar.gz
index 3cd2e68b4..c9773ae53 100644
Binary files a/data/resources/79/793bcaf8cfe749f90718953675b919aaac8b9bd5.tar.gz and b/data/resources/9c/9cf2f31e3aa318ce06f3896cf68ee514d75c685d.tar.gz differ
diff --git a/doc/img/server_list.png b/doc/img/server_list.png
index 14fc952a0..eb485abe5 100644
Binary files a/doc/img/server_list.png and b/doc/img/server_list.png differ
diff --git a/pom.xml b/pom.xml
index adb07dab3..a4782cd6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -139,6 +139,11 @@
16-ea+4
pom
+
+ com.jfoenix
+ jfoenix
+ 9.0.10
+
org.apache.commons
commons-compress
diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.java b/src/main/java/de/bixilon/minosoft/Minosoft.java
index 403bb9226..5ed74665b 100644
--- a/src/main/java/de/bixilon/minosoft/Minosoft.java
+++ b/src/main/java/de/bixilon/minosoft/Minosoft.java
@@ -75,16 +75,16 @@ public final class Minosoft {
Launcher.exit();
Platform.runLater(() -> {
Dialog dialog = new Dialog<>();
+ GUITools.initializePane(dialog.getDialogPane());
// Do not translate this, translations might fail to load...
dialog.setTitle("Critical Error");
dialog.setHeaderText("An error occurred while starting Minosoft");
- TextArea text = new TextArea(exception.getClass().getCanonicalName() + ": " + exception.getLocalizedMessage());
+ TextArea text = new TextArea(exception.getClass().getCanonicalName() + ": " + exception.getMessage());
text.setEditable(false);
text.setWrapText(true);
dialog.getDialogPane().setContent(text);
Stage stage = (Stage) dialog.getDialogPane().getScene().getWindow();
- stage.getIcons().add(GUITools.logo);
stage.setAlwaysOnTop(true);
stage.toFront();
stage.setOnCloseRequest(dialogEvent -> {
diff --git a/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java b/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java
index 7503d4718..436ccb3a1 100644
--- a/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java
+++ b/src/main/java/de/bixilon/minosoft/config/StaticConfiguration.java
@@ -20,6 +20,7 @@ import java.io.File;
public class StaticConfiguration {
public static final boolean DEBUG_MODE = false; // if true, additional checks will be made to validate data, ... Decreases performance
+ public static final boolean DEBUG_SLOW_LOADING = false; // if true, many Thread.sleep will be executed and the start will be delayed (by a lot)
public static String CONFIG_FILENAME = "config.json"; // Filename of minosoft's base configuration (located in AppData/Minosoft/config)
public static boolean SKIP_MOJANG_AUTHENTICATION = false; // disables all connections to mojang
public static boolean COLORED_LOG = true; // the log should be colored with ANSI (does not affect base components)
diff --git a/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java b/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java
index cef2b5aa8..7a591ea9c 100644
--- a/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java
+++ b/src/main/java/de/bixilon/minosoft/data/assets/AssetsManager.java
@@ -111,6 +111,9 @@ public class AssetsManager {
try {
String hash = assets.get(filename);
boolean compressed = (source == AssetsSource.MOJANG);
+ if (StaticConfiguration.DEBUG_SLOW_LOADING) {
+ Thread.sleep(100L);
+ }
if (!verifyAssetHash(hash, compressed)) {
AssetsManager.downloadAsset(source, hash);
}
diff --git a/src/main/java/de/bixilon/minosoft/data/inventory/InventorySlots.java b/src/main/java/de/bixilon/minosoft/data/inventory/InventorySlots.java
index bd35556b3..4beac8d54 100644
--- a/src/main/java/de/bixilon/minosoft/data/inventory/InventorySlots.java
+++ b/src/main/java/de/bixilon/minosoft/data/inventory/InventorySlots.java
@@ -110,7 +110,11 @@ public class InventorySlots {
@Override
public int getId(int versionId) {
- return valueMap.get(versionId);
+ Integer value = valueMap.get(versionId);
+ if (value == null) {
+ return Integer.MIN_VALUE;
+ }
+ return value;
}
}
diff --git a/src/main/java/de/bixilon/minosoft/data/locale/Strings.java b/src/main/java/de/bixilon/minosoft/data/locale/Strings.java
index 743a8da54..bd370c541 100644
--- a/src/main/java/de/bixilon/minosoft/data/locale/Strings.java
+++ b/src/main/java/de/bixilon/minosoft/data/locale/Strings.java
@@ -87,5 +87,7 @@ public enum Strings {
BUTTON_LOGIN,
BUTTON_SAVE,
BUTTON_ADD,
- VERSION_AUTOMATIC
+ VERSION_AUTOMATIC,
+
+ SERVER_ADDRESS_INPUT_REQUIRED
}
diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockProperties.java b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockProperties.java
index f3c063af2..c8f078a67 100644
--- a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockProperties.java
+++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockProperties.java
@@ -191,22 +191,22 @@ public enum BlockProperties {
FIRE_AGE_LEVEL_25,
// noteblock
- NOTBLOCK_INSTRUMENT_HARP,
- NOTBLOCK_INSTRUMENT_BASEDRUM,
- NOTBLOCK_INSTRUMENT_SNARE,
- NOTBLOCK_INSTRUMENT_HAT,
- NOTBLOCK_INSTRUMENT_BASS,
- NOTBLOCK_INSTRUMENT_FLUTE,
- NOTBLOCK_INSTRUMENT_BELL,
- NOTBLOCK_INSTRUMENT_GUITAR,
- NOTBLOCK_INSTRUMENT_CHIME,
- NOTBLOCK_INSTRUMENT_XYLOPHONE,
- NOTBLOCK_INSTRUMENT_IRON_XYLOPHONE("instrument", "iron_xylophone"),
- NOTBLOCK_INSTRUMENT_COW_BELL("instrument", "cow_bell"),
- NOTBLOCK_INSTRUMENT_DIDGERIDOO,
- NOTBLOCK_INSTRUMENT_BIT,
- NOTBLOCK_INSTRUMENT_BANJO,
- NOTBLOCK_INSTRUMENT_PLING,
+ NOTEBLOCK_INSTRUMENT_HARP,
+ NOTEBLOCK_INSTRUMENT_BASEDRUM,
+ NOTEBLOCK_INSTRUMENT_SNARE,
+ NOTEBLOCK_INSTRUMENT_HAT,
+ NOTEBLOCK_INSTRUMENT_BASS,
+ NOTEBLOCK_INSTRUMENT_FLUTE,
+ NOTEBLOCK_INSTRUMENT_BELL,
+ NOTEBLOCK_INSTRUMENT_GUITAR,
+ NOTEBLOCK_INSTRUMENT_CHIME,
+ NOTEBLOCK_INSTRUMENT_XYLOPHONE,
+ NOTEBLOCK_INSTRUMENT_IRON_XYLOPHONE("instrument", "iron_xylophone"),
+ NOTEBLOCK_INSTRUMENT_COW_BELL("instrument", "cow_bell"),
+ NOTEBLOCK_INSTRUMENT_DIDGERIDOO,
+ NOTEBLOCK_INSTRUMENT_BIT,
+ NOTEBLOCK_INSTRUMENT_BANJO,
+ NOTEBLOCK_INSTRUMENT_PLING,
NOTEBLOCK_NOTE_LEVEL_0,
NOTEBLOCK_NOTE_LEVEL_1,
diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
index 4d36dad71..c11bb24d1 100644
--- a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
+++ b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
@@ -43,23 +43,23 @@ public class VersionMapping {
private final HashSet loaded = new HashSet<>();
private Version version;
private VersionMapping parentMapping;
- private HashBiMap motiveIdentifierMap;
- private HashBiMap particleIdentifierMap;
- private HashBiMap statisticIdentifierMap;
- private HashBiMap itemMap;
- private HashBiMap motiveIdMap;
- private HashBiMap mobEffectMap;
- private HashBiMap dimensionMap;
+ private final HashBiMap, EntityInformation> entityInformationMap = HashBiMap.create();
+ private final HashMap entityMetaIndexMap = new HashMap<>();
+ private final HashMap> entityMetaIndexOffsetParentMapping = new HashMap<>();
+ private final HashBiMap> entityIdClassMap = HashBiMap.create();
+ private HashBiMap motiveIdentifierMap = HashBiMap.create();
+ private HashBiMap particleIdentifierMap = HashBiMap.create();
+ private HashBiMap statisticIdentifierMap = HashBiMap.create();
private HashMap> dimensionIdentifierMap = new HashMap<>();
- private HashBiMap blockMap;
- private HashBiMap blockIdMap;
- private HashBiMap enchantmentMap;
- private HashBiMap particleIdMap;
- private HashBiMap statisticIdMap;
- private HashBiMap, EntityInformation> entityInformationMap;
- private HashMap entityMetaIndexMap;
- private HashMap> entityMetaIndexOffsetParentMapping;
- private HashBiMap> entityIdClassMap;
+ private HashBiMap itemMap = HashBiMap.create();
+ private HashBiMap motiveIdMap = HashBiMap.create();
+ private HashBiMap mobEffectMap = HashBiMap.create();
+ private HashBiMap dimensionMap = HashBiMap.create();
+ private HashBiMap blockMap = HashBiMap.create();
+ private HashBiMap blockIdMap = HashBiMap.create();
+ private HashBiMap enchantmentMap = HashBiMap.create();
+ private HashBiMap particleIdMap = HashBiMap.create();
+ private HashBiMap statisticIdMap = HashBiMap.create();
private HashMap> modelMap = new HashMap<>();
private Integer blockTextureId; // OpenGL texture id for all block texture
@@ -160,7 +160,11 @@ public class VersionMapping {
return dimensionMap.get(versionId);
}
+ @Nullable
public Block getBlockById(int versionId) {
+ if (versionId == ProtocolDefinition.NULL_BLOCK_ID) {
+ return null;
+ }
if (parentMapping != null) {
Block block = parentMapping.getBlockById(versionId);
if (block != null) {
@@ -348,16 +352,6 @@ public class VersionMapping {
dimensionMap = Versions.PRE_FLATTENING_MAPPING.dimensionMap;
break;
}
- itemMap = HashBiMap.create();
- enchantmentMap = HashBiMap.create();
- statisticIdMap = HashBiMap.create();
- statisticIdentifierMap = HashBiMap.create();
- blockIdMap = HashBiMap.create();
- motiveIdMap = HashBiMap.create();
- motiveIdentifierMap = HashBiMap.create();
- particleIdMap = HashBiMap.create();
- particleIdentifierMap = HashBiMap.create();
- mobEffectMap = HashBiMap.create();
if (data == null) {
break;
@@ -433,17 +427,11 @@ public class VersionMapping {
}
if (data == null) {
- blockMap = HashBiMap.create();
break;
}
blockMap = Blocks.load(mod, data, !version.isFlattened());
}
case ENTITIES -> {
- entityInformationMap = HashBiMap.create();
- entityMetaIndexMap = new HashMap<>();
- entityMetaIndexOffsetParentMapping = new HashMap<>();
- entityIdClassMap = HashBiMap.create();
-
if (data == null) {
break;
}
@@ -462,7 +450,6 @@ public class VersionMapping {
}
if (data == null) {
- modelMap = new HashMap<>();
break;
}
Pair, Integer> pair = BlockModelLoader.load(mod, data);
diff --git a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.java b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.java
index f0f1d9a8b..300d0eab9 100644
--- a/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.java
+++ b/src/main/java/de/bixilon/minosoft/data/text/BaseComponent.java
@@ -27,6 +27,7 @@ import java.text.StringCharacterIterator;
import java.util.ArrayList;
public class BaseComponent extends ChatComponent {
+ private final static String LEGACY_RESET_SUFFIX = String.valueOf(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) + PostChatFormattingCodes.RESET.getChar();
private final ArrayList parts = new ArrayList<>();
public BaseComponent() {
@@ -157,18 +158,25 @@ public class BaseComponent extends ChatComponent {
return PostChatFormattingCodes.RESET.getANSI() + getANSIColoredMessage();
}
+ @Override
public String getANSIColoredMessage() {
StringBuilder builder = new StringBuilder();
parts.forEach((chatPart -> builder.append(chatPart.getANSIColoredMessage())));
return builder.toString();
}
+ @Override
public String getLegacyText() {
StringBuilder builder = new StringBuilder();
parts.forEach((chatPart -> builder.append(chatPart.getLegacyText())));
- return builder.toString();
+ String string = builder.toString();
+ if (string.endsWith(LEGACY_RESET_SUFFIX)) {
+ string = string.substring(0, string.length() - LEGACY_RESET_SUFFIX.length());
+ }
+ return string;
}
+ @Override
public String getMessage() {
StringBuilder builder = new StringBuilder();
parts.forEach((chatPart -> builder.append(chatPart.getMessage())));
@@ -195,4 +203,8 @@ public class BaseComponent extends ChatComponent {
parts.add(new BaseComponent(message));
return this;
}
+
+ public boolean isEmpty() {
+ return parts.isEmpty();
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.java b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.java
index b56235c73..a9a607247 100644
--- a/src/main/java/de/bixilon/minosoft/data/text/TextComponent.java
+++ b/src/main/java/de/bixilon/minosoft/data/text/TextComponent.java
@@ -157,7 +157,9 @@ public class TextComponent extends ChatComponent {
@Override
public ObservableList getJavaFXText(ObservableList nodes) {
Text text = new Text(this.text);
- if (color != null) {
+ if (color == null) {
+ text.setFill(Color.WHITE);
+ } else {
text.setFill(Color.web(color.toString()));
}
formatting.forEach((chatFormattingCode -> {
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
index ed1d7745c..bfff0d48b 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/AccountWindow.java
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.*;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.data.locale.LocaleManager;
import de.bixilon.minosoft.data.locale.Strings;
@@ -26,11 +27,11 @@ import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
-import javafx.scene.Node;
-import javafx.scene.control.*;
+import javafx.scene.control.Label;
+import javafx.scene.control.MenuItem;
+import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
-import javafx.stage.Stage;
import javafx.stage.Window;
import java.net.URL;
@@ -45,8 +46,7 @@ public class AccountWindow implements Initializable {
public void initialize(URL url, ResourceBundle resourceBundle) {
AccountListCell.listView.setCellFactory((lv) -> AccountListCell.newInstance());
- ObservableList accounts = FXCollections.observableArrayList();
- accounts.addAll(Minosoft.getAccountList().values());
+ ObservableList accounts = FXCollections.observableArrayList(Minosoft.getAccountList().values());
AccountListCell.listView.setItems(accounts);
accountPane.setCenter(AccountListCell.listView);
@@ -55,35 +55,39 @@ public class AccountWindow implements Initializable {
@FXML
public void addAccount() {
- Dialog> dialog = new Dialog<>();
+ JFXAlert> dialog = new JFXAlert<>();
dialog.setTitle(LocaleManager.translate(Strings.LOGIN_DIALOG_TITLE));
- dialog.setHeaderText(LocaleManager.translate(Strings.LOGIN_DIALOG_HEADER));
- ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(GUITools.logo);
+ GUITools.initializePane(dialog.getDialogPane());
+ JFXDialogLayout layout = new JFXDialogLayout();
+ layout.setHeading(new Label(LocaleManager.translate(Strings.LOGIN_DIALOG_HEADER)));
- ButtonType loginButtonType = new ButtonType(LocaleManager.translate(Strings.BUTTON_LOGIN), ButtonBar.ButtonData.OK_DONE);
- dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, ButtonType.CANCEL);
+ JFXButton loginButton = new JFXButton(LocaleManager.translate(Strings.BUTTON_LOGIN));
+ layout.setActions(loginButton);
- GridPane grid = new GridPane();
+ GridPane gridPane = new GridPane();
+ gridPane.setHgap(15);
+ gridPane.setVgap(15);
- TextField email = new TextField();
- email.setPromptText(LocaleManager.translate(Strings.EMAIL));
- PasswordField password = new PasswordField();
- password.setPromptText(LocaleManager.translate(Strings.PASSWORD));
+ JFXTextField emailField = new JFXTextField();
+ emailField.setPromptText(LocaleManager.translate(Strings.EMAIL));
- grid.add(new Label(LocaleManager.translate(Strings.EMAIL) + ":"), 0, 0);
- grid.add(email, 1, 0);
- grid.add(new Label(LocaleManager.translate(Strings.PASSWORD) + ":"), 0, 1);
- grid.add(password, 1, 1);
- Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
+ JFXPasswordField passwordField = new JFXPasswordField();
+ passwordField.setPromptText(LocaleManager.translate(Strings.PASSWORD));
- email.textProperty().addListener((observable, oldValue, newValue) -> loginButton.setDisable(newValue.trim().isEmpty()));
+ gridPane.add(new Label(LocaleManager.translate(Strings.EMAIL) + ":"), 0, 0);
+ gridPane.add(emailField, 1, 0);
+ gridPane.add(new Label(LocaleManager.translate(Strings.PASSWORD) + ":"), 0, 1);
+ gridPane.add(passwordField, 1, 1);
+
+ emailField.textProperty().addListener((observable, oldValue, newValue) -> loginButton.setDisable(newValue.trim().isEmpty()));
loginButton.setDisable(true);
- dialog.getDialogPane().setContent(grid);
+ layout.setBody(gridPane);
+ dialog.setContent(layout);
- Platform.runLater(email::requestFocus);
+ Platform.runLater(emailField::requestFocus);
loginButton.addEventFilter(ActionEvent.ACTION, event -> {
- MojangAccountAuthenticationAttempt attempt = MojangAuthentication.login(email.getText(), password.getText());
+ MojangAccountAuthenticationAttempt attempt = MojangAuthentication.login(emailField.getText(), passwordField.getText());
if (attempt.succeeded()) {
// login okay
MojangAccount account = attempt.getAccount();
@@ -91,6 +95,7 @@ public class AccountWindow implements Initializable {
account.saveToConfig();
AccountListCell.listView.getItems().add(account);
Log.info(String.format("Added and saved account (playerName=%s, email=%s, uuid=%s)", account.getPlayerName(), account.getMojangUserName(), account.getUUID()));
+ dialog.close();
return;
}
event.consume();
@@ -98,14 +103,25 @@ public class AccountWindow implements Initializable {
error.setStyle("-fx-text-fill: red");
error.setText(attempt.getError());
- grid.add(new Label(LocaleManager.translate(Strings.ERROR)), 0, 2);
- grid.add(error, 1, 2);
+ gridPane.add(new Label(LocaleManager.translate(Strings.ERROR)), 0, 2);
+ gridPane.add(error, 1, 2);
// ToDo resize window
});
Window window = dialog.getDialogPane().getScene().getWindow();
window.setOnCloseRequest(windowEvent -> window.hide());
+
+ dialog.getDialogPane().setOnKeyReleased(keyEvent -> {
+ if (keyEvent.getCode() != KeyCode.ENTER) {
+ return;
+ }
+ if (emailField.getText().trim().isEmpty()) {
+ return;
+ }
+ loginButton.fire();
+ });
+
dialog.showAndWait();
}
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java b/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java
index ea34ce186..e9b7f7c0a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/GUITools.java
@@ -13,29 +13,32 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.JFXComboBox;
import de.bixilon.minosoft.data.mappings.versions.Version;
import de.bixilon.minosoft.data.mappings.versions.Versions;
import de.bixilon.minosoft.logging.LogLevels;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
-import javafx.scene.control.ComboBox;
+import javafx.scene.Scene;
import javafx.scene.image.Image;
+import javafx.scene.layout.Pane;
+import javafx.stage.Stage;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.Base64;
public class GUITools {
- public final static Image logo = new Image(GUITools.class.getResourceAsStream("/icons/windowIcon.png"));
- public final static ObservableList versions = FXCollections.observableArrayList();
- public final static ComboBox versionList = new ComboBox<>(GUITools.versions);
- public final static ObservableList logLevels = FXCollections.observableList(Arrays.asList(LogLevels.values().clone()));
+ public final static Image MINOSOFT_LOGO = new Image(GUITools.class.getResourceAsStream("/icons/windowIcon.png"));
+ public final static ObservableList VERSIONS = FXCollections.observableArrayList();
+ public final static JFXComboBox VERSION_COMBO_BOX = new JFXComboBox<>(GUITools.VERSIONS);
+ public final static ObservableList LOG_LEVELS = FXCollections.observableList(Arrays.asList(LogLevels.values().clone()));
static {
- GUITools.versions.add(Versions.LOWEST_VERSION_SUPPORTED);
- Versions.getVersionIdMap().forEach((key, value) -> GUITools.versions.add(value));
+ GUITools.VERSIONS.add(Versions.LOWEST_VERSION_SUPPORTED);
+ Versions.getVersionIdMap().forEach((key, value) -> GUITools.VERSIONS.add(value));
- GUITools.versions.sort((a, b) -> {
+ GUITools.VERSIONS.sort((a, b) -> {
if (a.getVersionId() == -1) {
return -Integer.MAX_VALUE;
}
@@ -66,4 +69,17 @@ public class GUITools {
return null;
}
}
+
+ public static Scene initializeScene(Scene scene) {
+ scene.getStylesheets().add("/layout/style.css");
+ if (scene.getWindow() instanceof Stage stage) {
+ stage.getIcons().add(GUITools.MINOSOFT_LOGO);
+ }
+ return scene;
+ }
+
+ public static Pane initializePane(Pane pane) {
+ initializeScene(pane.getScene());
+ return pane;
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java b/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
index 9d3fa1245..b0fc5c4f4 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/Launcher.java
@@ -44,10 +44,8 @@ public class Launcher {
if (exit) {
return;
}
- Stage stage = new Stage();
- stage.getIcons().add(GUITools.logo);
- GUITools.versionList.setCellFactory(new Callback<>() {
+ GUITools.VERSION_COMBO_BOX.setCellFactory(new Callback<>() {
@Override
public ListCell call(ListView p) {
return new ListCell<>() {
@@ -76,11 +74,12 @@ public class Launcher {
System.exit(1);
}
+ Stage stage = new Stage();
Scene scene = new Scene(root, 600, 800);
stage.setScene(scene);
stage.setTitle(LocaleManager.translate(Strings.MAIN_WINDOW_TITLE));
- stage.getIcons().add(GUITools.logo);
+ GUITools.initializeScene(scene);
stage.setOnCloseRequest(windowEvent -> System.exit(0));
if (exit) {
return;
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
index ed971ab4d..c5af7af3a 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/MainWindow.java
@@ -13,10 +13,16 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.JFXAlert;
+import com.jfoenix.controls.JFXButton;
+import com.jfoenix.controls.JFXDialogLayout;
+import com.jfoenix.controls.JFXTextField;
+import com.jfoenix.validation.RequiredFieldValidator;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.data.locale.LocaleManager;
import de.bixilon.minosoft.data.locale.Strings;
import de.bixilon.minosoft.data.mappings.versions.Versions;
+import de.bixilon.minosoft.data.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.protocol.LANServerListener;
import de.bixilon.minosoft.util.DNSUtil;
@@ -25,11 +31,12 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
-import javafx.geometry.Insets;
-import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
-import javafx.scene.control.*;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Label;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuItem;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane;
@@ -37,6 +44,7 @@ import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
+import javax.annotation.Nullable;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
@@ -62,22 +70,28 @@ public class MainWindow implements Initializable {
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle(LocaleManager.translate(Strings.MANAGE_ACCOUNTS_NO_ACCOUNT_ERROR_TITLE));
- stage.getIcons().add(GUITools.logo);
stage.setScene(new Scene(parent));
+
+ GUITools.initializeScene(stage.getScene());
Platform.setImplicitExit(false);
stage.setOnCloseRequest(event -> {
if (Minosoft.getSelectedAccount() == null) {
event.consume();
- Alert alert = new Alert(Alert.AlertType.WARNING, LocaleManager.translate(Strings.ERROR), ButtonType.CANCEL, ButtonType.OK);
- alert.setHeaderText(LocaleManager.translate(Strings.MANAGE_ACCOUNTS_NO_ACCOUNT_ERROR_HEADER));
- alert.setContentText(LocaleManager.translate(Strings.MANAGE_ACCOUNTS_NO_ACCOUNT_ERROR_ERROR));
- alert.showAndWait().ifPresent((type) -> {
- if (type == ButtonType.OK) {
- System.exit(0);
- return;
- }
- alert.close();
- });
+ JFXAlert> alert = new JFXAlert<>();
+ GUITools.initializePane(alert.getDialogPane());
+ alert.setTitle(LocaleManager.translate(Strings.ERROR));
+ JFXDialogLayout layout = new JFXDialogLayout();
+ layout.setHeading(new Label(LocaleManager.translate(Strings.MANAGE_ACCOUNTS_NO_ACCOUNT_ERROR_HEADER)));
+ layout.setBody(new Label(LocaleManager.translate(Strings.MANAGE_ACCOUNTS_NO_ACCOUNT_ERROR_ERROR)));
+
+ JFXButton cancel = new JFXButton(ButtonType.CANCEL.getText());
+ cancel.setOnAction((actionEvent -> alert.close()));
+ JFXButton close = new JFXButton(ButtonType.OK.getText());
+ close.setOnAction(actionEvent -> System.exit(0));
+
+ layout.setActions(cancel, close);
+ alert.setContent(layout);
+ alert.showAndWait();
} else {
stage.close();
}
@@ -106,6 +120,116 @@ public class MainWindow implements Initializable {
});
}
+ public static void addOrEditServer(@Nullable final Server server) {
+ JFXAlert> dialog = new JFXAlert<>();
+ GUITools.initializePane(dialog.getDialogPane());
+
+
+ JFXDialogLayout layout = new JFXDialogLayout();
+
+ GridPane gridPane = new GridPane();
+ gridPane.setVgap(15);
+ gridPane.setHgap(50);
+
+ JFXButton submitButton;
+
+
+ JFXTextField serverNameField = new JFXTextField();
+ serverNameField.setPromptText(LocaleManager.translate(Strings.SERVER_NAME));
+
+ JFXTextField serverAddressField = new JFXTextField();
+ serverAddressField.setPromptText(LocaleManager.translate(Strings.SERVER_ADDRESS));
+ RequiredFieldValidator serverAddressValidator = new RequiredFieldValidator();
+ serverAddressValidator.setMessage(LocaleManager.translate(Strings.SERVER_ADDRESS_INPUT_REQUIRED));
+ serverAddressField.getValidators().add(serverAddressValidator);
+ serverAddressField.focusedProperty().addListener((o, oldValue, newValue) -> {
+ if (!newValue) {
+ serverAddressField.validate();
+ }
+ });
+
+ GUITools.VERSION_COMBO_BOX.getSelectionModel().select(Versions.LOWEST_VERSION_SUPPORTED);
+
+
+ if (server == null) {
+ // add
+ dialog.setTitle(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_TITLE));
+ layout.setHeading(new Label(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_HEADER)));
+
+ submitButton = new JFXButton(LocaleManager.translate(Strings.BUTTON_ADD));
+
+ serverNameField.setText(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_DEFAULT_SERVER_NAME));
+ } else {
+ dialog.setTitle(LocaleManager.translate(Strings.EDIT_SERVER_DIALOG_TITLE, server.getName().getMessage()));
+ layout.setHeading(new Label(LocaleManager.translate(Strings.EDIT_SERVER_DIALOG_HEADER)));
+
+ submitButton = new JFXButton(LocaleManager.translate(Strings.BUTTON_SAVE));
+
+ serverNameField.setText(server.getName().getLegacyText());
+ serverAddressField.setText(server.getAddress());
+
+ if (server.getDesiredVersionId() != -1) {
+ GUITools.VERSION_COMBO_BOX.getSelectionModel().select(Versions.getVersionById(server.getDesiredVersionId()));
+ }
+ }
+ submitButton.setButtonType(JFXButton.ButtonType.RAISED);
+
+ gridPane.add(new Label(LocaleManager.translate(Strings.SERVER_NAME) + ":"), 0, 0);
+ gridPane.add(serverNameField, 1, 0);
+ gridPane.add(new Label(LocaleManager.translate(Strings.SERVER_ADDRESS) + ":"), 0, 1);
+ gridPane.add(serverAddressField, 1, 1);
+ gridPane.add(new Label(LocaleManager.translate(Strings.VERSION) + ":"), 0, 2);
+ gridPane.add(GUITools.VERSION_COMBO_BOX, 1, 2);
+
+
+ layout.setBody(gridPane);
+ JFXButton closeButton = new JFXButton(ButtonType.CLOSE.getText());
+ closeButton.setOnAction((actionEvent -> dialog.hide()));
+ closeButton.setButtonType(JFXButton.ButtonType.RAISED);
+ layout.setActions(closeButton, submitButton);
+
+
+ serverAddressField.textProperty().addListener((observable, oldValue, newValue) -> submitButton.setDisable(newValue.trim().isEmpty()));
+ submitButton.setDisable(serverAddressField.getText().isBlank());
+ dialog.setContent(layout);
+
+ Platform.runLater(serverNameField::requestFocus);
+
+ submitButton.setOnAction(actionEvent -> {
+ Server server1 = server;
+ BaseComponent serverName = new BaseComponent(serverNameField.getText());
+ String serverAddress = DNSUtil.correctHostName(serverAddressField.getText());
+ int desiredVersionId = GUITools.VERSION_COMBO_BOX.getSelectionModel().getSelectedItem().getVersionId();
+
+ if (server1 == null) {
+ server1 = new Server(Server.getNextServerId(), serverName, serverAddress, desiredVersionId);
+ Minosoft.serverList.add(server1);
+ ServerListCell.listView.getItems().add(server1);
+ } else {
+ server1.setName(serverName);
+ server1.setAddress(serverAddress);
+ server1.setDesiredVersionId(desiredVersionId);
+ if (server1.getCell() != null) {
+ server1.getCell().setName(server1.getName());
+ //ToDo: version
+ }
+ }
+ server1.saveToConfig();
+ Log.info(String.format("%s and saved server (serverName=%s, serverAddress=%s, version=%d)", ((server == null) ? "Added" : "Edited"), serverName.getLegacyText(), serverAddress, desiredVersionId));
+ dialog.hide();
+ });
+ dialog.getDialogPane().setOnKeyReleased(keyEvent -> {
+ if (keyEvent.getCode() != KeyCode.ENTER) {
+ return;
+ }
+ if (serverAddressField.getText().trim().isEmpty()) {
+ return;
+ }
+ submitButton.fire();
+ });
+ dialog.showAndWait();
+ }
+
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
serversPane.setCenter(ServerListCell.listView);
@@ -125,54 +249,7 @@ public class MainWindow implements Initializable {
@FXML
public void addServer() {
- Dialog> dialog = new Dialog<>();
- dialog.setTitle(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_TITLE));
- dialog.setHeaderText(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_HEADER));
- ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(GUITools.logo);
-
- ButtonType addButtonType = new ButtonType(LocaleManager.translate(Strings.BUTTON_ADD), ButtonBar.ButtonData.OK_DONE);
- dialog.getDialogPane().getButtonTypes().addAll(addButtonType, ButtonType.CANCEL);
-
- GridPane grid = new GridPane();
- grid.setHgap(10);
- grid.setVgap(10);
- grid.setPadding(new Insets(20, 300, 10, 10));
-
- TextField serverName = new TextField();
- serverName.setPromptText(LocaleManager.translate(Strings.SERVER_NAME));
- serverName.setText(LocaleManager.translate(Strings.ADD_SERVER_DIALOG_DEFAULT_SERVER_NAME));
- TextField serverAddress = new TextField();
- serverAddress.setPromptText(LocaleManager.translate(Strings.SERVER_ADDRESS));
-
- GUITools.versionList.getSelectionModel().select(Versions.LOWEST_VERSION_SUPPORTED);
-
- grid.add(new Label(LocaleManager.translate(Strings.SERVER_NAME) + ":"), 0, 0);
- grid.add(serverName, 1, 0);
- grid.add(new Label(LocaleManager.translate(Strings.SERVER_ADDRESS) + ":"), 0, 1);
- grid.add(serverAddress, 1, 1);
- grid.add(new Label(LocaleManager.translate(Strings.VERSION) + ":"), 0, 2);
- grid.add(GUITools.versionList, 1, 2);
-
- Node addButton = dialog.getDialogPane().lookupButton(addButtonType);
-
- serverAddress.textProperty().addListener((observable, oldValue, newValue) -> addButton.setDisable(newValue.trim().isEmpty()));
- addButton.setDisable(true);
-
- dialog.getDialogPane().setContent(grid);
-
- Platform.runLater(serverName::requestFocus);
-
- dialog.setResultConverter(dialogButton -> {
- if (dialogButton == addButtonType) {
- Server server = new Server(Server.getNextServerId(), serverName.getText(), DNSUtil.correctHostName(serverAddress.getText()), GUITools.versionList.getSelectionModel().getSelectedItem().getVersionId());
- Minosoft.serverList.add(server);
- server.saveToConfig();
- ServerListCell.listView.getItems().add(server);
- Log.info(String.format("Added and saved server (serverName=%s, serverAddress=%s, version=%d)", server.getName(), server.getAddress(), server.getDesiredVersionId()));
- }
- return null;
- });
- dialog.showAndWait();
+ addOrEditServer(null);
}
@FXML
@@ -205,10 +282,9 @@ public class MainWindow implements Initializable {
Parent parent = new FXMLLoader(MainWindow.class.getResource("/layout/settings.fxml")).load();
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
- stage.getIcons().add(GUITools.logo);
stage.setTitle(LocaleManager.translate(Strings.SETTINGS_TITLE));
- stage.getIcons().add(GUITools.logo);
stage.setScene(new Scene(parent));
+ GUITools.initializeScene(stage.getScene());
stage.addEventHandler(KeyEvent.KEY_PRESSED, (KeyEvent event) -> {
if (event.getCode() == KeyCode.ESCAPE) {
stage.close();
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/Server.java b/src/main/java/de/bixilon/minosoft/gui/main/Server.java
index 20caac79f..78c00a0e6 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/Server.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/Server.java
@@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.main;
import com.google.gson.JsonObject;
import de.bixilon.minosoft.Minosoft;
+import de.bixilon.minosoft.data.text.BaseComponent;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.protocol.ConnectionReasons;
import de.bixilon.minosoft.protocol.protocol.LANServerListener;
@@ -25,34 +26,37 @@ import java.util.ArrayList;
import java.util.Base64;
public class Server {
- static int highestServerId;
- final int id;
- final ArrayList connections = new ArrayList<>();
- String name;
- String address;
- int desiredVersion;
- byte[] favicon;
- Connection lastPing;
+ private static int highestServerId;
+ private final int id;
+ private final ArrayList connections = new ArrayList<>();
+ private BaseComponent name;
+ private BaseComponent addressName;
+ private String address;
+ private int desiredVersion;
+ private byte[] favicon;
+ private Connection lastPing;
private boolean readOnly = false;
+ private ServerListCell cell;
- public Server(int id, String name, String address, int desiredVersion, byte[] favicon) {
+ public Server(int id, BaseComponent name, String address, int desiredVersion, byte[] favicon) {
this(id, name, address, desiredVersion);
this.favicon = favicon;
}
- public Server(int id, String name, String address, int desiredVersion) {
+ public Server(int id, BaseComponent name, String address, int desiredVersion) {
this.id = id;
if (id > highestServerId) {
highestServerId = id;
}
this.name = name;
this.address = address;
+ this.addressName = new BaseComponent(address);
this.desiredVersion = desiredVersion;
}
public Server(ServerAddress address) {
this.id = getNextServerId();
- this.name = String.format("LAN Server #%d", LANServerListener.getServers().size());
+ this.name = new BaseComponent(String.format("LAN Server #%d", LANServerListener.getServers().size()));
this.address = address.toString();
this.desiredVersion = -1; // Automatic
this.readOnly = true;
@@ -63,7 +67,7 @@ public class Server {
}
public static Server deserialize(JsonObject json) {
- Server server = new Server(json.get("id").getAsInt(), json.get("name").getAsString(), json.get("address").getAsString(), json.get("version").getAsInt());
+ Server server = new Server(json.get("id").getAsInt(), new BaseComponent(json.get("name").getAsString()), json.get("address").getAsString(), json.get("version").getAsInt());
if (json.has("favicon")) {
server.setFavicon(Base64.getDecoder().decode(json.get("favicon").getAsString()));
}
@@ -113,11 +117,15 @@ public class Server {
return String.format("%s (%s)", getName(), getAddress());
}
- public String getName() {
+ public BaseComponent getName() {
+ if (name.isEmpty()) {
+ return addressName;
+ }
return name;
}
- public void setName(String name) {
+
+ public void setName(BaseComponent name) {
this.name = name;
}
@@ -127,6 +135,7 @@ public class Server {
public void setAddress(String address) {
this.address = address;
+ this.addressName = new BaseComponent(address);
}
public void ping() {
@@ -164,7 +173,7 @@ public class Server {
public JsonObject serialize() {
JsonObject json = new JsonObject();
json.addProperty("id", id);
- json.addProperty("name", name);
+ json.addProperty("name", name.getLegacyText());
json.addProperty("address", address);
json.addProperty("version", desiredVersion);
if (favicon != null) {
@@ -184,4 +193,12 @@ public class Server {
public boolean isReadOnly() {
return readOnly;
}
+
+ public ServerListCell getCell() {
+ return cell;
+ }
+
+ public void setCell(ServerListCell cell) {
+ this.cell = cell;
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java
index f49b2de7e..93280b9bb 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/ServerListCell.java
@@ -13,12 +13,16 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.JFXAlert;
+import com.jfoenix.controls.JFXButton;
+import com.jfoenix.controls.JFXDialogLayout;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.data.Player;
import de.bixilon.minosoft.data.locale.LocaleManager;
import de.bixilon.minosoft.data.locale.Strings;
import de.bixilon.minosoft.data.mappings.versions.Version;
import de.bixilon.minosoft.data.mappings.versions.Versions;
+import de.bixilon.minosoft.data.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.modding.event.EventInvokerCallback;
import de.bixilon.minosoft.modding.event.events.ConnectionStateChangeEvent;
@@ -26,11 +30,9 @@ import de.bixilon.minosoft.modding.event.events.ServerListPingArriveEvent;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.ping.ForgeModInfo;
import de.bixilon.minosoft.protocol.ping.ServerListPing;
-import de.bixilon.minosoft.util.DNSUtil;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
-import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
@@ -38,7 +40,6 @@ import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
-import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
@@ -54,13 +55,14 @@ import java.util.ResourceBundle;
public class ServerListCell extends ListCell implements Initializable {
public static final ListView listView = new ListView<>();
- public ImageView icon;
- public TextFlow motd;
- public Label version;
- public Label players;
- public Label serverBrand;
- public Label serverName;
- public AnchorPane root;
+ public ImageView faviconField;
+ public TextFlow nameField;
+ public TextFlow motdField;
+ public Label versionField;
+ public Label playersField;
+ public Label brandField;
+
+ public GridPane root;
public MenuItem optionsConnect;
public MenuItem optionsShowInfo;
public MenuItem optionsEdit;
@@ -97,10 +99,6 @@ public class ServerListCell extends ListCell implements Initializable {
optionsDelete.setText(LocaleManager.translate(Strings.SERVER_ACTION_DELETE));
}
- public AnchorPane getRoot() {
- return root;
- }
-
@Override
protected void updateItem(Server server, boolean empty) {
super.updateItem(server, empty);
@@ -117,16 +115,17 @@ public class ServerListCell extends ListCell implements Initializable {
if (server.equals(this.server)) {
return;
}
+ server.setCell(this);
resetCell();
this.server = server;
- serverName.setText(server.getName());
+ setName(server.getName());
Image favicon = GUITools.getImage(server.getFavicon());
if (favicon == null) {
- favicon = GUITools.logo;
+ favicon = GUITools.MINOSOFT_LOGO;
}
- icon.setImage(favicon);
+ faviconField.setImage(favicon);
if (server.isConnected()) {
setStyle("-fx-background-color: darkseagreen;");
optionsSessions.setDisable(false);
@@ -149,37 +148,37 @@ public class ServerListCell extends ListCell implements Initializable {
}
if (ping == null) {
// Offline
- players.setText("");
- version.setText(LocaleManager.translate(Strings.OFFLINE));
- version.setStyle("-fx-text-fill: red;");
+ playersField.setText("");
+ versionField.setText(LocaleManager.translate(Strings.OFFLINE));
+ versionField.setStyle("-fx-text-fill: red;");
setErrorMotd(String.format("%s", server.getLastPing().getLastConnectionException()));
optionsConnect.setDisable(true);
canConnect = false;
return;
}
- players.setText(LocaleManager.translate(Strings.SERVER_INFO_SLOTS_PLAYERS_ONLINE, ping.getPlayerOnline(), ping.getMaxPlayers()));
+ playersField.setText(LocaleManager.translate(Strings.SERVER_INFO_SLOTS_PLAYERS_ONLINE, ping.getPlayerOnline(), ping.getMaxPlayers()));
Version serverVersion;
if (server.getDesiredVersionId() == -1) {
serverVersion = Versions.getVersionByProtocolId(ping.getProtocolId());
} else {
serverVersion = Versions.getVersionById(server.getDesiredVersionId());
- version.setStyle("-fx-text-fill: green;");
+ versionField.setStyle("-fx-text-fill: -secondary-light-light-color;");
}
if (serverVersion == null) {
- version.setText(ping.getServerBrand());
- version.setStyle("-fx-text-fill: red;");
+ versionField.setText(ping.getServerBrand());
+ versionField.setStyle("-fx-text-fill: red;");
optionsConnect.setDisable(true);
canConnect = false;
} else {
- version.setText(serverVersion.getVersionName());
+ versionField.setText(serverVersion.getVersionName());
optionsConnect.setDisable(false);
canConnect = true;
}
- serverBrand.setText(ping.getServerModInfo().getBrand());
- serverBrand.setTooltip(new Tooltip(ping.getServerModInfo().getInfo()));
- motd.getChildren().addAll(ping.getMotd().getJavaFXText());
+ brandField.setText(ping.getServerModInfo().getBrand());
+ brandField.setTooltip(new Tooltip(ping.getServerModInfo().getInfo()));
+ motdField.getChildren().setAll(ping.getMotd().getJavaFXText());
if (ping.getFavicon() != null) {
- icon.setImage(GUITools.getImage(ping.getFavicon()));
+ faviconField.setImage(GUITools.getImage(ping.getFavicon()));
if (!Arrays.equals(ping.getFavicon(), server.getFavicon())) {
server.setFavicon(ping.getFavicon());
server.saveToConfig();
@@ -191,34 +190,40 @@ public class ServerListCell extends ListCell implements Initializable {
}
if (server.getLastPing().getLastConnectionException() != null) {
// connection failed because of an error in minosoft, but ping was okay
- version.setStyle("-fx-text-fill: red;");
+ versionField.setStyle("-fx-text-fill: red;");
optionsConnect.setDisable(true);
canConnect = false;
- setErrorMotd(String.format("%s: %s", server.getLastPing().getLastConnectionException().getClass().getCanonicalName(), server.getLastPing().getLastConnectionException().getLocalizedMessage()));
+ setErrorMotd(String.format("%s: %s", server.getLastPing().getLastConnectionException().getClass().getCanonicalName(), server.getLastPing().getLastConnectionException().getMessage()));
}
})));
}
+ public void setName(BaseComponent name) {
+ nameField.getChildren().setAll(name.getJavaFXText());
+ for (Node node : nameField.getChildren()) {
+ node.setStyle("-fx-font-size: 15pt ;");
+ }
+ }
+
private void resetCell() {
// clear all cells
setStyle(null);
- motd.getChildren().clear();
- serverBrand.setText("");
- serverBrand.setTooltip(null);
- motd.setStyle(null);
- version.setText(LocaleManager.translate(Strings.CONNECTING));
- version.setStyle(null);
- players.setText("");
+ motdField.getChildren().clear();
+ brandField.setText("");
+ brandField.setTooltip(null);
+ motdField.setStyle(null);
+ versionField.setText(LocaleManager.translate(Strings.CONNECTING));
+ versionField.setStyle(null);
+ playersField.setText("");
optionsConnect.setDisable(true);
optionsEdit.setDisable(false);
optionsDelete.setDisable(false);
}
private void setErrorMotd(String message) {
- motd.getChildren().clear();
Text text = new Text(message);
text.setFill(Color.RED);
- motd.getChildren().add(text);
+ motdField.getChildren().setAll(text);
}
public void delete() {
@@ -227,12 +232,12 @@ public class ServerListCell extends ListCell implements Initializable {
}
server.getConnections().forEach(Connection::disconnect);
server.delete();
- Log.info(String.format("Deleted server (name=\"%s\", address=\"%s\")", server.getName(), server.getAddress()));
+ Log.info(String.format("Deleted server (name=\"%s\", address=\"%s\")", server.getName().getLegacyText(), server.getAddress()));
listView.getItems().remove(server);
}
public void refresh() {
- Log.info(String.format("Refreshing server status (serverName=\"%s\", address=\"%s\")", server.getName(), server.getAddress()));
+ Log.info(String.format("Refreshing server status (serverName=\"%s\", address=\"%s\")", server.getName().getLegacyText(), server.getAddress()));
if (server.getLastPing() == null) {
// server was not pinged, don't even try, only costs memory and cpu
return;
@@ -250,7 +255,7 @@ public class ServerListCell extends ListCell implements Initializable {
case SECONDARY -> optionsMenu.fire();
case MIDDLE -> {
listView.getSelectionModel().select(server);
- edit();
+ editServer();
}
}
}
@@ -273,68 +278,8 @@ public class ServerListCell extends ListCell implements Initializable {
}
- public void edit() {
- if (server.isReadOnly()) {
- return;
- }
- Dialog> dialog = new Dialog<>();
- dialog.setTitle(LocaleManager.translate(Strings.EDIT_SERVER_DIALOG_TITLE, server.getName()));
- dialog.setHeaderText(LocaleManager.translate(Strings.EDIT_SERVER_DIALOG_HEADER));
- ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(GUITools.logo);
-
- ButtonType saveButtonType = new ButtonType(LocaleManager.translate(Strings.BUTTON_SAVE), ButtonBar.ButtonData.OK_DONE);
- dialog.getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL);
-
- GridPane grid = new GridPane();
- grid.setHgap(10);
- grid.setVgap(10);
- grid.setPadding(new Insets(20, 300, 10, 10));
-
- TextField serverName = new TextField();
- serverName.setPromptText(LocaleManager.translate(Strings.SERVER_NAME));
- serverName.setText(server.getName());
- TextField serverAddress = new TextField();
- serverAddress.setPromptText(LocaleManager.translate(Strings.SERVER_ADDRESS));
- serverAddress.setText(server.getAddress());
-
- if (server.getDesiredVersionId() == -1) {
- GUITools.versionList.getSelectionModel().select(Versions.LOWEST_VERSION_SUPPORTED);
- } else {
- GUITools.versionList.getSelectionModel().select(Versions.getVersionById(server.getDesiredVersionId()));
- }
-
- grid.add(new Label(LocaleManager.translate(Strings.SERVER_NAME) + ":"), 0, 0);
- grid.add(serverName, 1, 0);
- grid.add(new Label(LocaleManager.translate(Strings.SERVER_ADDRESS) + ":"), 0, 1);
- grid.add(serverAddress, 1, 1);
- grid.add(new Label(LocaleManager.translate(Strings.VERSION) + ":"), 0, 2);
- grid.add(GUITools.versionList, 1, 2);
-
- Node saveButton = dialog.getDialogPane().lookupButton(saveButtonType);
-
- serverAddress.textProperty().addListener((observable, oldValue, newValue) -> saveButton.setDisable(newValue.trim().isEmpty()));
-
- dialog.getDialogPane().setContent(grid);
-
- Platform.runLater(serverName::requestFocus);
-
- dialog.setResultConverter(dialogButton -> {
- if (dialogButton == saveButtonType) {
- serverName.setText(serverName.getText());
- server.setName(serverName.getText());
- server.setDesiredVersionId(GUITools.versionList.getSelectionModel().getSelectedItem().getVersionId());
- if (server.getDesiredVersionId() != -1) {
- version.setText(Versions.getVersionById(server.getDesiredVersionId()).getVersionName());
- version.setTextFill(Color.BLACK);
- }
- server.setAddress(DNSUtil.correctHostName(serverAddress.getText()));
- server.saveToConfig();
- Log.info(String.format("Edited and saved server (serverName=%s, serverAddress=%s, version=%d)", server.getName(), server.getAddress(), server.getDesiredVersionId()));
- }
- return null;
- });
-
- dialog.showAndWait();
+ public void editServer() {
+ MainWindow.addOrEditServer(server);
}
private void handleConnectionCallback(ConnectionStateChangeEvent event) {
@@ -363,19 +308,24 @@ public class ServerListCell extends ListCell implements Initializable {
}
public void showInfo() {
- Dialog> dialog = new Dialog<>();
- dialog.setTitle("View server info: " + server.getName());
- ((Stage) dialog.getDialogPane().getScene().getWindow()).getIcons().add(GUITools.logo);
+ JFXAlert> dialog = new JFXAlert<>();
+ dialog.setTitle("View server info: " + server.getName().getMessage());
+ GUITools.initializePane(dialog.getDialogPane());
- ButtonType loginButtonType = ButtonType.CLOSE;
- dialog.getDialogPane().getButtonTypes().add(loginButtonType);
+ JFXDialogLayout layout = new JFXDialogLayout();
+
+
+ JFXButton closeButton = new JFXButton(ButtonType.CLOSE.getText());
+ closeButton.setOnAction((actionEvent -> dialog.hide()));
+ closeButton.setButtonType(JFXButton.ButtonType.RAISED);
+ layout.setActions(closeButton);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
- grid.setPadding(new Insets(20, 300, 10, 10));
- Label serverNameLabel = new Label(server.getName());
+ TextFlow serverNameLabel = new TextFlow();
+ serverNameLabel.getChildren().setAll(server.getName().getJavaFXText());
Label serverAddressLabel = new Label(server.getAddress());
Label forcedVersionLabel = new Label();
@@ -386,7 +336,9 @@ public class ServerListCell extends ListCell implements Initializable {
}
int column = -1;
- grid.add(new Label(LocaleManager.translate(Strings.SERVER_NAME) + ":"), 0, ++column);
+ Label a = new Label(LocaleManager.translate(Strings.SERVER_NAME) + ":");
+ a.setWrapText(false);
+ grid.add(a, 0, ++column);
grid.add(serverNameLabel, 1, column);
grid.add(new Label(LocaleManager.translate(Strings.SERVER_ADDRESS) + ":"), 0, ++column);
grid.add(serverAddressLabel, 1, column);
@@ -415,7 +367,7 @@ public class ServerListCell extends ListCell implements Initializable {
Label serverBrandLabel = new Label(lastPing.getServerBrand());
Label playersOnlineMaxLabel = new Label(LocaleManager.translate(Strings.SERVER_INFO_SLOTS_PLAYERS_ONLINE, lastPing.getPlayerOnline(), lastPing.getMaxPlayers()));
TextFlow motdLabel = new TextFlow();
- motdLabel.getChildren().addAll(lastPing.getMotd().getJavaFXText());
+ motdLabel.getChildren().setAll(lastPing.getMotd().getJavaFXText());
Label moddedBrandLabel = new Label(lastPing.getServerModInfo().getBrand());
grid.add(new Label(LocaleManager.translate(Strings.SERVER_INFO_REAL_SERVER_ADDRESS) + ":"), 0, ++column);
@@ -440,9 +392,9 @@ public class ServerListCell extends ListCell implements Initializable {
}
}
}
-
- dialog.getDialogPane().setContent(grid);
-
+ // ToDo: size probably
+ layout.setBody(grid);
+ dialog.setContent(layout);
dialog.showAndWait();
}
@@ -454,8 +406,8 @@ public class ServerListCell extends ListCell implements Initializable {
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle(LocaleManager.translate(Strings.SESSIONS_DIALOG_TITLE, server.getName()));
- stage.getIcons().add(GUITools.logo);
stage.setScene(new Scene(parent));
+ GUITools.initializeScene(stage.getScene());
stage.show();
} catch (IOException e) {
e.printStackTrace();
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/SettingsWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/SettingsWindow.java
index 5eeb63353..a17a62663 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/SettingsWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/SettingsWindow.java
@@ -13,6 +13,7 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.JFXComboBox;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.config.ConfigurationPaths;
import de.bixilon.minosoft.data.locale.LocaleManager;
@@ -20,7 +21,6 @@ import de.bixilon.minosoft.data.locale.Strings;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.logging.LogLevels;
import javafx.fxml.Initializable;
-import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.layout.GridPane;
@@ -30,14 +30,14 @@ import java.util.ResourceBundle;
public class SettingsWindow implements Initializable {
public GridPane tabGeneral;
- public ComboBox generalLogLevel;
+ public JFXComboBox generalLogLevel;
public Tab general;
public Tab download;
public Label generalLogLevelLabel;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
- generalLogLevel.setItems(GUITools.logLevels);
+ generalLogLevel.setItems(GUITools.LOG_LEVELS);
generalLogLevel.getSelectionModel().select(Log.getLevel());
generalLogLevel.setOnAction((actionEvent -> {
LogLevels newLevel = generalLogLevel.getValue();
diff --git a/src/main/java/de/bixilon/minosoft/gui/main/StartProgressWindow.java b/src/main/java/de/bixilon/minosoft/gui/main/StartProgressWindow.java
index 1fcd420a7..393723cd6 100644
--- a/src/main/java/de/bixilon/minosoft/gui/main/StartProgressWindow.java
+++ b/src/main/java/de/bixilon/minosoft/gui/main/StartProgressWindow.java
@@ -13,25 +13,27 @@
package de.bixilon.minosoft.gui.main;
+import com.jfoenix.controls.JFXAlert;
+import com.jfoenix.controls.JFXDialogLayout;
+import com.jfoenix.controls.JFXProgressBar;
import de.bixilon.minosoft.data.locale.LocaleManager;
import de.bixilon.minosoft.data.locale.Strings;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.CountUpAndDownLatch;
import javafx.application.Application;
import javafx.application.Platform;
-import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
-import javafx.scene.control.ProgressBar;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicReference;
public class StartProgressWindow extends Application {
- public static CountDownLatch toolkitLatch = new CountDownLatch(2); // 2 if not started, 1 if started, 2 if loaded
- public static Dialog progressDialog;
+ public final static CountDownLatch toolkitLatch = new CountDownLatch(2); // 2 if not started, 1 if started, 2 if loaded
+ public static JFXAlert progressDialog;
+ private static JFXProgressBar progressBar;
+ private static Label progressLabel;
private static boolean exit = false;
public static void show(CountUpAndDownLatch progress) throws InterruptedException {
@@ -44,20 +46,30 @@ public class StartProgressWindow extends Application {
latch.countDown();
return;
}
- AtomicReference progressBar = new AtomicReference<>();
- AtomicReference