diff --git a/src/net/knarcraft/serverlauncher/Main.java b/src/net/knarcraft/serverlauncher/Main.java index d0f5157..37708f7 100644 --- a/src/net/knarcraft/serverlauncher/Main.java +++ b/src/net/knarcraft/serverlauncher/Main.java @@ -33,7 +33,6 @@ public class Main { gui = new GUI(); new ServerConsoles(); Profile.load(); - //TODO: replace with profiles loading generating a default profile if empty. ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); exec.scheduleAtFixedRate(Main::updateConsoles, 10, 250, TimeUnit.MILLISECONDS); diff --git a/src/net/knarcraft/serverlauncher/profile/Profile.java b/src/net/knarcraft/serverlauncher/profile/Profile.java index 073dc1c..4532a4e 100644 --- a/src/net/knarcraft/serverlauncher/profile/Profile.java +++ b/src/net/knarcraft/serverlauncher/profile/Profile.java @@ -9,6 +9,7 @@ import javax.swing.*; import java.io.*; import java.util.ArrayList; import java.util.Scanner; +import java.util.concurrent.Executors; /** * Contains all user settings, and a list of servers. @@ -149,6 +150,18 @@ public class Profile { this.runInBackground = value; } + public boolean getRunInBackground() { + return this.runInBackground; + } + + public int getDelayStartup() { + return this.delayStartup; + } + + public boolean getDownloadJars() { + return this.downloadJars; + } + public void setDelayStartup(int value) { if (value >= 0) { this.delayStartup = value; @@ -191,6 +204,7 @@ public class Profile { /** * Reads all server tabs, and saves it to the variables of the corresponding servers. + * Saves all profiles and servers to a text file. */ public void save() { for (Collection collection : this.collections) { @@ -226,6 +240,9 @@ public class Profile { } } + /** + * Reads profiles and servers from a text file. + */ public static void load() { try (Scanner in = new Scanner(new File("files/Profiles.txt"))) { try { @@ -252,8 +269,9 @@ public class Profile { Main.gui().addProfile(profileData[0]); } } - } catch (Exception e) { - e.printStackTrace(); + } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) { + JOptionPane.showMessageDialog(null, "Invalid Profile.txt file. Profiles could not be loaded. If this error persists, please manually delete the file.", "Error", JOptionPane.ERROR_MESSAGE); + System.exit(1); } if (profiles.size() == 0) { addProfile("Default"); @@ -263,5 +281,9 @@ public class Profile { addProfile("Default"); } Main.gui().update(); + if (current.getRunInBackground()) { + Main.gui().hide(); + Executors.newSingleThreadExecutor().execute(Server::startServers); + } } } diff --git a/src/net/knarcraft/serverlauncher/server/Server.java b/src/net/knarcraft/serverlauncher/server/Server.java index 1b14283..7cee6f6 100644 --- a/src/net/knarcraft/serverlauncher/server/Server.java +++ b/src/net/knarcraft/serverlauncher/server/Server.java @@ -55,7 +55,18 @@ public class Server { this.bungeeVersion = ""; } - public Server(String name, String path, boolean enabled, String typeName, String serverVersion, String maxRam, String vanillaVersion, String snapshotVersion, String spongeVanillaVersion, String bungeeVersion) { + public Server( + String name, + String path, + boolean enabled, + String typeName, + String serverVersion, + String maxRam, + String vanillaVersion, + String snapshotVersion, + String spongeVanillaVersion, + String bungeeVersion + ) { this.name = name; this.path = path; this.enabled = enabled; @@ -295,7 +306,6 @@ public class Server { case "MCPCplus": if (!file.isFile()) { success = downloadFile(url + name + ver + ".jar", filePath); - System.out.println(url + name + ver + ".jar"); if (!success) { throw new FileNotFoundException("Jar file could not be downloaded."); } @@ -312,7 +322,10 @@ public class Server { } newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { - success = downloadFile(url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", filePath); + success = downloadFile( + url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", + filePath + ); this.setVersion(this.type.getName(), newestVersion); if (!success) { throw new FileNotFoundException("Jar file could not be downloaded."); @@ -336,7 +349,10 @@ public class Server { } newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { - success = downloadFile(url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", filePath); + success = downloadFile( + url + newestVersion + type.getDownloadURLPart() + newestVersion + ".jar", + filePath + ); this.setVersion(name, newestVersion); if (!success) { throw new FileNotFoundException("Jar file could not be downloaded."); diff --git a/src/net/knarcraft/serverlauncher/userinterface/GUI.java b/src/net/knarcraft/serverlauncher/userinterface/GUI.java index 3157a59..0b59e23 100644 --- a/src/net/knarcraft/serverlauncher/userinterface/GUI.java +++ b/src/net/knarcraft/serverlauncher/userinterface/GUI.java @@ -7,10 +7,7 @@ import net.knarcraft.serverlauncher.profile.Profile; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; +import java.awt.event.*; import java.io.*; import java.net.URI; import java.net.URISyntaxException; @@ -19,6 +16,9 @@ import java.util.Objects; import java.util.Scanner; import java.util.concurrent.Executors; +import static java.awt.Frame.NORMAL; +import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE; + /** * Generates a GUI. * @@ -54,6 +54,10 @@ public class GUI implements ActionListener { private JTabbedPane serversPane; + private SystemTray tray; + private TrayIcon trayIcon; + + /** * Create the application window. */ @@ -100,6 +104,9 @@ public class GUI implements ActionListener { for (Collection collection : Profile.getCurrent().getCollections()) { serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); } + chckbxmntmRunInBackground.setState(Profile.getCurrent().getRunInBackground()); + chckbxmntmDelayStartup.setState(Profile.getCurrent().getDelayStartup() > 0); + chckbxmntmDownloadJars.setState(Profile.getCurrent().getDownloadJars()); } public void setStatus(String text) { @@ -126,7 +133,7 @@ public class GUI implements ActionListener { } frame = new JFrame("Minecraft server launcher"); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); frame.setResizable(false); ImageIcon img; try { @@ -136,13 +143,6 @@ public class GUI implements ActionListener { } frame.setIconImage(img.getImage()); - frame.addWindowListener(new WindowAdapter() { - public void windowClosing(WindowEvent e) { - save(); - stop(); - } - }); - JMenuBar menuBar = new JMenuBar(); frame.setJMenuBar(menuBar); @@ -389,6 +389,85 @@ public class GUI implements ActionListener { frame.validate(); frame.pack(); frame.setVisible(true); + tray(); + } + + public void hide() { + frame.setVisible(false); + try { + tray.add(trayIcon); + } catch (AWTException e) { + e.printStackTrace(); + } + } + + private void tray() { + if (SystemTray.isSupported()) { + tray = SystemTray.getSystemTray(); + Image trayImage = Toolkit.getDefaultToolkit().getImage("files/GUIIcon.png"); + PopupMenu popup = new PopupMenu(); + trayIcon = new TrayIcon(trayImage, "Minecraft Server Launcher", popup); + trayIcon.setImageAutoSize(true); + ActionListener exitListener= e -> { + save(); + System.exit(0); + }; + + 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 (Profile.getCurrent().getRunInBackground() && SystemTray.isSupported()) { + try { + tray.add(trayIcon); + frame.setVisible(false); + } catch (AWTException e1) { + e1.printStackTrace(); + } + } else { + save(); + stop(); + 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); + } + } + }); + } else { + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + save(); + stop(); + System.exit(0); + } + }); + } } public void updateSelectServers() { @@ -545,11 +624,6 @@ public class GUI implements ActionListener { } else { JOptionPane.showMessageDialog(null, "No profile selected", "Error", JOptionPane.ERROR_MESSAGE); } - if (chckbxmntmRunInBackground.isSelected()) { - frame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE); - } else { - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - } } /**