Implements run in background on exit

The GUI will be minimized to tray on exit, if runInBackground is enabled.
Starting with runInBackground enabled, hides the GUI and runs the servers.
This commit is contained in:
Kristian Knarvik 2018-02-04 10:20:58 +01:00
parent e9e500fb2f
commit 9b14603d85
4 changed files with 135 additions and 24 deletions

View File

@ -33,7 +33,6 @@ public class Main {
gui = new GUI(); gui = new GUI();
new ServerConsoles(); new ServerConsoles();
Profile.load(); Profile.load();
//TODO: replace with profiles loading generating a default profile if empty.
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(); ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(Main::updateConsoles, 10, 250, TimeUnit.MILLISECONDS); exec.scheduleAtFixedRate(Main::updateConsoles, 10, 250, TimeUnit.MILLISECONDS);

View File

@ -9,6 +9,7 @@ import javax.swing.*;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.Executors;
/** /**
* Contains all user settings, and a list of servers. * Contains all user settings, and a list of servers.
@ -149,6 +150,18 @@ public class Profile {
this.runInBackground = value; 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) { public void setDelayStartup(int value) {
if (value >= 0) { if (value >= 0) {
this.delayStartup = value; this.delayStartup = value;
@ -191,6 +204,7 @@ public class Profile {
/** /**
* Reads all server tabs, and saves it to the variables of the corresponding servers. * 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() { public void save() {
for (Collection collection : this.collections) { for (Collection collection : this.collections) {
@ -226,6 +240,9 @@ public class Profile {
} }
} }
/**
* Reads profiles and servers from a text file.
*/
public static void load() { public static void load() {
try (Scanner in = new Scanner(new File("files/Profiles.txt"))) { try (Scanner in = new Scanner(new File("files/Profiles.txt"))) {
try { try {
@ -252,8 +269,9 @@ public class Profile {
Main.gui().addProfile(profileData[0]); Main.gui().addProfile(profileData[0]);
} }
} }
} catch (Exception e) { } catch (ArrayIndexOutOfBoundsException | NumberFormatException e) {
e.printStackTrace(); 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) { if (profiles.size() == 0) {
addProfile("Default"); addProfile("Default");
@ -263,5 +281,9 @@ public class Profile {
addProfile("Default"); addProfile("Default");
} }
Main.gui().update(); Main.gui().update();
if (current.getRunInBackground()) {
Main.gui().hide();
Executors.newSingleThreadExecutor().execute(Server::startServers);
}
} }
} }

View File

@ -55,7 +55,18 @@ public class Server {
this.bungeeVersion = ""; 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.name = name;
this.path = path; this.path = path;
this.enabled = enabled; this.enabled = enabled;
@ -295,7 +306,6 @@ public class Server {
case "MCPCplus": case "MCPCplus":
if (!file.isFile()) { if (!file.isFile()) {
success = downloadFile(url + name + ver + ".jar", filePath); success = downloadFile(url + name + ver + ".jar", filePath);
System.out.println(url + name + ver + ".jar");
if (!success) { if (!success) {
throw new FileNotFoundException("Jar file could not be downloaded."); throw new FileNotFoundException("Jar file could not be downloaded.");
} }
@ -312,7 +322,10 @@ public class Server {
} }
newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd());
if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { 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); this.setVersion(this.type.getName(), newestVersion);
if (!success) { if (!success) {
throw new FileNotFoundException("Jar file could not be downloaded."); throw new FileNotFoundException("Jar file could not be downloaded.");
@ -336,7 +349,10 @@ public class Server {
} }
newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd()); newestVersion = stringBetween(versionText, type.getSrcStart(), type.getSrcEnd());
if (!file.isFile() || !newestVersion.equals(this.getVersion(name))) { 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); this.setVersion(name, newestVersion);
if (!success) { if (!success) {
throw new FileNotFoundException("Jar file could not be downloaded."); throw new FileNotFoundException("Jar file could not be downloaded.");

View File

@ -7,10 +7,7 @@ import net.knarcraft.serverlauncher.profile.Profile;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.*;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*; import java.io.*;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
@ -19,6 +16,9 @@ import java.util.Objects;
import java.util.Scanner; import java.util.Scanner;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import static java.awt.Frame.NORMAL;
import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
/** /**
* Generates a GUI. * Generates a GUI.
* *
@ -54,6 +54,10 @@ public class GUI implements ActionListener {
private JTabbedPane serversPane; private JTabbedPane serversPane;
private SystemTray tray;
private TrayIcon trayIcon;
/** /**
* Create the application window. * Create the application window.
*/ */
@ -100,6 +104,9 @@ public class GUI implements ActionListener {
for (Collection collection : Profile.getCurrent().getCollections()) { for (Collection collection : Profile.getCurrent().getCollections()) {
serversPane.addTab(collection.getName(), collection.getServerTab().getPanel()); 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) { public void setStatus(String text) {
@ -126,7 +133,7 @@ public class GUI implements ActionListener {
} }
frame = new JFrame("Minecraft server launcher"); frame = new JFrame("Minecraft server launcher");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
frame.setResizable(false); frame.setResizable(false);
ImageIcon img; ImageIcon img;
try { try {
@ -136,13 +143,6 @@ public class GUI implements ActionListener {
} }
frame.setIconImage(img.getImage()); frame.setIconImage(img.getImage());
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
save();
stop();
}
});
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
frame.setJMenuBar(menuBar); frame.setJMenuBar(menuBar);
@ -389,6 +389,85 @@ public class GUI implements ActionListener {
frame.validate(); frame.validate();
frame.pack(); frame.pack();
frame.setVisible(true); 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() { public void updateSelectServers() {
@ -545,11 +624,6 @@ public class GUI implements ActionListener {
} else { } else {
JOptionPane.showMessageDialog(null, "No profile selected", "Error", JOptionPane.ERROR_MESSAGE); 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);
}
} }
/** /**