diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ServerAddressValidator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ServerAddressValidator.java new file mode 100644 index 000000000..8a73c8ef4 --- /dev/null +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/ServerAddressValidator.java @@ -0,0 +1,62 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2022 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.ui.construct; + +import com.jfoenix.validation.base.ValidatorBase; +import javafx.beans.NamedArg; +import javafx.scene.control.TextInputControl; +import org.jackhuang.hmcl.util.StringUtils; + +import java.util.regex.Pattern; + +import static org.jackhuang.hmcl.util.i18n.I18n.i18n; + +public class ServerAddressValidator extends ValidatorBase { + private final boolean nullable; + + public ServerAddressValidator() { + this(false); + } + + public ServerAddressValidator(@NamedArg("nullable") boolean nullable) { + this(i18n("input.url"), nullable); + } + + public ServerAddressValidator(@NamedArg("message") String message, @NamedArg("nullable") boolean nullable) { + super(message); + this.nullable = nullable; + } + + @Override + protected void eval() { + if (srcControl.get() instanceof TextInputControl) { + evalTextInputField(); + } + } + + private static final Pattern PATTERN = Pattern.compile("[-a-zA-Z0-9@:%._+~#=]{1,256}(:\\d+)?"); + + private void evalTextInputField() { + TextInputControl textField = ((TextInputControl) srcControl.get()); + + if (StringUtils.isBlank(textField.getText())) + hasErrors.set(!nullable); + else + hasErrors.set(!PATTERN.matcher(textField.getText()).matches()); + } +} diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/URLValidator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/URLValidator.java index dfd8a5864..357a8b01e 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/URLValidator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/construct/URLValidator.java @@ -1,3 +1,20 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2022 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package org.jackhuang.hmcl.ui.construct; import com.jfoenix.validation.base.ValidatorBase; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java index 8753246f6..fbaaa6e8c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPage.java @@ -290,7 +290,7 @@ public class MultiplayerPage extends DecoratorAnimatedPage implements DecoratorP break; } - clearSession(); +// clearSession(); }); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java index 011890bfe..cb91cf2d4 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/multiplayer/MultiplayerPageSkin.java @@ -215,31 +215,29 @@ public class MultiplayerPageSkin extends DecoratorAnimatedPage.DecoratorAnimated Label addressTitle = new Label(i18n("multiplayer.slave.server_address")); JFXTextField addressField = new JFXTextField(); - GridPane.setColumnSpan(addressField, 2); FXUtils.setValidateWhileTextChanged(addressField, true); - addressField.getValidators().add(new URLValidator()); + addressField.getValidators().add(new ServerAddressValidator()); - JFXButton startButton = new JFXButton(i18n("multiplayer.master.server_address.start")); + JFXButton startButton = new JFXButton(i18n("multiplayer.slave.server_address.start")); startButton.setOnAction(e -> control.broadcast(addressField.getText())); - notBroadcastingPane.addRow(2, addressTitle, addressField, startButton); + notBroadcastingPane.addRow(0, addressTitle, addressField, startButton); } GridPane broadcastingPane = new GridPane(); { - notBroadcastingPane.setVgap(8); - notBroadcastingPane.setHgap(16); - notBroadcastingPane.getColumnConstraints().setAll(titleColumn, valueColumn, rightColumn); + broadcastingPane.setVgap(8); + broadcastingPane.setHgap(16); + broadcastingPane.getColumnConstraints().setAll(titleColumn, valueColumn, rightColumn); Label addressTitle = new Label(i18n("multiplayer.slave.server_address")); Label addressLabel = new Label(); addressLabel.textProperty().bind(Bindings.createStringBinding(() -> control.getBroadcaster() != null ? control.getBroadcaster().getAddress() : "", control.broadcasterProperty())); - GridPane.setColumnSpan(addressLabel, 2); JFXButton stopButton = new JFXButton(i18n("multiplayer.slave.server_address.stop")); stopButton.setOnAction(e -> control.stopBroadcasting()); - notBroadcastingPane.addRow(2, addressTitle, addressLabel, stopButton); + broadcastingPane.addRow(0, addressTitle, addressLabel, stopButton); } FXUtils.onChangeAndOperate(control.broadcasterProperty(), broadcaster -> {