From 493b291dceb20b58b659764db2e4013681c26999 Mon Sep 17 00:00:00 2001 From: 2xsaiko Date: Wed, 22 Apr 2020 20:21:15 +0200 Subject: Improve connect dialog --- .../enigma/gui/dialog/ConnectToServerDialog.java | 163 ++++++++++++++------- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 2 +- .../enigma/gui/elements/VerifiableTextField.java | 61 ++++++++ 3 files changed, 175 insertions(+), 51 deletions(-) create mode 100644 enigma-swing/src/main/java/cuchaz/enigma/gui/elements/VerifiableTextField.java (limited to 'enigma-swing/src/main/java/cuchaz') 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 c5f505cf..070d03d4 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 @@ -1,64 +1,131 @@ package cuchaz.enigma.gui.dialog; +import java.awt.*; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.swing.*; + +import cuchaz.enigma.gui.elements.VerifiableTextField; import cuchaz.enigma.network.EnigmaServer; import cuchaz.enigma.utils.I18n; +import cuchaz.enigma.utils.ServerAddress; -import javax.swing.*; -import java.awt.Frame; - -public class ConnectToServerDialog { - - public static Result show(Frame parentComponent) { - JTextField usernameField = new JTextField(System.getProperty("user.name"), 20); - JPanel usernameRow = new JPanel(); - usernameRow.add(new JLabel(I18n.translate("prompt.connect.username"))); - usernameRow.add(usernameField); - JTextField ipField = new JTextField(20); - JPanel ipRow = new JPanel(); - ipRow.add(new JLabel(I18n.translate("prompt.connect.ip"))); - ipRow.add(ipField); - JTextField portField = new JTextField(String.valueOf(EnigmaServer.DEFAULT_PORT), 10); - JPanel portRow = new JPanel(); - portRow.add(new JLabel(I18n.translate("prompt.port"))); - portRow.add(portField); - JPasswordField passwordField = new JPasswordField(20); - JPanel passwordRow = new JPanel(); - passwordRow.add(new JLabel(I18n.translate("prompt.password"))); - passwordRow.add(passwordField); - - int response = JOptionPane.showConfirmDialog(parentComponent, new Object[]{usernameRow, ipRow, portRow, passwordRow}, I18n.translate("prompt.connect.title"), JOptionPane.OK_CANCEL_OPTION); - if (response != JOptionPane.OK_OPTION) { - return null; +public class ConnectToServerDialog extends JDialog { + + private final JTextField usernameField; + private final VerifiableTextField ipField; + private final JPasswordField passwordField; + private boolean success = false; + + public ConnectToServerDialog(Frame owner) { + super(owner, I18n.translate("prompt.connect.title"), true); + + Container contentPane = getContentPane(); + contentPane.setLayout(new BorderLayout()); + Container inputContainer = new JPanel(new GridBagLayout()); + GridBagConstraints c = new GridBagConstraints(); + usernameField = new JTextField(System.getProperty("user.name")); + ipField = new VerifiableTextField(); + passwordField = new JPasswordField(); + + List labels = Stream.of("prompt.connect.username", "prompt.connect.address", "prompt.password") + .map(I18n::translate) + .map(JLabel::new) + .collect(Collectors.toList()); + List inputs = Arrays.asList(usernameField, ipField, passwordField); + + for (int i = 0; i < inputs.size(); i += 1) { + c.gridy = i; + c.insets = new Insets(4, 4, 4, 4); + + c.gridx = 0; + c.weightx = 0.0; + c.anchor = GridBagConstraints.LINE_END; + c.fill = GridBagConstraints.NONE; + inputContainer.add(labels.get(i), c); + + c.gridx = 1; + c.weightx = 1.0; + c.anchor = GridBagConstraints.LINE_START; + c.fill = GridBagConstraints.HORIZONTAL; + inputs.get(i).addActionListener(event -> confirm()); + inputContainer.add(inputs.get(i), c); } + contentPane.add(inputContainer, BorderLayout.CENTER); + Container buttonContainer = new JPanel(new GridBagLayout()); + c = new GridBagConstraints(); + c.weightx = 1.0; + c.insets = new Insets(4, 4, 4, 4); + c.anchor = GridBagConstraints.LINE_END; + JButton connectButton = new JButton(I18n.translate("prompt.connect.confirm")); + connectButton.addActionListener(event -> confirm()); + buttonContainer.add(connectButton, c); + c.weightx = 0.0; + c.anchor = GridBagConstraints.CENTER; + JButton abortButton = new JButton(I18n.translate("prompt.connect.cancel")); + abortButton.addActionListener(event -> cancel()); + buttonContainer.add(abortButton, c); + contentPane.add(buttonContainer, BorderLayout.SOUTH); + + setLocationRelativeTo(owner); + setSize(new Dimension(400, 185)); + } - String username = usernameField.getText(); - String ip = ipField.getText(); - int port; - try { - port = Integer.parseInt(portField.getText()); - } catch (NumberFormatException e) { - JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.nan"), I18n.translate("prompt.connect.title"), JOptionPane.ERROR_MESSAGE); - return null; + private void confirm() { + if (validateInputs()) { + success = true; + setVisible(false); } - if (port < 0 || port >= 65536) { - JOptionPane.showMessageDialog(parentComponent, I18n.translate("prompt.port.invalid"), I18n.translate("prompt.connect.title"), JOptionPane.ERROR_MESSAGE); - return null; + } + + private void cancel() { + success = false; + setVisible(false); + } + + public boolean validateInputs() { + boolean error = false; + ipField.setErrorState(false); + + if (ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT) == null) { + ipField.setErrorState(true); + error = true; } - char[] password = passwordField.getPassword(); - return new Result(username, ip, port, password); + return !error; + } + + public Result getResult() { + if (!success) return null; + return new Result( + usernameField.getText(), + Objects.requireNonNull(ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT)), + passwordField.getPassword() + ); + } + + public static Result show(Frame parent) { + ConnectToServerDialog d = new ConnectToServerDialog(parent); + + d.setVisible(true); + Result r = d.getResult(); + + d.dispose(); + return r; } public static class Result { private final String username; - private final String ip; - private final int port; + private final ServerAddress address; private final char[] password; - public Result(String username, String ip, int port, char[] password) { + public Result(String username, ServerAddress address, char[] password) { this.username = username; - this.ip = ip; - this.port = port; + this.address = address; this.password = password; } @@ -66,12 +133,8 @@ public class ConnectToServerDialog { return username; } - public String getIp() { - return ip; - } - - public int getPort() { - return port; + public ServerAddress getAddress() { + return address; } public char[] getPassword() { diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 3378d1a4..1481a9dc 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -227,7 +227,7 @@ public class MenuBar { } this.gui.getController().disconnectIfConnected(null); try { - this.gui.getController().createClient(result.getUsername(), result.getIp(), result.getPort(), result.getPassword()); + this.gui.getController().createClient(result.getUsername(), result.getAddress().address, result.getAddress().port, result.getPassword()); } catch (IOException e) { JOptionPane.showMessageDialog(this.gui.getFrame(), e.toString(), I18n.translate("menu.collab.connect.error"), JOptionPane.ERROR_MESSAGE); this.gui.getController().disconnectIfConnected(null); diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/VerifiableTextField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/VerifiableTextField.java new file mode 100644 index 00000000..41a24840 --- /dev/null +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/VerifiableTextField.java @@ -0,0 +1,61 @@ +package cuchaz.enigma.gui.elements; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; + +import javax.swing.JTextField; +import javax.swing.text.Document; + +public class VerifiableTextField extends JTextField { + + private boolean hasError; + + public VerifiableTextField() { + } + + public VerifiableTextField(String text) { + super(text); + } + + public VerifiableTextField(int columns) { + super(columns); + } + + public VerifiableTextField(String text, int columns) { + super(text, columns); + } + + public VerifiableTextField(Document doc, String text, int columns) { + super(doc, text, columns); + } + + { + addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + setErrorState(false); + } + }); + } + + public void setErrorState(boolean b) { + this.hasError = b; + repaint(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (hasError) { + g.setColor(Color.RED); + int x1 = getWidth() - 9; + int x2 = getWidth() - 2; + int y1 = 1; + int y2 = 8; + g.fillPolygon(new int[]{x1, x2, x2}, new int[]{y1, y1, y2}, 3); + } + } + +} -- cgit v1.2.3