simplified loading of SlipstreamConfig
This commit is contained in:
parent
9e8e830ab1
commit
ccd50b0275
3 changed files with 84 additions and 128 deletions
|
@ -1,19 +1,14 @@
|
||||||
package net.vhati.modmanager;
|
package net.vhati.modmanager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Properties;
|
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UIManager.LookAndFeelInfo;
|
|
||||||
|
|
||||||
import ch.qos.logback.classic.LoggerContext;
|
import ch.qos.logback.classic.LoggerContext;
|
||||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
@ -36,8 +31,8 @@ public class FTLModManager {
|
||||||
|
|
||||||
public static final String APP_NAME = "Slipstream Mod Manager";
|
public static final String APP_NAME = "Slipstream Mod Manager";
|
||||||
public static final ComparableVersion APP_VERSION = new ComparableVersion( "1.9.1" );
|
public static final ComparableVersion APP_VERSION = new ComparableVersion( "1.9.1" );
|
||||||
public static final String APP_URL = "https://subsetgames.com/forum/viewtopic.php?f=12&t=17102";
|
public static final String APP_URL = "TODO";
|
||||||
public static final String APP_AUTHOR = "Vhati";
|
public static final String APP_AUTHOR = "jan-leila";
|
||||||
|
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
|
@ -53,7 +48,7 @@ public class FTLModManager {
|
||||||
|
|
||||||
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
|
||||||
encoder.setContext( lc );
|
encoder.setContext( lc );
|
||||||
encoder.setCharset( Charset.forName( "UTF-8" ) );
|
encoder.setCharset(StandardCharsets.UTF_8);
|
||||||
encoder.setPattern( "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" );
|
encoder.setPattern( "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" );
|
||||||
encoder.start();
|
encoder.start();
|
||||||
|
|
||||||
|
@ -76,7 +71,7 @@ public class FTLModManager {
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void uncaughtException( Thread t, Throwable e ) {
|
public void uncaughtException( Thread t, Throwable e ) {
|
||||||
log.error( "Uncaught exception in thread: "+ t.toString(), e );
|
log.error("Uncaught exception in thread: {}", t.toString(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -86,20 +81,15 @@ public class FTLModManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure all popups are triggered from the event dispatch thread.
|
// Ensure all popups are triggered from the event dispatch thread.
|
||||||
|
SwingUtilities.invokeLater(FTLModManager::guiInit);
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
guiInit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void guiInit() {
|
private static void guiInit() {
|
||||||
try {
|
try {
|
||||||
|
// TODO: get mods file from env var
|
||||||
// Nag if the jar was double-clicked.
|
// Nag if the jar was double-clicked.
|
||||||
if ( new File( "./mods/" ).exists() == false ) {
|
if (!new File("./mods/").exists()) {
|
||||||
String currentPath = new File( "." ).getAbsoluteFile().getParentFile().getAbsolutePath();
|
String currentPath = new File( "." ).getAbsoluteFile().getParentFile().getAbsolutePath();
|
||||||
|
|
||||||
log.error( String.format( "Slipstream could not find its own folder (Currently in \"%s\"), exiting...", currentPath ) );
|
log.error( String.format( "Slipstream could not find its own folder (Currently in \"%s\"), exiting...", currentPath ) );
|
||||||
|
@ -108,46 +98,13 @@ public class FTLModManager {
|
||||||
throw new ExitException();
|
throw new ExitException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: get config file from env var
|
||||||
File configFile = new File( "modman.cfg" );
|
File configFile = new File( "modman.cfg" );
|
||||||
|
|
||||||
boolean writeConfig = false;
|
SlipstreamConfig appConfig = new SlipstreamConfig(configFile);
|
||||||
Properties props = new Properties();
|
|
||||||
props.setProperty( SlipstreamConfig.ALLOW_ZIP, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.FTL_DATS_PATH, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.STEAM_DISTRO, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.STEAM_EXE_PATH, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.NEVER_RUN_FTL, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.UPDATE_CATALOG, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.UPDATE_APP, "" ); // Prompt.
|
|
||||||
props.setProperty( SlipstreamConfig.USE_DEFAULT_UI, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.REMEMBER_GEOMETRY, "true" );
|
|
||||||
// "manager_geometry" doesn't have a default.
|
|
||||||
|
|
||||||
// Read the config file.
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
if ( configFile.exists() ) {
|
|
||||||
log.debug( "Loading config file" );
|
|
||||||
in = new FileInputStream( configFile );
|
|
||||||
props.load( new InputStreamReader( in, "UTF-8" ) );
|
|
||||||
} else {
|
|
||||||
writeConfig = true; // Create a new cfg, but only if necessary.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
log.error( "Error loading config", e );
|
|
||||||
showErrorDialog( "Error loading config from "+ configFile.getPath() );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {if ( in != null ) in.close();}
|
|
||||||
catch ( IOException e ) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
SlipstreamConfig appConfig = new SlipstreamConfig( props, configFile );
|
|
||||||
|
|
||||||
// Look-and-Feel.
|
// Look-and-Feel.
|
||||||
boolean useDefaultUI = "true".equals( appConfig.getProperty( SlipstreamConfig.USE_DEFAULT_UI, "false" ) );
|
boolean useDefaultUI = Boolean.parseBoolean(appConfig.getProperty(SlipstreamConfig.USE_DEFAULT_UI, "false"));
|
||||||
|
|
||||||
if ( !useDefaultUI ) {
|
if ( !useDefaultUI ) {
|
||||||
LookAndFeel defaultLaf = UIManager.getLookAndFeel();
|
LookAndFeel defaultLaf = UIManager.getLookAndFeel();
|
||||||
|
@ -157,7 +114,7 @@ public class FTLModManager {
|
||||||
log.debug( "Setting system look and feel: "+ UIManager.getSystemLookAndFeelClassName() );
|
log.debug( "Setting system look and feel: "+ UIManager.getSystemLookAndFeelClassName() );
|
||||||
|
|
||||||
// SystemLaf is risky. It may throw an exception, or lead to graphical bugs.
|
// SystemLaf is risky. It may throw an exception, or lead to graphical bugs.
|
||||||
// Problems are geneally caused by custom Windows themes.
|
// Problems are generally caused by custom Windows themes.
|
||||||
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
|
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
|
@ -165,7 +122,6 @@ public class FTLModManager {
|
||||||
log.info( "Setting "+ SlipstreamConfig.USE_DEFAULT_UI +"=true in the config file to prevent this error..." );
|
log.info( "Setting "+ SlipstreamConfig.USE_DEFAULT_UI +"=true in the config file to prevent this error..." );
|
||||||
|
|
||||||
appConfig.setProperty( SlipstreamConfig.USE_DEFAULT_UI, "true" );
|
appConfig.setProperty( SlipstreamConfig.USE_DEFAULT_UI, "true" );
|
||||||
writeConfig = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel( defaultLaf );
|
UIManager.setLookAndFeel( defaultLaf );
|
||||||
|
@ -220,7 +176,6 @@ public class FTLModManager {
|
||||||
|
|
||||||
if ( datsDir != null ) {
|
if ( datsDir != null ) {
|
||||||
appConfig.setProperty( SlipstreamConfig.FTL_DATS_PATH, datsDir.getAbsolutePath() );
|
appConfig.setProperty( SlipstreamConfig.FTL_DATS_PATH, datsDir.getAbsolutePath() );
|
||||||
writeConfig = true;
|
|
||||||
log.info( "FTL dats located at: "+ datsDir.getAbsolutePath() );
|
log.info( "FTL dats located at: "+ datsDir.getAbsolutePath() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -237,11 +192,9 @@ public class FTLModManager {
|
||||||
int steamBasedResponse = JOptionPane.showConfirmDialog( null, "Was FTL installed via Steam?", "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE );
|
int steamBasedResponse = JOptionPane.showConfirmDialog( null, "Was FTL installed via Steam?", "Confirm", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE );
|
||||||
if ( steamBasedResponse == JOptionPane.YES_OPTION ) {
|
if ( steamBasedResponse == JOptionPane.YES_OPTION ) {
|
||||||
appConfig.setProperty( SlipstreamConfig.STEAM_DISTRO, "true" );
|
appConfig.setProperty( SlipstreamConfig.STEAM_DISTRO, "true" );
|
||||||
writeConfig = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
appConfig.setProperty( SlipstreamConfig.STEAM_DISTRO, "false" );
|
appConfig.setProperty( SlipstreamConfig.STEAM_DISTRO, "false" );
|
||||||
writeConfig = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +248,6 @@ public class FTLModManager {
|
||||||
|
|
||||||
if ( steamExeFile != null ) {
|
if ( steamExeFile != null ) {
|
||||||
appConfig.setProperty( SlipstreamConfig.STEAM_EXE_PATH, steamExeFile.getAbsolutePath() );
|
appConfig.setProperty( SlipstreamConfig.STEAM_EXE_PATH, steamExeFile.getAbsolutePath() );
|
||||||
writeConfig = true;
|
|
||||||
log.info( "Steam located at: "+ steamExeFile.getAbsolutePath() );
|
log.info( "Steam located at: "+ steamExeFile.getAbsolutePath() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,11 +260,9 @@ public class FTLModManager {
|
||||||
int launchResponse = JOptionPane.showOptionDialog( null, "Would you prefer to launch FTL directly, or via Steam?", "How to Launch?", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, launchOptions, launchOptions[1] );
|
int launchResponse = JOptionPane.showOptionDialog( null, "Would you prefer to launch FTL directly, or via Steam?", "How to Launch?", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, launchOptions, launchOptions[1] );
|
||||||
if ( launchResponse == 0 ) {
|
if ( launchResponse == 0 ) {
|
||||||
appConfig.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "false" );
|
appConfig.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "false" );
|
||||||
writeConfig = true;
|
|
||||||
}
|
}
|
||||||
else if ( launchResponse == 1 ) {
|
else if ( launchResponse == 1 ) {
|
||||||
appConfig.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "true" );
|
appConfig.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "true" );
|
||||||
writeConfig = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,18 +290,6 @@ public class FTLModManager {
|
||||||
appConfig.setProperty( SlipstreamConfig.UPDATE_CATALOG, "0" );
|
appConfig.setProperty( SlipstreamConfig.UPDATE_CATALOG, "0" );
|
||||||
appConfig.setProperty( SlipstreamConfig.UPDATE_APP, "0" );
|
appConfig.setProperty( SlipstreamConfig.UPDATE_APP, "0" );
|
||||||
}
|
}
|
||||||
writeConfig = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( writeConfig ) {
|
|
||||||
try {
|
|
||||||
appConfig.writeConfig();
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
String errorMsg = String.format( "Error writing config to \"%s\"", configFile.getPath() );
|
|
||||||
log.error( errorMsg, e );
|
|
||||||
showErrorDialog( errorMsg );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagerFrame frame = null;
|
ManagerFrame frame = null;
|
||||||
|
@ -388,8 +326,6 @@ public class FTLModManager {
|
||||||
JOptionPane.showMessageDialog( null, message, "Error", JOptionPane.ERROR_MESSAGE );
|
JOptionPane.showMessageDialog( null, message, "Error", JOptionPane.ERROR_MESSAGE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static class ExitException extends RuntimeException {
|
private static class ExitException extends RuntimeException {
|
||||||
public ExitException() {
|
public ExitException() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class SlipstreamCLI {
|
||||||
}
|
}
|
||||||
|
|
||||||
File configFile = new File( "modman.cfg" );
|
File configFile = new File( "modman.cfg" );
|
||||||
SlipstreamConfig appConfig = getConfig( configFile );
|
SlipstreamConfig appConfig = new SlipstreamConfig( configFile );
|
||||||
|
|
||||||
if ( slipstreamCmd.listMods ) {
|
if ( slipstreamCmd.listMods ) {
|
||||||
listMods(appConfig);
|
listMods(appConfig);
|
||||||
|
@ -353,48 +353,6 @@ public class SlipstreamCLI {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads settings from a config file.
|
|
||||||
*
|
|
||||||
* If an error occurs, it'll be logged,
|
|
||||||
* and default settings will be returned.
|
|
||||||
*/
|
|
||||||
private static SlipstreamConfig getConfig( File configFile ) {
|
|
||||||
|
|
||||||
Properties props = new Properties();
|
|
||||||
props.setProperty( SlipstreamConfig.ALLOW_ZIP, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.FTL_DATS_PATH, "" );
|
|
||||||
props.setProperty( SlipstreamConfig.STEAM_EXE_PATH, "" );
|
|
||||||
props.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.NEVER_RUN_FTL, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.USE_DEFAULT_UI, "false" );
|
|
||||||
props.setProperty( SlipstreamConfig.REMEMBER_GEOMETRY, "true" );
|
|
||||||
// "update_catalog" doesn't have a default.
|
|
||||||
// "update_app" doesn't have a default.
|
|
||||||
// "manager_geometry" doesn't have a default.
|
|
||||||
|
|
||||||
// Read the config file.
|
|
||||||
InputStream in = null;
|
|
||||||
try {
|
|
||||||
if ( configFile.exists() ) {
|
|
||||||
log.trace( "Loading properties from config file" );
|
|
||||||
in = new FileInputStream( configFile );
|
|
||||||
props.load( new InputStreamReader( in, "UTF-8" ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( IOException e ) {
|
|
||||||
log.error( "Error loading config", e );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
try {if ( in != null ) in.close();}
|
|
||||||
catch ( IOException e ) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
SlipstreamConfig appConfig = new SlipstreamConfig( props, configFile );
|
|
||||||
return appConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the validity of the config's dats path and returns it.
|
* Checks the validity of the config's dats path and returns it.
|
||||||
* Or exits if the path is invalid.
|
* Or exits if the path is invalid.
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
package net.vhati.modmanager.core;
|
package net.vhati.modmanager.core;
|
||||||
|
|
||||||
import java.io.File;
|
import org.slf4j.Logger;
|
||||||
import java.io.FileOutputStream;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
import javax.swing.*;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
|
||||||
public class SlipstreamConfig {
|
public class SlipstreamConfig {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger( SlipstreamConfig.class );
|
||||||
|
|
||||||
public static final String ALLOW_ZIP = "allow_zip";
|
public static final String ALLOW_ZIP = "allow_zip";
|
||||||
public static final String FTL_DATS_PATH = "ftl_dats_path";
|
public static final String FTL_DATS_PATH = "ftl_dats_path";
|
||||||
|
@ -26,12 +29,35 @@ public class SlipstreamConfig {
|
||||||
public static final String REMEMBER_GEOMETRY = "remember_geometry";
|
public static final String REMEMBER_GEOMETRY = "remember_geometry";
|
||||||
public static final String MANAGER_GEOMETRY = "manager_geometry";
|
public static final String MANAGER_GEOMETRY = "manager_geometry";
|
||||||
|
|
||||||
private Properties config;
|
private final Properties config;
|
||||||
private File configFile;
|
private final File configFile;
|
||||||
|
|
||||||
|
private final AtomicBoolean shutdownHookInitialized;
|
||||||
|
|
||||||
|
public SlipstreamConfig(File configFile) {
|
||||||
|
this.shutdownHookInitialized = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
config = getProperties();
|
||||||
|
|
||||||
|
// Read the config file.
|
||||||
|
InputStream in = null;
|
||||||
|
try {
|
||||||
|
if ( configFile.exists() ) {
|
||||||
|
log.debug( "Loading config file" );
|
||||||
|
in = new FileInputStream( configFile );
|
||||||
|
config.load( new InputStreamReader( in, StandardCharsets.UTF_8) );
|
||||||
|
scheduleShutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( IOException e ) {
|
||||||
|
log.error( "Error loading config", e );
|
||||||
|
showErrorDialog( "Error loading config from "+ configFile.getPath() );
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {if ( in != null ) in.close();}
|
||||||
|
catch ( IOException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
public SlipstreamConfig( Properties config, File configFile ) {
|
|
||||||
this.config = config;
|
|
||||||
this.configFile = configFile;
|
this.configFile = configFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +68,23 @@ public class SlipstreamConfig {
|
||||||
this.configFile = srcConfig.getConfigFile();
|
this.configFile = srcConfig.getConfigFile();
|
||||||
this.config = new Properties();
|
this.config = new Properties();
|
||||||
this.config.putAll( srcConfig.getConfig() );
|
this.config.putAll( srcConfig.getConfig() );
|
||||||
|
this.shutdownHookInitialized = srcConfig.shutdownHookInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Properties getProperties() {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty( SlipstreamConfig.ALLOW_ZIP, "false" );
|
||||||
|
props.setProperty( SlipstreamConfig.FTL_DATS_PATH, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.STEAM_DISTRO, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.STEAM_EXE_PATH, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.NEVER_RUN_FTL, "false" );
|
||||||
|
props.setProperty( SlipstreamConfig.UPDATE_CATALOG, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.UPDATE_APP, "" ); // Prompt.
|
||||||
|
props.setProperty( SlipstreamConfig.USE_DEFAULT_UI, "false" );
|
||||||
|
props.setProperty( SlipstreamConfig.REMEMBER_GEOMETRY, "true" );
|
||||||
|
return props;
|
||||||
|
}
|
||||||
|
|
||||||
public Properties getConfig() { return config; }
|
public Properties getConfig() { return config; }
|
||||||
|
|
||||||
|
@ -51,9 +92,30 @@ public class SlipstreamConfig {
|
||||||
|
|
||||||
|
|
||||||
public Object setProperty( String key, String value ) {
|
public Object setProperty( String key, String value ) {
|
||||||
|
scheduleShutdown();
|
||||||
return config.setProperty( key, value );
|
return config.setProperty( key, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void scheduleShutdown() {
|
||||||
|
if (!shutdownHookInitialized.compareAndExchange(false, true)) {
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
try {
|
||||||
|
this.writeConfig();
|
||||||
|
} catch (IOException e) {
|
||||||
|
String errorMsg = String.format( "Error writing config to \"%s\"", configFile.getPath() );
|
||||||
|
log.error( errorMsg, e );
|
||||||
|
// TODO: only show this error when in gui mode
|
||||||
|
showErrorDialog( errorMsg );
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showErrorDialog( String message ) {
|
||||||
|
JOptionPane.showMessageDialog( null, message, "Error", JOptionPane.ERROR_MESSAGE );
|
||||||
|
}
|
||||||
|
|
||||||
public int getPropertyAsInt( String key, int defaultValue ) {
|
public int getPropertyAsInt( String key, int defaultValue ) {
|
||||||
String s = config.getProperty( key );
|
String s = config.getProperty( key );
|
||||||
if ( s != null && s.matches("^\\d+$") )
|
if ( s != null && s.matches("^\\d+$") )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue