Bump to version 4.0, finished server dialog data.
This commit is contained in:
parent
71a2cca824
commit
ac8b269fc8
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>ace-of-shades</artifactId>
|
||||
<groupId>nl.andrewlalis</groupId>
|
||||
<version>3.1</version>
|
||||
<version>4.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package nl.andrewlalis.aos_client.launcher;
|
||||
|
||||
import nl.andrewlalis.aos_client.Client;
|
||||
import nl.andrewlalis.aos_client.launcher.servers.ServerInfo;
|
||||
import nl.andrewlalis.aos_client.launcher.servers.ServerInfoCellRenderer;
|
||||
import nl.andrewlalis.aos_client.launcher.servers.ServerInfoListModel;
|
||||
import nl.andrewlalis.aos_client.launcher.servers.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
@ -12,6 +10,7 @@ import java.awt.event.MouseEvent;
|
|||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -22,7 +21,9 @@ import java.util.regex.Pattern;
|
|||
* the menu that the user interacts with before joining a game.
|
||||
*/
|
||||
public class Launcher extends JFrame {
|
||||
private static final Pattern addressPattern = Pattern.compile("(.+):(\\d+)");
|
||||
public static final Pattern addressPattern = Pattern.compile("(.+):(\\d+)");
|
||||
public static final Path DATA_DIR = Path.of(System.getProperty("user.home"), "ace-of-shades");
|
||||
public static final Pattern usernamePattern = Pattern.compile("[a-zA-Z0-9_-]+");
|
||||
|
||||
public Launcher() throws HeadlessException {
|
||||
super("Ace of Shades - Launcher");
|
||||
|
@ -36,9 +37,6 @@ public class Launcher extends JFrame {
|
|||
private Container buildContent() {
|
||||
JTabbedPane mainPanel = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
mainPanel.addTab("Servers", null, this.getServersPanel(), "View a list of available servers.");
|
||||
//
|
||||
// JPanel settingsPanel = new JPanel();
|
||||
// mainPanel.addTab("Settings", null, settingsPanel, "Change game settings.");
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
@ -47,8 +45,6 @@ public class Launcher extends JFrame {
|
|||
JPanel panel = new JPanel(new BorderLayout());
|
||||
|
||||
ServerInfoListModel listModel = new ServerInfoListModel();
|
||||
listModel.add(new ServerInfo("one", "localhost:8035", "andrew"));
|
||||
listModel.add(new ServerInfo("two", "localhost:25565", null));
|
||||
JList<ServerInfo> serversList = new JList<>(listModel);
|
||||
serversList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
serversList.setCellRenderer(new ServerInfoCellRenderer());
|
||||
|
@ -68,8 +64,15 @@ public class Launcher extends JFrame {
|
|||
menu.add(connectItem);
|
||||
JMenuItem editItem = new JMenuItem("Edit");
|
||||
editItem.addActionListener(a -> {
|
||||
// TODO: Open edit dialog.
|
||||
listModel.serverEdited();
|
||||
EditServerDialog dialog = new EditServerDialog((Frame) SwingUtilities.getWindowAncestor(panel), server);
|
||||
dialog.setVisible(true);
|
||||
ServerInfo editedInfo = dialog.getServerInfo();
|
||||
if (editedInfo != null) {
|
||||
server.setName(editedInfo.getName());
|
||||
server.setHost(editedInfo.getHost());
|
||||
server.setUsername(editedInfo.getUsername());
|
||||
listModel.serverEdited();
|
||||
}
|
||||
});
|
||||
menu.add(editItem);
|
||||
JMenuItem removeItem = new JMenuItem("Remove");
|
||||
|
@ -94,7 +97,12 @@ public class Launcher extends JFrame {
|
|||
JButton addServerButton = new JButton("Add Server");
|
||||
addServerButton.setToolTipText("Add a new server to the list.");
|
||||
addServerButton.addActionListener(e -> {
|
||||
// TODO: Add server dialog.
|
||||
AddServerDialog dialog = new AddServerDialog(this);
|
||||
dialog.setVisible(true);
|
||||
ServerInfo server = dialog.getServerInfo();
|
||||
if (server != null) {
|
||||
listModel.add(server);
|
||||
}
|
||||
});
|
||||
buttonPanel.add(addServerButton);
|
||||
JButton directConnectButton = new JButton("Direct Connect");
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package nl.andrewlalis.aos_client.launcher.servers;
|
||||
|
||||
import nl.andrewlalis.aos_client.launcher.Launcher;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AddServerDialog extends JDialog {
|
||||
protected JTextField serverNameField;
|
||||
protected JTextField serverAddressField;
|
||||
protected JTextField usernameField;
|
||||
|
||||
private ServerInfo serverInfo;
|
||||
|
||||
public AddServerDialog(Frame owner) {
|
||||
super(owner, true);
|
||||
this.setTitle("Add Server");
|
||||
this.setContentPane(this.getContent());
|
||||
this.pack();
|
||||
this.setLocationRelativeTo(owner);
|
||||
}
|
||||
|
||||
public ServerInfo getServerInfo() {
|
||||
return this.serverInfo;
|
||||
}
|
||||
|
||||
private Container getContent() {
|
||||
JPanel container = new JPanel(new BorderLayout());
|
||||
JPanel inputPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.insets = new Insets(5, 5, 5, 5);
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
inputPanel.add(new JLabel("Name"), c);
|
||||
serverNameField = new JTextField(20);
|
||||
c.gridx++;
|
||||
inputPanel.add(serverNameField, c);
|
||||
|
||||
c.gridx = 0;
|
||||
c.gridy++;
|
||||
inputPanel.add(new JLabel("Address"), c);
|
||||
serverAddressField = new JTextField(20);
|
||||
c.gridx++;
|
||||
inputPanel.add(serverAddressField, c);
|
||||
|
||||
c.gridy++;
|
||||
c.gridx = 0;
|
||||
inputPanel.add(new JLabel("Username"), c);
|
||||
usernameField = new JTextField(20);
|
||||
c.gridx++;
|
||||
inputPanel.add(usernameField, c);
|
||||
|
||||
container.add(inputPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
JButton cancelButton = new JButton("Cancel");
|
||||
cancelButton.addActionListener(e -> {
|
||||
this.serverInfo = null;
|
||||
this.dispose();
|
||||
});
|
||||
JButton okButton = new JButton("Ok");
|
||||
okButton.addActionListener(e -> {
|
||||
var messages = this.validateInputs();
|
||||
if (!messages.isEmpty()) {
|
||||
String msg = String.join("\n", messages);
|
||||
JOptionPane.showMessageDialog(this, "The information you entered is not valid:\n" + msg, "Invalid Server Data", JOptionPane.WARNING_MESSAGE);
|
||||
} else {
|
||||
String username = this.usernameField.getText();
|
||||
if (username.isBlank()) {
|
||||
username = null;
|
||||
}
|
||||
this.serverInfo = new ServerInfo(this.serverNameField.getText(), this.serverAddressField.getText(), username);
|
||||
this.dispose();
|
||||
}
|
||||
});
|
||||
buttonPanel.add(okButton);
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
container.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private List<String> validateInputs() {
|
||||
String name = this.serverNameField.getText();
|
||||
String address = this.serverAddressField.getText();
|
||||
String username = this.usernameField.getText();
|
||||
List<String> messages = new ArrayList<>();
|
||||
|
||||
if (name == null || name.isBlank()) {
|
||||
messages.add("Server name cannot be blank.");
|
||||
}
|
||||
if (name != null && name.length() > 32) {
|
||||
messages.add("Server name is too long.");
|
||||
}
|
||||
if (address == null || address.isBlank()) {
|
||||
messages.add("Server address cannot be blank.");
|
||||
}
|
||||
if (address != null && !Launcher.addressPattern.matcher(address).matches()) {
|
||||
messages.add("Server address is not properly formatted as HOST:PORT.");
|
||||
}
|
||||
if (username != null && !username.isBlank() && username.length() > 16) {
|
||||
messages.add("Username is too long. Maximum of 16 characters.");
|
||||
}
|
||||
if (username != null && !Launcher.usernamePattern.matcher(username).matches()) {
|
||||
messages.add("Username should contain only letters, numbers, underscores, and hyphens.");
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package nl.andrewlalis.aos_client.launcher.servers;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class EditServerDialog extends AddServerDialog {
|
||||
public EditServerDialog(Frame owner, ServerInfo server) {
|
||||
super(owner);
|
||||
this.setTitle("Edit Server - " + server.getName());
|
||||
this.serverNameField.setText(server.getName());
|
||||
this.serverAddressField.setText(server.getHost());
|
||||
this.usernameField.setText(server.getUsername());
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package nl.andrewlalis.aos_client.launcher.servers;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class ServerInfo implements Comparable<ServerInfo> {
|
||||
public class ServerInfo implements Comparable<ServerInfo>, Serializable {
|
||||
private String name;
|
||||
private String host;
|
||||
private String username;
|
||||
|
|
|
@ -1,15 +1,39 @@
|
|||
package nl.andrewlalis.aos_client.launcher.servers;
|
||||
|
||||
import nl.andrewlalis.aos_client.launcher.Launcher;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Model which represents the list of servers. This model is backed by a file
|
||||
* containing the serialized list, which is updated any time a server is added,
|
||||
* edited, or removed.
|
||||
*/
|
||||
public class ServerInfoListModel extends AbstractListModel<ServerInfo> {
|
||||
public static final Path SERVERS_FILE = Launcher.DATA_DIR.resolve("servers.dat");
|
||||
|
||||
private final List<ServerInfo> servers;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ServerInfoListModel() {
|
||||
this.servers = new ArrayList<>();
|
||||
List<ServerInfo> list = null;
|
||||
if (Files.exists(SERVERS_FILE)) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(SERVERS_FILE))) {
|
||||
list = (ArrayList<ServerInfo>) ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (list == null) list = new ArrayList<>();
|
||||
servers = list;
|
||||
}
|
||||
|
||||
public void add(ServerInfo server) {
|
||||
|
@ -17,6 +41,7 @@ public class ServerInfoListModel extends AbstractListModel<ServerInfo> {
|
|||
this.servers.add(server);
|
||||
this.servers.sort(Comparator.naturalOrder());
|
||||
this.fireContentsChanged(this, 0, this.getSize());
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void remove(ServerInfo server) {
|
||||
|
@ -24,10 +49,12 @@ public class ServerInfoListModel extends AbstractListModel<ServerInfo> {
|
|||
if (index == -1) return;
|
||||
this.servers.remove(index);
|
||||
this.fireIntervalRemoved(this, index, index);
|
||||
this.save();
|
||||
}
|
||||
|
||||
public void serverEdited() {
|
||||
this.fireContentsChanged(this, 0, this.getSize());
|
||||
this.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,4 +66,15 @@ public class ServerInfoListModel extends AbstractListModel<ServerInfo> {
|
|||
public ServerInfo getElementAt(int index) {
|
||||
return this.servers.get(index);
|
||||
}
|
||||
|
||||
private void save() {
|
||||
try {
|
||||
Files.createDirectories(SERVERS_FILE.getParent());
|
||||
ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(SERVERS_FILE));
|
||||
oos.writeObject(this.servers);
|
||||
oos.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>ace-of-shades</artifactId>
|
||||
<groupId>nl.andrewlalis</groupId>
|
||||
<version>3.1</version>
|
||||
<version>4.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -7,7 +7,7 @@
|
|||
<groupId>nl.andrewlalis</groupId>
|
||||
<artifactId>ace-of-shades</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>3.1</version>
|
||||
<version>4.0</version>
|
||||
<modules>
|
||||
<module>server</module>
|
||||
<module>client</module>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<artifactId>ace-of-shades</artifactId>
|
||||
<groupId>nl.andrewlalis</groupId>
|
||||
<version>3.1</version>
|
||||
<version>4.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
|
Loading…
Reference in New Issue