diff options
| author | 2020-04-22 23:52:09 +0200 | |
|---|---|---|
| committer | 2020-06-03 23:55:56 +0200 | |
| commit | a648df9683fc93922daad22f7bcb3e8c247d1860 (patch) | |
| tree | fcf95a84ff44a2fb7ccdfdbc0837749382bdfcc5 | |
| parent | Extend validation system (diff) | |
| download | enigma-fork-a648df9683fc93922daad22f7bcb3e8c247d1860.tar.gz enigma-fork-a648df9683fc93922daad22f7bcb3e8c247d1860.tar.xz enigma-fork-a648df9683fc93922daad22f7bcb3e8c247d1860.zip | |
Improve CreateServerDialog
3 files changed, 121 insertions, 45 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java index eede946..697fc51 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java | |||
| @@ -23,7 +23,7 @@ public class ConnectToServerDialog extends JDialog { | |||
| 23 | private final JTextField usernameField; | 23 | private final JTextField usernameField; |
| 24 | private final ValidatableTextField ipField; | 24 | private final ValidatableTextField ipField; |
| 25 | private final JPasswordField passwordField; | 25 | private final JPasswordField passwordField; |
| 26 | private boolean success = false; | 26 | private boolean actionConfirm = false; |
| 27 | 27 | ||
| 28 | public ConnectToServerDialog(Frame owner) { | 28 | public ConnectToServerDialog(Frame owner) { |
| 29 | super(owner, I18n.translate("prompt.connect.title"), true); | 29 | super(owner, I18n.translate("prompt.connect.title"), true); |
| @@ -70,7 +70,7 @@ public class ConnectToServerDialog extends JDialog { | |||
| 70 | buttonContainer.add(connectButton, c); | 70 | buttonContainer.add(connectButton, c); |
| 71 | c.weightx = 0.0; | 71 | c.weightx = 0.0; |
| 72 | c.anchor = GridBagConstraints.CENTER; | 72 | c.anchor = GridBagConstraints.CENTER; |
| 73 | JButton abortButton = new JButton(I18n.translate("prompt.connect.cancel")); | 73 | JButton abortButton = new JButton(I18n.translate("prompt.cancel")); |
| 74 | abortButton.addActionListener(event -> cancel()); | 74 | abortButton.addActionListener(event -> cancel()); |
| 75 | buttonContainer.add(abortButton, c); | 75 | buttonContainer.add(abortButton, c); |
| 76 | contentPane.add(buttonContainer, BorderLayout.SOUTH); | 76 | contentPane.add(buttonContainer, BorderLayout.SOUTH); |
| @@ -83,13 +83,13 @@ public class ConnectToServerDialog extends JDialog { | |||
| 83 | vc.reset(); | 83 | vc.reset(); |
| 84 | validateInputs(); | 84 | validateInputs(); |
| 85 | if (vc.canProceed()) { | 85 | if (vc.canProceed()) { |
| 86 | success = true; | 86 | actionConfirm = true; |
| 87 | setVisible(false); | 87 | setVisible(false); |
| 88 | } | 88 | } |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | private void cancel() { | 91 | private void cancel() { |
| 92 | success = false; | 92 | actionConfirm = false; |
| 93 | setVisible(false); | 93 | setVisible(false); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| @@ -98,11 +98,12 @@ public class ConnectToServerDialog extends JDialog { | |||
| 98 | if (ipField.getText().trim().isEmpty()) { | 98 | if (ipField.getText().trim().isEmpty()) { |
| 99 | vc.raise(Message.EMPTY_FIELD); | 99 | vc.raise(Message.EMPTY_FIELD); |
| 100 | } else if (ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT) == null) { | 100 | } else if (ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT) == null) { |
| 101 | vc.raise(Message.INVALID_IP, ipField.getText()); | 101 | vc.raise(Message.INVALID_IP); |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | public Result getResult() { | 105 | public Result getResult() { |
| 106 | if (!actionConfirm) return null; | ||
| 106 | vc.reset(); | 107 | vc.reset(); |
| 107 | validateInputs(); | 108 | validateInputs(); |
| 108 | if (!vc.canProceed()) return null; | 109 | if (!vc.canProceed()) return null; |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java index eea1dff..bc4e9c9 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java | |||
| @@ -1,47 +1,124 @@ | |||
| 1 | package cuchaz.enigma.gui.dialog; | 1 | package cuchaz.enigma.gui.dialog; |
| 2 | 2 | ||
| 3 | import java.awt.*; | ||
| 4 | import java.util.Arrays; | ||
| 5 | import java.util.List; | ||
| 6 | import java.util.stream.Collectors; | ||
| 7 | import java.util.stream.Stream; | ||
| 8 | |||
| 9 | import javax.swing.*; | ||
| 10 | |||
| 11 | import cuchaz.enigma.gui.elements.ValidatablePasswordField; | ||
| 12 | import cuchaz.enigma.gui.elements.ValidatableTextField; | ||
| 3 | import cuchaz.enigma.network.EnigmaServer; | 13 | import cuchaz.enigma.network.EnigmaServer; |
| 4 | import cuchaz.enigma.utils.I18n; | 14 | import cuchaz.enigma.utils.I18n; |
| 15 | import cuchaz.enigma.utils.validation.Message; | ||
| 16 | import cuchaz.enigma.utils.validation.StandardValidation; | ||
| 17 | import cuchaz.enigma.utils.validation.ValidationContext; | ||
| 5 | 18 | ||
| 6 | import javax.swing.*; | 19 | public class CreateServerDialog extends JDialog { |
| 7 | import java.awt.*; | ||
| 8 | 20 | ||
| 9 | public class CreateServerDialog { | 21 | private final ValidationContext vc = new ValidationContext(); |
| 10 | 22 | ||
| 11 | public static Result show(Frame parentComponent) { | 23 | private final ValidatableTextField portField; |
| 12 | JTextField portField = new JTextField(String.valueOf(EnigmaServer.DEFAULT_PORT), 10); | 24 | private final ValidatablePasswordField passwordField; |
| 13 | JPanel portRow = new JPanel(); | 25 | private boolean actionConfirm = false; |
| 14 | portRow.add(new JLabel(I18n.translate("prompt.port"))); | 26 | |
| 15 | portRow.add(portField); | 27 | public CreateServerDialog(Frame owner) { |
| 16 | JPasswordField passwordField = new JPasswordField(20); | 28 | super(owner, I18n.translate("prompt.create_server.title"), true); |
| 17 | JPanel passwordRow = new JPanel(); | 29 | |
| 18 | passwordRow.add(new JLabel(I18n.translate("prompt.password"))); | 30 | Container contentPane = getContentPane(); |
| 19 | passwordRow.add(passwordField); | 31 | contentPane.setLayout(new BorderLayout()); |
| 20 | 32 | Container inputContainer = new JPanel(new GridBagLayout()); | |
| 21 | int response = JOptionPane.showConfirmDialog(parentComponent, new Object[]{portRow, passwordRow}, I18n.translate("prompt.create_server.title"), JOptionPane.OK_CANCEL_OPTION); | 33 | GridBagConstraints c = new GridBagConstraints(); |
| 22 | if (response != JOptionPane.OK_OPTION) { | 34 | portField = new ValidatableTextField(Integer.toString(EnigmaServer.DEFAULT_PORT)); |
| 23 | return null; | 35 | passwordField = new ValidatablePasswordField(); |
| 24 | } | 36 | |
| 37 | java.util.List<JLabel> labels = Stream.of("prompt.create_server.port", "prompt.password") | ||
| 38 | .map(I18n::translate) | ||
| 39 | .map(JLabel::new) | ||
| 40 | .collect(Collectors.toList()); | ||
| 41 | List<JTextField> inputs = Arrays.asList(portField, passwordField); | ||
| 42 | |||
| 43 | for (int i = 0; i < inputs.size(); i += 1) { | ||
| 44 | c.gridy = i; | ||
| 45 | c.insets = new Insets(4, 4, 4, 4); | ||
| 25 | 46 | ||
| 26 | int port; | 47 | c.gridx = 0; |
| 27 | try { | 48 | c.weightx = 0.0; |
| 28 | port = Integer.parseInt(portField.getText()); | 49 | c.anchor = GridBagConstraints.LINE_END; |
| 29 | } catch (NumberFormatException e) { | 50 | c.fill = GridBagConstraints.NONE; |
| 30 | JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.nan"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE); | 51 | inputContainer.add(labels.get(i), c); |
| 31 | return null; | 52 | |
| 53 | c.gridx = 1; | ||
| 54 | c.weightx = 1.0; | ||
| 55 | c.anchor = GridBagConstraints.LINE_START; | ||
| 56 | c.fill = GridBagConstraints.HORIZONTAL; | ||
| 57 | inputs.get(i).addActionListener(event -> confirm()); | ||
| 58 | inputContainer.add(inputs.get(i), c); | ||
| 32 | } | 59 | } |
| 33 | if (port < 0 || port >= 65536) { | 60 | contentPane.add(inputContainer, BorderLayout.CENTER); |
| 34 | JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.invalid"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE); | 61 | Container buttonContainer = new JPanel(new GridBagLayout()); |
| 35 | return null; | 62 | c = new GridBagConstraints(); |
| 63 | c.weightx = 1.0; | ||
| 64 | c.insets = new Insets(4, 4, 4, 4); | ||
| 65 | c.anchor = GridBagConstraints.LINE_END; | ||
| 66 | JButton connectButton = new JButton(I18n.translate("prompt.create_server.confirm")); | ||
| 67 | connectButton.addActionListener(event -> confirm()); | ||
| 68 | buttonContainer.add(connectButton, c); | ||
| 69 | c.weightx = 0.0; | ||
| 70 | c.anchor = GridBagConstraints.CENTER; | ||
| 71 | JButton abortButton = new JButton(I18n.translate("prompt.cancel")); | ||
| 72 | abortButton.addActionListener(event -> cancel()); | ||
| 73 | buttonContainer.add(abortButton, c); | ||
| 74 | contentPane.add(buttonContainer, BorderLayout.SOUTH); | ||
| 75 | |||
| 76 | setLocationRelativeTo(owner); | ||
| 77 | setSize(new Dimension(400, 150)); | ||
| 78 | } | ||
| 79 | |||
| 80 | private void confirm() { | ||
| 81 | vc.reset(); | ||
| 82 | validateInputs(); | ||
| 83 | if (vc.canProceed()) { | ||
| 84 | actionConfirm = true; | ||
| 85 | setVisible(false); | ||
| 36 | } | 86 | } |
| 87 | } | ||
| 88 | |||
| 89 | private void cancel() { | ||
| 90 | actionConfirm = false; | ||
| 91 | setVisible(false); | ||
| 92 | } | ||
| 37 | 93 | ||
| 38 | char[] password = passwordField.getPassword(); | 94 | public void validateInputs() { |
| 39 | if (password.length > EnigmaServer.MAX_PASSWORD_LENGTH) { | 95 | vc.setActiveElement(portField); |
| 40 | JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.password.too_long"), I18n.translate("prompt.create_server.title"), JOptionPane.ERROR_MESSAGE); | 96 | StandardValidation.isIntInRange(vc, portField.getText(), 0, 65535); |
| 41 | return null; | 97 | vc.setActiveElement(passwordField); |
| 98 | if (passwordField.getPassword().length > EnigmaServer.MAX_PASSWORD_LENGTH) { | ||
| 99 | vc.raise(Message.FIELD_LENGTH_OUT_OF_RANGE, EnigmaServer.MAX_PASSWORD_LENGTH); | ||
| 42 | } | 100 | } |
| 101 | } | ||
| 102 | |||
| 103 | public Result getResult() { | ||
| 104 | if (!actionConfirm) return null; | ||
| 105 | vc.reset(); | ||
| 106 | validateInputs(); | ||
| 107 | if (!vc.canProceed()) return null; | ||
| 108 | return new Result( | ||
| 109 | Integer.parseInt(portField.getText()), | ||
| 110 | passwordField.getPassword() | ||
| 111 | ); | ||
| 112 | } | ||
| 113 | |||
| 114 | public static Result show(Frame parent) { | ||
| 115 | CreateServerDialog d = new CreateServerDialog(parent); | ||
| 116 | |||
| 117 | d.setVisible(true); | ||
| 118 | Result r = d.getResult(); | ||
| 43 | 119 | ||
| 44 | return new Result(port, password); | 120 | d.dispose(); |
| 121 | return r; | ||
| 45 | } | 122 | } |
| 46 | 123 | ||
| 47 | public static class Result { | 124 | public static class Result { |
diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index bc31f2c..868ebad 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json | |||
| @@ -136,17 +136,15 @@ | |||
| 136 | "prompt.close.cancel": "Cancel", | 136 | "prompt.close.cancel": "Cancel", |
| 137 | "prompt.open": "Open", | 137 | "prompt.open": "Open", |
| 138 | "prompt.cancel": "Cancel", | 138 | "prompt.cancel": "Cancel", |
| 139 | "prompt.connect.title": "Connect to server", | 139 | "prompt.connect.title": "Connect to Server", |
| 140 | "prompt.connect.username": "Username:", | 140 | "prompt.connect.username": "Username:", |
| 141 | "prompt.connect.address": "Address:", | 141 | "prompt.connect.address": "Address:", |
| 142 | "prompt.connect.confirm": "Connect", | 142 | "prompt.connect.confirm": "Connect", |
| 143 | "prompt.connect.cancel": "Cancel", | 143 | "prompt.create_server.title": "Start Server", |
| 144 | "prompt.port": "Port:", | 144 | "prompt.create_server.port": "Port:", |
| 145 | "prompt.port.nan": "Port is not a number", | 145 | "prompt.create_server.confirm": "Start", |
| 146 | "prompt.port.invalid": "Port is out of range, should be between 0-65535", | 146 | "prompt.cancel": "Cancel", |
| 147 | "prompt.password": "Password:", | 147 | "prompt.password": "Password:", |
| 148 | "prompt.password.too_long": "Password is too long, it must be at most 255 characters.", | ||
| 149 | "prompt.create_server.title": "Create server", | ||
| 150 | 148 | ||
| 151 | "disconnect.disconnected": "Disconnected", | 149 | "disconnect.disconnected": "Disconnected", |
| 152 | "disconnect.server_closed": "Server closed", | 150 | "disconnect.server_closed": "Server closed", |
| @@ -167,7 +165,7 @@ | |||
| 167 | "status.ready": "Ready.", | 165 | "status.ready": "Ready.", |
| 168 | 166 | ||
| 169 | "validation.message.empty_field": "This field is required.", | 167 | "validation.message.empty_field": "This field is required.", |
| 170 | "validation.message.invalid_ip": "Invalid IP/Port combination: '%s'.", | 168 | "validation.message.invalid_ip": "Invalid IP/Port combination.", |
| 171 | "validation.message.not_int": "Value must be an integer.", | 169 | "validation.message.not_int": "Value must be an integer.", |
| 172 | "validation.message.field_out_of_range_int": "Value must be an integer between %d and %d.", | 170 | "validation.message.field_out_of_range_int": "Value must be an integer between %d and %d.", |
| 173 | "validation.message.field_length_out_of_range": "Value must be less than %d characters long.", | 171 | "validation.message.field_length_out_of_range": "Value must be less than %d characters long.", |