diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java index fd8a6d3..11d242e 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/Main.java @@ -106,10 +106,10 @@ public class Main { } boolean runningNew = serversRunning(); if (!runningNew && serversAreRunning) { - gui.updateRunning(false); + gui.updateGUIElementsWhenServersStartOrStop(false); gui.setStatus("Servers are stopped"); } else if (runningNew && !serversAreRunning) { - gui.updateRunning(true); + gui.updateGUIElementsWhenServersStartOrStop(true); } serversAreRunning = runningNew; } catch (Exception e) { diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java index b9e6aa4..4a1d82d 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Controller.java @@ -230,7 +230,7 @@ public class Controller { */ private void executeGUILoadingTasks() { this.serverLauncherGUI.updateProfiles(); - this.serverLauncherGUI.update(); + this.serverLauncherGUI.updateWithSavedProfileData(); this.currentProfile.updateConsoles(); if (this.downloadAllJars) { Executors.newSingleThreadExecutor().execute(() -> { @@ -244,7 +244,7 @@ public class Controller { } if (this.currentProfile.getRunInBackground()) { Executors.newSingleThreadExecutor().execute(Server::startServers); - this.serverLauncherGUI.hide(); + this.serverLauncherGUI.hideToTray(); } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java index 5c2b075..b100d03 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/profile/Profile.java @@ -159,7 +159,7 @@ public class Profile { for (int i = 0; i < collections.size(); i++) { if (collections.get(i).getName().equals(name)) { this.collections.remove(i); - serverLauncherGui.update(); + serverLauncherGui.updateWithSavedProfileData(); break; } } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java index 3348269..dbc77d5 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/server/Server.java @@ -137,7 +137,7 @@ public class Server { } catch (IOException e) { e.printStackTrace(); } - controller.getGUI().updateRunning(false); + controller.getGUI().updateGUIElementsWhenServersStartOrStop(false); return; } } @@ -323,7 +323,7 @@ public class Server { */ public void addPlayer(String name) { this.playerList.add(name); - Main.getController().getGUI().addPlayer(name); + Main.getController().getGUI().getServerControlTab().addPlayer(name); } /** @@ -333,7 +333,7 @@ public class Server { */ public void removePlayer(String name) { playerList.removeIf(player -> player.equals(name)); - Main.getController().getGUI().removePlayer(name); + Main.getController().getGUI().getServerControlTab().removePlayer(name); } /** diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerControlTab.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerControlTab.java new file mode 100644 index 0000000..cae7a4e --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerControlTab.java @@ -0,0 +1,273 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +import net.knarcraft.minecraftserverlauncher.profile.Collection; +import net.knarcraft.minecraftserverlauncher.profile.Controller; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +/** + * This class takes care of all server controls on the server control tab + */ +public class ServerControlTab implements ActionListener { + + private JComboBox targetServerCombo; + private JComboBox targetPlayerCombo; + private JButton kickButton; + private JButton banButton; + private JButton opButton; + private JButton deopButton; + private JButton customCommandButton; + private JButton saveServerButton; + private JButton reloadButton; + private JButton showConsolesButton; + private JTextField customCommandTextField; + + private Controller controller = Controller.getInstance(); + private final ArrayList globalPlayers; + + /** + * Instantiates a new server control tab + * + * @param mainFrame

The main frame of the GUI

+ * @param controlServers

The JPanel to attach the server controls to

+ */ + public ServerControlTab(JFrame mainFrame, JPanel controlServers) { + this.globalPlayers = new ArrayList<>(); + initialize(mainFrame, controlServers); + } + + /** + * Initializes GUI elements for the server control tab + * + * @param mainFrame

The main frame of the GUI

+ * @param controlServers

The JPanel to attach the server controls to

+ */ + private void initialize(JFrame mainFrame, JPanel controlServers) { + SpringLayout springLayout = new SpringLayout(); + controlServers.setLayout(springLayout); + targetServerCombo = new JComboBox<>(); + springLayout.putConstraint(SpringLayout.NORTH, targetServerCombo, 10, SpringLayout.NORTH, controlServers); + controlServers.add(targetServerCombo); + targetServerCombo.addActionListener(this); + + targetPlayerCombo = new JComboBox<>(); + springLayout.putConstraint(SpringLayout.NORTH, targetPlayerCombo, 6, SpringLayout.SOUTH, targetServerCombo); + targetPlayerCombo.setEditable(true); + controlServers.add(targetPlayerCombo); + + kickButton = new JButton("Kick"); + springLayout.putConstraint(SpringLayout.NORTH, kickButton, 10, SpringLayout.NORTH, controlServers); + springLayout.putConstraint(SpringLayout.WEST, kickButton, 6, SpringLayout.EAST, targetServerCombo); + springLayout.putConstraint(SpringLayout.EAST, kickButton, 104, SpringLayout.WEST, kickButton); + springLayout.putConstraint(SpringLayout.SOUTH, targetServerCombo, 0, SpringLayout.SOUTH, kickButton); + controlServers.add(kickButton); + kickButton.addActionListener(this); + + banButton = new JButton("Ban"); + springLayout.putConstraint(SpringLayout.NORTH, banButton, 6, SpringLayout.SOUTH, kickButton); + springLayout.putConstraint(SpringLayout.WEST, banButton, 6, SpringLayout.EAST, targetPlayerCombo); + springLayout.putConstraint(SpringLayout.EAST, banButton, 104, SpringLayout.WEST, banButton); + springLayout.putConstraint(SpringLayout.SOUTH, targetPlayerCombo, 0, SpringLayout.SOUTH, banButton); + controlServers.add(banButton); + banButton.addActionListener(this); + + opButton = new JButton("OP"); + springLayout.putConstraint(SpringLayout.NORTH, opButton, 10, SpringLayout.NORTH, controlServers); + springLayout.putConstraint(SpringLayout.WEST, opButton, 6, SpringLayout.EAST, kickButton); + springLayout.putConstraint(SpringLayout.EAST, opButton, -10, SpringLayout.EAST, controlServers); + controlServers.add(opButton); + opButton.addActionListener(this); + + deopButton = new JButton("DEOP"); + springLayout.putConstraint(SpringLayout.WEST, deopButton, 6, SpringLayout.EAST, banButton); + springLayout.putConstraint(SpringLayout.NORTH, deopButton, 5, SpringLayout.SOUTH, opButton); + springLayout.putConstraint(SpringLayout.EAST, deopButton, -10, SpringLayout.EAST, controlServers); + controlServers.add(deopButton); + deopButton.addActionListener(this); + + JLabel lblTargetServer = new JLabel("Target server"); + springLayout.putConstraint(SpringLayout.WEST, targetServerCombo, 6, SpringLayout.EAST, lblTargetServer); + springLayout.putConstraint(SpringLayout.EAST, targetServerCombo, 121, SpringLayout.EAST, lblTargetServer); + springLayout.putConstraint(SpringLayout.NORTH, lblTargetServer, 10, SpringLayout.NORTH, controlServers); + springLayout.putConstraint(SpringLayout.SOUTH, lblTargetServer, 0, SpringLayout.SOUTH, targetServerCombo); + springLayout.putConstraint(SpringLayout.WEST, lblTargetServer, 10, SpringLayout.WEST, controlServers); + controlServers.add(lblTargetServer); + + JLabel lblTargetPlayer = new JLabel("Target player"); + springLayout.putConstraint(SpringLayout.WEST, targetPlayerCombo, 7, SpringLayout.EAST, lblTargetPlayer); + springLayout.putConstraint(SpringLayout.EAST, targetPlayerCombo, 122, SpringLayout.EAST, lblTargetPlayer); + springLayout.putConstraint(SpringLayout.NORTH, lblTargetPlayer, 6, SpringLayout.SOUTH, lblTargetServer); + springLayout.putConstraint(SpringLayout.SOUTH, lblTargetPlayer, 0, SpringLayout.SOUTH, targetPlayerCombo); + springLayout.putConstraint(SpringLayout.WEST, lblTargetPlayer, 0, SpringLayout.WEST, lblTargetServer); + controlServers.add(lblTargetPlayer); + + customCommandButton = new JButton("Custom command"); + springLayout.putConstraint(SpringLayout.WEST, customCommandButton, 250, SpringLayout.WEST, controlServers); + springLayout.putConstraint(SpringLayout.EAST, customCommandButton, 0, SpringLayout.EAST, opButton); + controlServers.add(customCommandButton); + customCommandButton.addActionListener(this); + mainFrame.getRootPane().setDefaultButton(customCommandButton); + + customCommandTextField = new JTextField(); + springLayout.putConstraint(SpringLayout.WEST, customCommandTextField, 10, SpringLayout.WEST, controlServers); + springLayout.putConstraint(SpringLayout.EAST, customCommandTextField, -6, SpringLayout.WEST, customCommandButton); + springLayout.putConstraint(SpringLayout.NORTH, customCommandButton, 0, SpringLayout.NORTH, customCommandTextField); + springLayout.putConstraint(SpringLayout.SOUTH, customCommandTextField, 0, SpringLayout.SOUTH, customCommandButton); + controlServers.add(customCommandTextField); + customCommandTextField.setColumns(10); + + saveServerButton = new JButton("Save server"); + springLayout.putConstraint(SpringLayout.NORTH, customCommandTextField, 6, SpringLayout.SOUTH, saveServerButton); + springLayout.putConstraint(SpringLayout.NORTH, saveServerButton, 6, SpringLayout.SOUTH, banButton); + springLayout.putConstraint(SpringLayout.WEST, saveServerButton, 0, SpringLayout.WEST, kickButton); + springLayout.putConstraint(SpringLayout.EAST, saveServerButton, 104, SpringLayout.WEST, kickButton); + springLayout.putConstraint(SpringLayout.EAST, saveServerButton, 104, SpringLayout.WEST, kickButton); + controlServers.add(saveServerButton); + saveServerButton.addActionListener(this); + + reloadButton = new JButton("Reload"); + springLayout.putConstraint(SpringLayout.NORTH, reloadButton, 6, SpringLayout.SOUTH, deopButton); + springLayout.putConstraint(SpringLayout.WEST, reloadButton, 0, SpringLayout.WEST, deopButton); + springLayout.putConstraint(SpringLayout.EAST, reloadButton, 0, SpringLayout.EAST, opButton); + controlServers.add(reloadButton); + reloadButton.addActionListener(this); + + showConsolesButton = new JButton("View server consoles"); + springLayout.putConstraint(SpringLayout.NORTH, showConsolesButton, 0, SpringLayout.NORTH, saveServerButton); + springLayout.putConstraint(SpringLayout.WEST, showConsolesButton, 0, SpringLayout.WEST, lblTargetServer); + springLayout.putConstraint(SpringLayout.EAST, showConsolesButton, 0, SpringLayout.EAST, targetServerCombo); + controlServers.add(showConsolesButton); + showConsolesButton.addActionListener(this); + } + + /** + * Updates available servers according to existing collections + */ + public void update() { + this.targetServerCombo.removeAllItems(); + this.targetServerCombo.addItem("All"); + for (Collection collection : Controller.getInstance().getCurrentProfile().getCollections()) { + this.targetServerCombo.addItem(collection.getName()); + } + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + //Registers actions on the server control tab + handleServerControlTabButtons(actionEvent.getSource()); + } + + /** + * Handles buttons and combos on the server control tab + * + * @param actionSource

The object being interacted with

+ */ + private void handleServerControlTabButtons(Object actionSource) { + String selectedServerValue = null; + String selectedPlayerValue = null; + Object selectedServer = targetServerCombo.getSelectedItem(); + if (selectedServer != null) { + selectedServerValue = selectedServer.toString(); + } + Object selectedPlayer = targetPlayerCombo.getSelectedItem(); + if (selectedPlayer != null) { + selectedPlayerValue = selectedPlayer.toString(); + } + //Register actions on all commands executed on a specific player + handlePlayerCommands(actionSource, selectedServerValue, selectedPlayerValue); + //Registers actions on all commands executed on a specific server + handleServerCommands(actionSource, selectedServerValue); + + if (actionSource == showConsolesButton) { + ServerConsoles.setAsVisible(); + } else if (actionSource == targetServerCombo) { + updatePlayers(); + } + } + + /** + * Updates the list of players currently online on the selected server + */ + private void updatePlayers() { + String selectedServerValue; + Object selectedServer = targetServerCombo.getSelectedItem(); + if (selectedServer != null) { + targetPlayerCombo.removeAllItems(); + selectedServerValue = selectedServer.toString(); + if (selectedServerValue.equals("All")) { + for (String player : this.globalPlayers) { + targetPlayerCombo.addItem(player); + } + } else { + for (String player : controller.getCurrentProfile().getCollection(selectedServerValue).getServer().getPlayers()) { + targetPlayerCombo.addItem(player); + } + } + } + } + + /** + * Adds a player to the global player list, and updates the players combo + * + * @param name

The name of the player to add

+ */ + public void addPlayer(String name) { + this.globalPlayers.add(name); + this.updatePlayers(); + } + + /** + * Removes a player from the global list of players + * + * @param name

The name of the player to remove

+ */ + public void removePlayer(String name) { + globalPlayers.removeIf(playerName -> playerName.equals(name)); + this.updatePlayers(); + } + + /** + * Handles command buttons acting on a specific server + * + * @param actionSource

The object being interacted with

+ * @param selectedServerValue

The server currently selected

+ */ + private void handleServerCommands(Object actionSource, String selectedServerValue) { + if (selectedServerValue == null) { + return; + } + if (actionSource == customCommandButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, customCommandTextField.getText()); + customCommandTextField.setText(""); + } else if (actionSource == saveServerButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "save-all"); + } else if (actionSource == reloadButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "reload"); + } + } + + /** + * Handles command buttons which act on a player + * + * @param actionSource

The clicked object

+ * @param selectedServerValue

The server currently selected

+ * @param selectedPlayerValue

The player currently selected

+ */ + private void handlePlayerCommands(Object actionSource, String selectedServerValue, String selectedPlayerValue) { + if (selectedServerValue == null || selectedPlayerValue == null) { + return; + } + if (actionSource == kickButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); + } else if (actionSource == banButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); + } else if (actionSource == opButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "op " + selectedPlayerValue); + } else if (actionSource == deopButton) { + controller.getCurrentProfile().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); + } + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java index 76fdc0b..9aef608 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherGUI.java @@ -3,7 +3,6 @@ package net.knarcraft.minecraftserverlauncher.userinterface; import net.knarcraft.minecraftserverlauncher.Main; import net.knarcraft.minecraftserverlauncher.profile.Collection; import net.knarcraft.minecraftserverlauncher.profile.Controller; -import net.knarcraft.minecraftserverlauncher.profile.Profile; import net.knarcraft.minecraftserverlauncher.server.Server; import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; @@ -36,31 +35,16 @@ import static net.knarcraft.minecraftserverlauncher.utility.CommonFunctions.getR public class ServerLauncherGUI extends MessageHandler implements ActionListener, GUI { private final JLabel lblStatuslabel = new JLabel("Servers are stopped"); - private final ArrayList globalPlayers; private Controller controller; private Map textStrings; + private Tray applicationTray; private JFrame frame; private JTabbedPane tabbedPane; private JTabbedPane serversPane; - /******* - * Menu - ********/ - //Options - private JCheckBoxMenuItem runInBackgroundCheckBoxMenuItem; - private JCheckBoxMenuItem delayStartupCheckBoxMenuItem; - private JCheckBoxMenuItem downloadJarsCheckBoxMenuItem; - //Help - private JMenuItem errorsMenuItem; - private JMenuItem setupMenuItem; - private JMenuItem manualUpdateMenuItem; - //Info/options - private JMenuItem runInBackgroundMenuItem; - private JMenuItem delayStartupMenuItem; - private JMenuItem downloadJarsMenuItem; - //Info/about - private JMenuItem aboutMenuItem; - private JMenuItem storyMenuItem; + private ServerControlTab serverControlTab; + private ServerLauncherMenu serverLauncherMenu; + //Basic controls private JButton startServerButton; private JButton stopServerButton; @@ -69,21 +53,6 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, private JButton addProfileButton; private JButton deleteProfileButton; private JComboBox profiles; - //Server controls - private JComboBox targetServerCombo; - private JComboBox targetPlayerCombo; - private JButton kickButton; - private JButton banButton; - private JButton opButton; - private JButton deopButton; - private JButton customCommandButton; - private JButton saveServerButton; - private JButton reloadButton; - private JButton showConsolesButton; - private JTextField customCommandTextField; - //Tray - private SystemTray tray; - private TrayIcon trayIcon; /** * Creates the application window @@ -93,7 +62,6 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, initialize(440, 170); loadMessages(); this.controller = Main.getController(); - this.globalPlayers = new ArrayList<>(); } /** @@ -107,7 +75,6 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, initialize(width, height); loadMessages(); this.controller = Main.getController(); - this.globalPlayers = new ArrayList<>(); } /** @@ -122,7 +89,8 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, @Override public void setStatus(String text) { this.lblStatuslabel.setText(text); - try (PrintWriter file = new PrintWriter(new FileWriter(Main.getApplicationWorkDirectory() + File.separator + "latestrun.log", true))) { + try (PrintWriter file = new PrintWriter(new FileWriter(Main.getApplicationWorkDirectory() + + File.separator + "latestrun.log", true))) { file.println(text); } catch (IOException e) { e.printStackTrace(); @@ -144,26 +112,6 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, return chooser.getSelectedFile(); } - /** - * Adds a player to the global player list, and updates the players combo - * - * @param name

The name of the player to add

- */ - public void addPlayer(String name) { - this.globalPlayers.add(name); - this.updatePlayers(); - } - - /** - * Removes a player from the global list of players - * - * @param name

The name of the player to remove

- */ - public void removePlayer(String name) { - globalPlayers.removeIf(playerName -> playerName.equals(name)); - this.updatePlayers(); - } - /** * Updates the profiles combo */ @@ -176,6 +124,15 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, this.profiles.setSelectedItem(selectedProfile); } + /** + * Gets the server control tab used by this GUI + * + * @return

The server control tab used by this GUI

+ */ + public ServerControlTab getServerControlTab() { + return this.serverControlTab; + } + /** * Gets the size of the main JFrame * @@ -188,22 +145,22 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, /** * Updates ServerLauncherGUI according to current profile settings */ - public void update() { + public void updateWithSavedProfileData() { Controller controller = Main.getController(); serversPane.removeAll(); - runInBackgroundCheckBoxMenuItem.setState(controller.getRunInBackground()); - delayStartupCheckBoxMenuItem.setState(controller.getDelayStartup() > 0); - downloadJarsCheckBoxMenuItem.setState(controller.getDownloadAllJars()); - this.targetServerCombo.removeAllItems(); - this.targetServerCombo.addItem("All"); + serverLauncherMenu.update(); + serverControlTab.update(); for (Collection collection : controller.getCurrentProfile().getCollections()) { serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); - this.targetServerCombo.addItem(collection.getName()); } } /** - * Creates the ServerLauncherGUI + * Initializes the server launcher GUI + * + * @param width

The width of the GUI

+ * @param height

The height of the GUI

+ * @throws IOException

If unable to load the GUI icon

*/ private void initialize(int width, int height) throws IOException { try { @@ -227,64 +184,7 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, JMenuBar menuBar = new JMenuBar(); frame.setJMenuBar(menuBar); - JMenu mnOptions = new JMenu("Options"); - menuBar.add(mnOptions); - - runInBackgroundCheckBoxMenuItem = new JCheckBoxMenuItem("Run in background on exit"); - mnOptions.add(runInBackgroundCheckBoxMenuItem); - runInBackgroundCheckBoxMenuItem.addActionListener(this); - - delayStartupCheckBoxMenuItem = new JCheckBoxMenuItem("Delay Startup"); - mnOptions.add(delayStartupCheckBoxMenuItem); - delayStartupCheckBoxMenuItem.addActionListener(this); - - downloadJarsCheckBoxMenuItem = new JCheckBoxMenuItem("Download jars"); - mnOptions.add(downloadJarsCheckBoxMenuItem); - downloadJarsCheckBoxMenuItem.addActionListener(this); - - JMenu mnHelp = new JMenu("Help"); - menuBar.add(mnHelp); - - errorsMenuItem = new JMenuItem("Errors"); - mnHelp.add(errorsMenuItem); - errorsMenuItem.addActionListener(this); - - setupMenuItem = new JMenuItem("Setup"); - mnHelp.add(setupMenuItem); - setupMenuItem.addActionListener(this); - - manualUpdateMenuItem = new JMenuItem("Manual update"); - mnHelp.add(manualUpdateMenuItem); - manualUpdateMenuItem.addActionListener(this); - - JMenu mnInfo = new JMenu("Info"); - menuBar.add(mnInfo); - - JMenu mnOptionsInfo = new JMenu("Options"); - mnInfo.add(mnOptionsInfo); - - runInBackgroundMenuItem = new JMenuItem("Run in background on exit"); - mnOptionsInfo.add(runInBackgroundMenuItem); - runInBackgroundMenuItem.addActionListener(this); - - delayStartupMenuItem = new JMenuItem("Delay Startup"); - mnOptionsInfo.add(delayStartupMenuItem); - delayStartupMenuItem.addActionListener(this); - - downloadJarsMenuItem = new JMenuItem("Download jars"); - mnOptionsInfo.add(downloadJarsMenuItem); - downloadJarsMenuItem.addActionListener(this); - - JMenu mnAbout = new JMenu("About"); - mnInfo.add(mnAbout); - - aboutMenuItem = new JMenuItem("About"); - mnAbout.add(aboutMenuItem); - aboutMenuItem.addActionListener(this); - - storyMenuItem = new JMenuItem("Story"); - mnAbout.add(storyMenuItem); - storyMenuItem.addActionListener(this); + this.serverLauncherMenu = new ServerLauncherMenu(menuBar, this); tabbedPane = new JTabbedPane(JTabbedPane.TOP); frame.getContentPane().add(tabbedPane); @@ -355,102 +255,9 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, JPanel controlServers = new JPanel(); tabbedPane.addTab("Control servers", null, controlServers, null); - SpringLayout sl_panel_1 = new SpringLayout(); - controlServers.setLayout(sl_panel_1); - targetServerCombo = new JComboBox<>(); - sl_panel_1.putConstraint(SpringLayout.NORTH, targetServerCombo, 10, SpringLayout.NORTH, controlServers); - controlServers.add(targetServerCombo); - targetServerCombo.addActionListener(this); + serverControlTab = new ServerControlTab(frame, controlServers); - targetPlayerCombo = new JComboBox<>(); - sl_panel_1.putConstraint(SpringLayout.NORTH, targetPlayerCombo, 6, SpringLayout.SOUTH, targetServerCombo); - targetPlayerCombo.setEditable(true); - controlServers.add(targetPlayerCombo); - - kickButton = new JButton("Kick"); - sl_panel_1.putConstraint(SpringLayout.NORTH, kickButton, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.WEST, kickButton, 6, SpringLayout.EAST, targetServerCombo); - sl_panel_1.putConstraint(SpringLayout.EAST, kickButton, 104, SpringLayout.WEST, kickButton); - sl_panel_1.putConstraint(SpringLayout.SOUTH, targetServerCombo, 0, SpringLayout.SOUTH, kickButton); - controlServers.add(kickButton); - kickButton.addActionListener(this); - - banButton = new JButton("Ban"); - sl_panel_1.putConstraint(SpringLayout.NORTH, banButton, 6, SpringLayout.SOUTH, kickButton); - sl_panel_1.putConstraint(SpringLayout.WEST, banButton, 6, SpringLayout.EAST, targetPlayerCombo); - sl_panel_1.putConstraint(SpringLayout.EAST, banButton, 104, SpringLayout.WEST, banButton); - sl_panel_1.putConstraint(SpringLayout.SOUTH, targetPlayerCombo, 0, SpringLayout.SOUTH, banButton); - controlServers.add(banButton); - banButton.addActionListener(this); - - opButton = new JButton("OP"); - sl_panel_1.putConstraint(SpringLayout.NORTH, opButton, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.WEST, opButton, 6, SpringLayout.EAST, kickButton); - sl_panel_1.putConstraint(SpringLayout.EAST, opButton, -10, SpringLayout.EAST, controlServers); - controlServers.add(opButton); - opButton.addActionListener(this); - - deopButton = new JButton("DEOP"); - sl_panel_1.putConstraint(SpringLayout.WEST, deopButton, 6, SpringLayout.EAST, banButton); - sl_panel_1.putConstraint(SpringLayout.NORTH, deopButton, 5, SpringLayout.SOUTH, opButton); - sl_panel_1.putConstraint(SpringLayout.EAST, deopButton, -10, SpringLayout.EAST, controlServers); - controlServers.add(deopButton); - deopButton.addActionListener(this); - - JLabel lblTargetServer = new JLabel("Target server"); - sl_panel_1.putConstraint(SpringLayout.WEST, targetServerCombo, 6, SpringLayout.EAST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.EAST, targetServerCombo, 121, SpringLayout.EAST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetServer, 10, SpringLayout.NORTH, controlServers); - sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetServer, 0, SpringLayout.SOUTH, targetServerCombo); - sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetServer, 10, SpringLayout.WEST, controlServers); - controlServers.add(lblTargetServer); - - JLabel lblTargetPlayer = new JLabel("Target player"); - sl_panel_1.putConstraint(SpringLayout.WEST, targetPlayerCombo, 7, SpringLayout.EAST, lblTargetPlayer); - sl_panel_1.putConstraint(SpringLayout.EAST, targetPlayerCombo, 122, SpringLayout.EAST, lblTargetPlayer); - sl_panel_1.putConstraint(SpringLayout.NORTH, lblTargetPlayer, 6, SpringLayout.SOUTH, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.SOUTH, lblTargetPlayer, 0, SpringLayout.SOUTH, targetPlayerCombo); - sl_panel_1.putConstraint(SpringLayout.WEST, lblTargetPlayer, 0, SpringLayout.WEST, lblTargetServer); - controlServers.add(lblTargetPlayer); - - customCommandButton = new JButton("Custom command"); - sl_panel_1.putConstraint(SpringLayout.WEST, customCommandButton, 250, SpringLayout.WEST, controlServers); - sl_panel_1.putConstraint(SpringLayout.EAST, customCommandButton, 0, SpringLayout.EAST, opButton); - controlServers.add(customCommandButton); - customCommandButton.addActionListener(this); - frame.getRootPane().setDefaultButton(customCommandButton); - - customCommandTextField = new JTextField(); - sl_panel_1.putConstraint(SpringLayout.WEST, customCommandTextField, 10, SpringLayout.WEST, controlServers); - sl_panel_1.putConstraint(SpringLayout.EAST, customCommandTextField, -6, SpringLayout.WEST, customCommandButton); - sl_panel_1.putConstraint(SpringLayout.NORTH, customCommandButton, 0, SpringLayout.NORTH, customCommandTextField); - sl_panel_1.putConstraint(SpringLayout.SOUTH, customCommandTextField, 0, SpringLayout.SOUTH, customCommandButton); - controlServers.add(customCommandTextField); - customCommandTextField.setColumns(10); - - saveServerButton = new JButton("Save server"); - sl_panel_1.putConstraint(SpringLayout.NORTH, customCommandTextField, 6, SpringLayout.SOUTH, saveServerButton); - sl_panel_1.putConstraint(SpringLayout.NORTH, saveServerButton, 6, SpringLayout.SOUTH, banButton); - sl_panel_1.putConstraint(SpringLayout.WEST, saveServerButton, 0, SpringLayout.WEST, kickButton); - sl_panel_1.putConstraint(SpringLayout.EAST, saveServerButton, 104, SpringLayout.WEST, kickButton); - sl_panel_1.putConstraint(SpringLayout.EAST, saveServerButton, 104, SpringLayout.WEST, kickButton); - controlServers.add(saveServerButton); - saveServerButton.addActionListener(this); - - reloadButton = new JButton("Reload"); - sl_panel_1.putConstraint(SpringLayout.NORTH, reloadButton, 6, SpringLayout.SOUTH, deopButton); - sl_panel_1.putConstraint(SpringLayout.WEST, reloadButton, 0, SpringLayout.WEST, deopButton); - sl_panel_1.putConstraint(SpringLayout.EAST, reloadButton, 0, SpringLayout.EAST, opButton); - controlServers.add(reloadButton); - reloadButton.addActionListener(this); - - showConsolesButton = new JButton("View server consoles"); - sl_panel_1.putConstraint(SpringLayout.NORTH, showConsolesButton, 0, SpringLayout.NORTH, saveServerButton); - sl_panel_1.putConstraint(SpringLayout.WEST, showConsolesButton, 0, SpringLayout.WEST, lblTargetServer); - sl_panel_1.putConstraint(SpringLayout.EAST, showConsolesButton, 0, SpringLayout.EAST, targetServerCombo); - controlServers.add(showConsolesButton); - showConsolesButton.addActionListener(this); JPanel panel_2 = new JPanel(); tabbedPane.addTab("Servers", null, panel_2, null); @@ -470,204 +277,97 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, frame.validate(); frame.pack(); frame.setVisible(true); - tray(); - updateRunning(false); + applicationTray = new Tray(frame, this); + updateGUIElementsWhenServersStartOrStop(false); } /** - * Prepares the system tray if available + * Hides the GUI to the system tray */ - private void tray() { - if (SystemTray.isSupported()) { - tray = SystemTray.getSystemTray(); - InputStream imageStream = CommonFunctions.getResourceAsStream("GUIIcon.png"); - Image trayImage; - try { - trayImage = ImageIO.read(imageStream); - } catch (IOException e) { - trayImage = Toolkit.getDefaultToolkit().getImage("resources/GUIIcon.png"); - e.printStackTrace(); - } - PopupMenu popup = new PopupMenu(); - trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup); - trayIcon.setImageAutoSize(true); - ActionListener exitListener = e -> { - stop(); - controller.saveState(); - System.exit(0); - }; + public void hideToTray() { + applicationTray.hideToTray(); + } - MenuItem restoreItem = new MenuItem("Restore"); - popup.add(restoreItem); - restoreItem.addActionListener(e -> { - frame.setExtendedState(NORMAL); - tray.remove(trayIcon); - frame.setVisible(true); - }); - MenuItem exitItem = new MenuItem("Exit"); - exitItem.addActionListener(exitListener); - popup.add(exitItem); - frame.addWindowStateListener(e -> { - if (e.getNewState() == NORMAL) { - tray.remove(trayIcon); - frame.setVisible(true); - } - }); - - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - if (controller.getRunInBackground() && SystemTray.isSupported()) { - try { - tray.add(trayIcon); - frame.setVisible(false); - } catch (AWTException e1) { - e1.printStackTrace(); - } - } else { - stop(); - controller.saveState(); - System.exit(0); - } - } - }); - - trayIcon.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - if (e.getClickCount() >= 1 && e.getButton() == MouseEvent.BUTTON1) { - frame.setExtendedState(NORMAL); - tray.remove(trayIcon); - frame.setVisible(true); - } - } - }); + /** + * Gets the currently selected profile + * + * @return

The currently selected profile or null

+ */ + public String getSelectedProfile() { + Object selectedProfile = profiles.getSelectedItem(); + if (selectedProfile != null) { + return selectedProfile.toString(); } else { - frame.addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - controller.saveState(); - stop(); - System.exit(0); - } - }); + return null; } - } - /** - * Hides the gui to the tray - */ - public void hide() { - frame.setVisible(false); - try { - tray.add(trayIcon); - } catch (AWTException e) { - e.printStackTrace(); - } } @Override public void actionPerformed(ActionEvent e) { - String selectedServerValue = null, selectedPlayerValue = null; - Object selectedServer = targetServerCombo.getSelectedItem(); - if (selectedServer != null) { - selectedServerValue = selectedServer.toString(); - } - Object selectedPlayer = targetPlayerCombo.getSelectedItem(); - if (selectedPlayer != null) { - selectedPlayerValue = selectedPlayer.toString(); - } - if (e.getSource() == runInBackgroundCheckBoxMenuItem) { - background(); - } else if (e.getSource() == delayStartupCheckBoxMenuItem) { - delay(); - } else if (e.getSource() == downloadJarsCheckBoxMenuItem) { - downloadJars(); - } else if (e.getSource() == errorsMenuItem) { - CommonFunctions.goToURL(textStrings.get("infoURL")); - } else if (e.getSource() == setupMenuItem) { - showMessage("Setup", textStrings.get("setupText")); - } else if (e.getSource() == manualUpdateMenuItem) { - CommonFunctions.goToURL(textStrings.get("manualUpdateURL")); - } else if (e.getSource() == runInBackgroundMenuItem) { - showMessage("Run in background", textStrings.get("runInBackgroundText")); - } else if (e.getSource() == delayStartupMenuItem) { - showMessage("Delay startup", textStrings.get("delayStartupText")); - } else if (e.getSource() == downloadJarsMenuItem) { - showMessage("Download jars", textStrings.get("downloadJarsText")); - } else if (e.getSource() == aboutMenuItem) { - showMessage("About", textStrings.get("aboutText")); - } else if (e.getSource() == storyMenuItem) { - CommonFunctions.goToURL(textStrings.get("storyURL")); - } else if (e.getSource() == startServerButton) { + Object actionSource = e.getSource(); + //Registers actions on the main tab + handleMainTabButtons(actionSource); + } + + + + /** + * Handles buttons and the combo on the main tab + * + * @param actionSource

The object being interacted with

+ */ + private void handleMainTabButtons(Object actionSource) { + if (actionSource == startServerButton) { controller.saveState(); Executors.newSingleThreadExecutor().execute(Server::startServers); - } else if (e.getSource() == stopServerButton) { - stop(); - } else if (e.getSource() == addServerButton) { - String serverName = JOptionPane.showInputDialog("Name of server: "); - try { - controller.getCurrentProfile().addCollection(serverName); - } catch (ConfigurationException e1) { - e1.printStackTrace(); - } - this.update(); - controller.getCurrentProfile().updateConsoles(); - } else if (e.getSource() == backupButton) { + } else if (actionSource == stopServerButton) { + stopServers(); + } else if (actionSource == addServerButton) { + addServer(); + } else if (actionSource == backupButton) { CommonFunctions.backup(this); - } else if (e.getSource() == addProfileButton) { + } else if (actionSource == addProfileButton) { controller.addProfile(JOptionPane.showInputDialog("Profile name: ")); updateProfiles(); - } else if (e.getSource() == deleteProfileButton) { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - controller.removeProfile(selected.toString()); - updateProfiles(); - } - } else if (e.getSource() == profiles) { + } else if (actionSource == deleteProfileButton) { + deleteProfile(); + } else if (actionSource == profiles) { changeProfile(); - } else if (e.getSource() == kickButton) { - if (selectedServerValue != null && selectedPlayerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "kick " + selectedPlayerValue); - } - } else if (e.getSource() == banButton) { - if (selectedServerValue != null && selectedPlayerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "ban " + selectedPlayerValue); - } - } else if (e.getSource() == opButton) { - if (selectedServerValue != null && selectedPlayerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "op " + selectedPlayerValue); - } - } else if (e.getSource() == deopButton) { - if (selectedServerValue != null && selectedPlayerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "deop " + selectedPlayerValue); - } - } else if (e.getSource() == customCommandButton) { - if (selectedServerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, customCommandTextField.getText()); - customCommandTextField.setText(""); - } - } else if (e.getSource() == saveServerButton) { - if (selectedServerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "save-all"); - } - } else if (e.getSource() == reloadButton) { - if (selectedServerValue != null) { - controller.getCurrentProfile().sendCommand(selectedServerValue, "reload"); - } - } else if (e.getSource() == showConsolesButton) { - ServerConsoles.setAsVisible(); - } else if (e.getSource() == targetServerCombo) { - updatePlayers(); } } + /** + * Deletes the selected profile + */ + private void deleteProfile() { + Object selected = profiles.getSelectedItem(); + if (selected != null) { + controller.removeProfile(selected.toString()); + updateProfiles(); + } + } + + /** + * Adds a new server with a server tab + */ + private void addServer() { + String serverName = JOptionPane.showInputDialog("Name of server: "); + try { + controller.getCurrentProfile().addCollection(serverName); + } catch (ConfigurationException e1) { + e1.printStackTrace(); + } + this.updateWithSavedProfileData(); + controller.getCurrentProfile().updateConsoles(); + } + /** * Updates the ServerLauncherGUI components to block a user from doing illegal actions * * @param running

Whether the servers are currently running

*/ - public void updateRunning(boolean running) { + public void updateGUIElementsWhenServersStartOrStop(boolean running) { boolean stopped = !running; //Most gui is only enabled when the server is stopped rather than running. profiles.setEnabled(stopped); addProfileButton.setEnabled(stopped); @@ -687,14 +387,14 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, if (current != null) { controller.setCurrentProfile(current.toString()); } - this.update(); + this.updateWithSavedProfileData(); controller.getCurrentProfile().updateConsoles(); } /** * Stops all servers */ - private void stop() { + public void stopServers() { try { setStatus("Servers are stopping..."); Server.stop(); @@ -705,72 +405,13 @@ public class ServerLauncherGUI extends MessageHandler implements ActionListener, } /** - * Asks the user for a delay if checked, and sets the value to the current profile + * Gets a specific message from its key + * + * @param stringKey

The key for the string to get

+ * @return

The corresponding string

*/ - private void delay() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile profile = controller.getProfileByName(selected.toString()); - if (delayStartupCheckBoxMenuItem.isSelected()) { - String response = JOptionPane.showInputDialog("Seconds to delay: "); - if (response == null) { - delayStartupCheckBoxMenuItem.setState(false); - return; - } - int parsed = Integer.parseInt(response); - Objects.requireNonNull(profile).setDelayStartup(parsed); - } else { - Objects.requireNonNull(profile).setDelayStartup(0); - } - } else { - showError("No profile selected"); - } - } - - /** - * Saves the runInBackground setting to the current profile - */ - private void background() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - Profile profile = controller.getProfileByName(selected.toString()); - Objects.requireNonNull(profile).setRunInBackground(runInBackgroundCheckBoxMenuItem.isSelected()); - } else { - showError("No profile selected"); - } - } - - /** - * Saves the downloadJars setting to the current profile - */ - private void downloadJars() { - Object selected = profiles.getSelectedItem(); - if (selected != null) { - controller.setDownloadAllJars(downloadJarsCheckBoxMenuItem.isSelected()); - } else { - showError("No profile selected"); - } - } - - /** - * Updates the list of players currently online on the selected server - */ - private void updatePlayers() { - String selectedServerValue; - Object selectedServer = targetServerCombo.getSelectedItem(); - if (selectedServer != null) { - targetPlayerCombo.removeAllItems(); - selectedServerValue = selectedServer.toString(); - if (selectedServerValue.equals("All")) { - for (String player : this.globalPlayers) { - targetPlayerCombo.addItem(player); - } - } else { - for (String player : controller.getCurrentProfile().getCollection(selectedServerValue).getServer().getPlayers()) { - targetPlayerCombo.addItem(player); - } - } - } + public String getMessage(String stringKey) { + return textStrings.get(stringKey); } /** diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherMenu.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherMenu.java new file mode 100644 index 0000000..3b96c99 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerLauncherMenu.java @@ -0,0 +1,195 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +import net.knarcraft.minecraftserverlauncher.profile.Controller; +import net.knarcraft.minecraftserverlauncher.profile.Profile; +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Objects; + +/** + * This class takes care of the GUI's top menu + */ +public class ServerLauncherMenu implements ActionListener { + + private JMenuBar menuBar; + //Options + private JCheckBoxMenuItem runInBackgroundCheckBoxMenuItem; + private JCheckBoxMenuItem delayStartupCheckBoxMenuItem; + private JCheckBoxMenuItem downloadJarsCheckBoxMenuItem; + //Help + private JMenuItem errorsMenuItem; + private JMenuItem setupMenuItem; + private JMenuItem manualUpdateMenuItem; + //Info/options + private JMenuItem runInBackgroundMenuItem; + private JMenuItem delayStartupMenuItem; + private JMenuItem downloadJarsMenuItem; + //Info/about + private JMenuItem aboutMenuItem; + private JMenuItem storyMenuItem; + + private Controller controller; + private ServerLauncherGUI serverLauncherGUI; + + /** + * Initializes a new server launcher menu + * + * @param menuBar

The menu bar to attach items to

+ * @param serverLauncherGUI

The server launcher GUI to use

+ */ + public ServerLauncherMenu(JMenuBar menuBar, ServerLauncherGUI serverLauncherGUI) { + this.controller = Controller.getInstance(); + this.menuBar = menuBar; + this.serverLauncherGUI = serverLauncherGUI; + initialize(); + } + + /** + * Initializes all GUI elements + */ + public void initialize() { + JMenu mnOptions = new JMenu("Options"); + menuBar.add(mnOptions); + + runInBackgroundCheckBoxMenuItem = new JCheckBoxMenuItem("Run in background on exit"); + mnOptions.add(runInBackgroundCheckBoxMenuItem); + runInBackgroundCheckBoxMenuItem.addActionListener(this); + + delayStartupCheckBoxMenuItem = new JCheckBoxMenuItem("Delay Startup"); + mnOptions.add(delayStartupCheckBoxMenuItem); + delayStartupCheckBoxMenuItem.addActionListener(this); + + downloadJarsCheckBoxMenuItem = new JCheckBoxMenuItem("Download jars"); + mnOptions.add(downloadJarsCheckBoxMenuItem); + downloadJarsCheckBoxMenuItem.addActionListener(this); + + JMenu mnHelp = new JMenu("Help"); + menuBar.add(mnHelp); + + errorsMenuItem = new JMenuItem("Errors"); + mnHelp.add(errorsMenuItem); + errorsMenuItem.addActionListener(this); + + setupMenuItem = new JMenuItem("Setup"); + mnHelp.add(setupMenuItem); + setupMenuItem.addActionListener(this); + + manualUpdateMenuItem = new JMenuItem("Manual update"); + mnHelp.add(manualUpdateMenuItem); + manualUpdateMenuItem.addActionListener(this); + + JMenu mnInfo = new JMenu("Info"); + menuBar.add(mnInfo); + + JMenu mnOptionsInfo = new JMenu("Options"); + mnInfo.add(mnOptionsInfo); + + runInBackgroundMenuItem = new JMenuItem("Run in background on exit"); + mnOptionsInfo.add(runInBackgroundMenuItem); + runInBackgroundMenuItem.addActionListener(this); + + delayStartupMenuItem = new JMenuItem("Delay Startup"); + mnOptionsInfo.add(delayStartupMenuItem); + delayStartupMenuItem.addActionListener(this); + + downloadJarsMenuItem = new JMenuItem("Download jars"); + mnOptionsInfo.add(downloadJarsMenuItem); + downloadJarsMenuItem.addActionListener(this); + + JMenu mnAbout = new JMenu("About"); + mnInfo.add(mnAbout); + + aboutMenuItem = new JMenuItem("About"); + mnAbout.add(aboutMenuItem); + aboutMenuItem.addActionListener(this); + + storyMenuItem = new JMenuItem("Story"); + mnAbout.add(storyMenuItem); + storyMenuItem.addActionListener(this); + } + + public void update() { + runInBackgroundCheckBoxMenuItem.setState(controller.getRunInBackground()); + delayStartupCheckBoxMenuItem.setState(controller.getDelayStartup() > 0); + downloadJarsCheckBoxMenuItem.setState(controller.getDownloadAllJars()); + } + + @Override + public void actionPerformed(ActionEvent actionEvent) { + Object actionSource = actionEvent.getSource(); + if (actionSource == runInBackgroundCheckBoxMenuItem) { + background(); + } else if (actionSource == delayStartupCheckBoxMenuItem) { + delay(); + } else if (actionSource == downloadJarsCheckBoxMenuItem) { + downloadJars(); + } else if (actionSource == errorsMenuItem) { + CommonFunctions.goToURL(serverLauncherGUI.getMessage("infoURL")); + } else if (actionSource == setupMenuItem) { + serverLauncherGUI.showMessage("Setup", serverLauncherGUI.getMessage("setupText")); + } else if (actionSource == manualUpdateMenuItem) { + CommonFunctions.goToURL(serverLauncherGUI.getMessage("manualUpdateURL")); + } else if (actionSource == runInBackgroundMenuItem) { + serverLauncherGUI.showMessage("Run in background", serverLauncherGUI.getMessage("runInBackgroundText")); + } else if (actionSource == delayStartupMenuItem) { + serverLauncherGUI.showMessage("Delay startup", serverLauncherGUI.getMessage("delayStartupText")); + } else if (actionSource == downloadJarsMenuItem) { + serverLauncherGUI.showMessage("Download jars", serverLauncherGUI.getMessage("downloadJarsText")); + } else if (actionSource == aboutMenuItem) { + serverLauncherGUI.showMessage("About", serverLauncherGUI.getMessage("aboutText")); + } else if (actionSource == storyMenuItem) { + CommonFunctions.goToURL(serverLauncherGUI.getMessage("storyURL")); + } + } + + /** + * Asks the user for a delay if checked, and sets the value to the current profile + */ + private void delay() { + String selectedProfile = serverLauncherGUI.getSelectedProfile(); + if (selectedProfile != null) { + Profile profile = controller.getProfileByName(selectedProfile); + if (delayStartupCheckBoxMenuItem.isSelected()) { + String response = JOptionPane.showInputDialog("Seconds to delay: "); + if (response == null) { + delayStartupCheckBoxMenuItem.setState(false); + return; + } + int parsed = Integer.parseInt(response); + Objects.requireNonNull(profile).setDelayStartup(parsed); + } else { + Objects.requireNonNull(profile).setDelayStartup(0); + } + } else { + serverLauncherGUI.showError("No profile selected"); + } + } + + /** + * Saves the runInBackground setting to the current profile + */ + private void background() { + String selectedProfile = serverLauncherGUI.getSelectedProfile(); + if (selectedProfile != null) { + Profile profile = controller.getProfileByName(selectedProfile); + Objects.requireNonNull(profile).setRunInBackground(runInBackgroundCheckBoxMenuItem.isSelected()); + } else { + serverLauncherGUI.showError("No profile selected"); + } + } + + /** + * Saves the downloadJars setting to the current profile + */ + private void downloadJars() { + String selectedProfile = serverLauncherGUI.getSelectedProfile(); + if (selectedProfile != null) { + controller.setDownloadAllJars(downloadJarsCheckBoxMenuItem.isSelected()); + } else { + serverLauncherGUI.showError("No profile selected"); + } + } +} diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java index 3e820dc..b972316 100644 --- a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/ServerTab.java @@ -227,7 +227,7 @@ public class ServerTab implements ActionListener { */ private void remove() { Main.getController().getCurrentProfile().removeCollection(this.name); - Main.getController().getGUI().update(); + Main.getController().getGUI().updateWithSavedProfileData(); Main.getController().getCurrentProfile().updateConsoles(); } diff --git a/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Tray.java b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Tray.java new file mode 100644 index 0000000..81f6611 --- /dev/null +++ b/src/main/java/net/knarcraft/minecraftserverlauncher/userinterface/Tray.java @@ -0,0 +1,132 @@ +package net.knarcraft.minecraftserverlauncher.userinterface; + +import net.knarcraft.minecraftserverlauncher.Main; +import net.knarcraft.minecraftserverlauncher.profile.Controller; +import net.knarcraft.minecraftserverlauncher.utility.CommonFunctions; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.io.IOException; +import java.io.InputStream; + +import static java.awt.Frame.NORMAL; + +/** + * This class adds a tray to the GUI + */ +public class Tray { + + private SystemTray tray; + private TrayIcon trayIcon; + private Controller controller; + private ServerLauncherGUI serverLauncherGUI; + private JFrame mainFrame; + + /** + * Instantiates a new tray + * + * @param mainFrame

The main frame of the GUI

+ * @param serverLauncherGUI

The server launcher GUI to use

+ */ + public Tray(JFrame mainFrame, ServerLauncherGUI serverLauncherGUI) { + this.controller = Main.getController(); + this.mainFrame = mainFrame; + this.serverLauncherGUI = serverLauncherGUI; + initializeTray(); + } + + /** + * Prepares the system tray if available + */ + private void initializeTray() { + if (SystemTray.isSupported()) { + tray = SystemTray.getSystemTray(); + InputStream imageStream = CommonFunctions.getResourceAsStream("GUIIcon.png"); + Image trayImage; + try { + trayImage = ImageIO.read(imageStream); + } catch (IOException e) { + trayImage = Toolkit.getDefaultToolkit().getImage("resources/GUIIcon.png"); + e.printStackTrace(); + } + PopupMenu popup = new PopupMenu(); + trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup); + trayIcon.setImageAutoSize(true); + ActionListener exitListener = e -> { + serverLauncherGUI.stopServers(); + controller.saveState(); + System.exit(0); + }; + + MenuItem restoreItem = new MenuItem("Restore"); + popup.add(restoreItem); + restoreItem.addActionListener(e -> { + mainFrame.setExtendedState(NORMAL); + tray.remove(trayIcon); + mainFrame.setVisible(true); + }); + MenuItem exitItem = new MenuItem("Exit"); + exitItem.addActionListener(exitListener); + popup.add(exitItem); + mainFrame.addWindowStateListener(e -> { + if (e.getNewState() == NORMAL) { + tray.remove(trayIcon); + mainFrame.setVisible(true); + } + }); + + mainFrame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + if (controller.getRunInBackground()) { + try { + tray.add(trayIcon); + mainFrame.setVisible(false); + } catch (AWTException e1) { + e1.printStackTrace(); + } + } else { + serverLauncherGUI.stopServers(); + controller.saveState(); + System.exit(0); + } + } + }); + + trayIcon.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (e.getClickCount() >= 1 && e.getButton() == MouseEvent.BUTTON1) { + mainFrame.setExtendedState(NORMAL); + tray.remove(trayIcon); + mainFrame.setVisible(true); + } + } + }); + } else { + mainFrame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + controller.saveState(); + serverLauncherGUI.stopServers(); + System.exit(0); + } + }); + } + } + + /** + * Hides the gui to the tray + */ + public void hideToTray() { + mainFrame.setVisible(false); + try { + tray.add(trayIcon); + } catch (AWTException e) { + e.printStackTrace(); + } + } + +}