Added Preferences dialog

This commit is contained in:
Vhati 2013-09-16 06:57:58 -04:00
parent e7c3276541
commit 0aa6cc434d
7 changed files with 691 additions and 2 deletions

View file

@ -8,6 +8,7 @@ Changelog
- Added --global-panic commandline arg to show mod devs typoed find tags - Added --global-panic commandline arg to show mod devs typoed find tags
- Added commandline tips in readme_modders.txt - Added commandline tips in readme_modders.txt
- Fixed sloppy parser Validate error about things not allowed at root - Fixed sloppy parser Validate error about things not allowed at root
- Added a Preferences dialog as an alternative to editing modman.cfg
1.2: 1.2:
- Added a commandline interface - Added a commandline interface

View file

@ -57,7 +57,7 @@ public class SlipstreamConfig {
configComments += " ftl_dats_path - The path to FTL's resources folder. If invalid, you'll be prompted.\n"; configComments += " ftl_dats_path - The path to FTL's resources folder. If invalid, you'll be prompted.\n";
configComments += " never_run_ftl - If true, there will be no offer to run FTL after patching. Default: false.\n"; configComments += " never_run_ftl - If true, there will be no offer to run FTL after patching. Default: false.\n";
configComments += " update_catalog - If a number greater than 0, check for new mod descriptions every N days.\n"; configComments += " update_catalog - If a number greater than 0, check for new mod descriptions every N days.\n";
configComments += " update_app - If a number greater than 0, check for new app version every N days.\n"; configComments += " update_app - If a number greater than 0, check for newer app versions every N days.\n";
configComments += " use_default_ui - If true, no attempt will be made to resemble a native GUI. Default: false.\n"; configComments += " use_default_ui - If true, no attempt will be made to resemble a native GUI. Default: false.\n";
configComments += " remember_geometry - If true, window geometry will be saved on exit and restored on startup.\n"; configComments += " remember_geometry - If true, window geometry will be saved on exit and restored on startup.\n";
configComments += "\n"; configComments += "\n";

View file

@ -0,0 +1,432 @@
package net.vhati.modmanager.ui;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.vhati.modmanager.ui.RegexDocument;
public class FieldEditorPanel extends JPanel {
public enum ContentType { WRAPPED_LABEL, LABEL, STRING, INTEGER, BOOLEAN, SLIDER, COMBO, CHOOSER };
private Map<String, JTextArea> wrappedLabelMap = new HashMap<String, JTextArea>();
private Map<String, JLabel> labelMap = new HashMap<String, JLabel>();
private Map<String, JTextField> stringMap = new HashMap<String, JTextField>();
private Map<String, JTextField> intMap = new HashMap<String, JTextField>();
private Map<String, JCheckBox> boolMap = new HashMap<String, JCheckBox>();
private Map<String, JSlider> sliderMap = new HashMap<String, JSlider>();
private Map<String, JComboBox> comboMap = new HashMap<String, JComboBox>();
private Map<String, Chooser> chooserMap = new HashMap<String, Chooser>();
private Map<String, JLabel> reminderMap = new HashMap<String, JLabel>();
private GridBagConstraints gridC = new GridBagConstraints();
private Component nameStrut = Box.createHorizontalStrut(1);
private Component valueStrut = Box.createHorizontalStrut(120);
private Component reminderStrut = Box.createHorizontalStrut(90);
private boolean remindersVisible;
public FieldEditorPanel( boolean remindersVisible ) {
super( new GridBagLayout() );
this.remindersVisible = remindersVisible;
gridC.anchor = GridBagConstraints.WEST;
gridC.fill = GridBagConstraints.HORIZONTAL;
gridC.weightx = 0.0;
gridC.weighty = 0.0;
gridC.gridwidth = 1;
gridC.gridx = 0;
gridC.gridy = 0;
// No default width for col 0.
gridC.gridx = 0;
this.add( nameStrut, gridC );
gridC.gridx++;
this.add( valueStrut, gridC );
gridC.gridx++;
if ( remindersVisible ) {
this.add( reminderStrut, gridC );
gridC.gridy++;
}
gridC.insets = new Insets(2, 4, 2, 4);
}
public void setNameWidth( int width ) {
nameStrut.setMinimumSize( new Dimension(width, 0) );
nameStrut.setPreferredSize( new Dimension(width, 0) );
}
public void setValueWidth( int width ) {
valueStrut.setMinimumSize( new Dimension(width, 0) );
valueStrut.setPreferredSize( new Dimension(width, 0) );
}
public void setReminderWidth( int width ) {
reminderStrut.setMinimumSize( new Dimension(width, 0) );
reminderStrut.setPreferredSize( new Dimension(width, 0) );
}
/**
* Constructs JComponents for a given type of value.
* A row consists of a static label, some JComponent,
* and a reminder label.
*
* The component and reminder will be accessable later
* via getter methods.
*/
public void addRow( String valueName, ContentType contentType ) {
gridC.fill = GridBagConstraints.HORIZONTAL;
gridC.gridwidth = 1;
gridC.weighty = 0.0;
gridC.gridx = 0;
this.add( new JLabel( valueName +":" ), gridC );
gridC.gridx++;
if ( contentType == ContentType.WRAPPED_LABEL ) {
gridC.anchor = GridBagConstraints.WEST;
JTextArea valueArea = new JTextArea();
valueArea.setBackground(null);
valueArea.setEditable( false );
valueArea.setBorder(null);
valueArea.setLineWrap( true );
valueArea.setWrapStyleWord( true );
valueArea.setFocusable( false );
valueArea.setFont( UIManager.getFont("Label.font") );
wrappedLabelMap.put( valueName, valueArea );
this.add( valueArea, gridC );
}
else if ( contentType == ContentType.LABEL ) {
gridC.anchor = GridBagConstraints.WEST;
JLabel valueLbl = new JLabel();
valueLbl.setHorizontalAlignment( SwingConstants.CENTER );
labelMap.put( valueName, valueLbl );
this.add( valueLbl, gridC );
}
else if ( contentType == ContentType.STRING ) {
gridC.anchor = GridBagConstraints.WEST;
JTextField valueField = new JTextField();
stringMap.put( valueName, valueField );
this.add( valueField, gridC );
}
else if ( contentType == ContentType.INTEGER ) {
gridC.anchor = GridBagConstraints.WEST;
JTextField valueField = new JTextField();
valueField.setHorizontalAlignment( JTextField.RIGHT );
valueField.setDocument( new RegexDocument("[0-9]*") );
intMap.put( valueName, valueField );
this.add( valueField, gridC );
}
else if ( contentType == ContentType.BOOLEAN ) {
gridC.anchor = GridBagConstraints.CENTER;
JCheckBox valueCheck = new JCheckBox();
valueCheck.setHorizontalAlignment( SwingConstants.CENTER );
boolMap.put( valueName, valueCheck );
this.add( valueCheck, gridC );
}
else if ( contentType == ContentType.SLIDER ) {
gridC.anchor = GridBagConstraints.CENTER;
JPanel panel = new JPanel();
panel.setLayout( new BoxLayout(panel, BoxLayout.X_AXIS) );
final JSlider valueSlider = new JSlider( JSlider.HORIZONTAL );
valueSlider.setPreferredSize( new Dimension(50, valueSlider.getPreferredSize().height) );
sliderMap.put( valueName, valueSlider );
panel.add(valueSlider);
final JTextField valueField = new JTextField(3);
valueField.setMaximumSize( valueField.getPreferredSize() );
valueField.setHorizontalAlignment( JTextField.RIGHT );
valueField.setEditable( false );
panel.add(valueField);
this.add( panel, gridC );
valueSlider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
valueField.setText( ""+valueSlider.getValue() );
}
});
}
else if ( contentType == ContentType.COMBO ) {
gridC.anchor = GridBagConstraints.CENTER;
JComboBox valueCombo = new JComboBox();
valueCombo.setEditable(false);
comboMap.put( valueName, valueCombo );
this.add( valueCombo, gridC );
}
else if ( contentType == ContentType.CHOOSER ) {
gridC.anchor = GridBagConstraints.WEST;
JPanel panel = new JPanel();
panel.setLayout( new BoxLayout(panel, BoxLayout.X_AXIS) );
JTextField chooserField = new JTextField();
panel.add( chooserField );
panel.add( Box.createHorizontalStrut( 5 ) );
JButton chooserBtn = new JButton( "..." );
chooserBtn.setMargin( new Insets(1,2,1,2) );
panel.add( chooserBtn );
Chooser valueChooser = new Chooser( chooserField, chooserBtn );
chooserMap.put( valueName, valueChooser );
this.add( panel, gridC );
}
gridC.gridx++;
if ( remindersVisible ) {
gridC.anchor = GridBagConstraints.WEST;
JLabel valueReminder = new JLabel();
reminderMap.put( valueName, valueReminder );
this.add( valueReminder, gridC );
}
gridC.gridy++;
}
public void addTextRow( String text ) {
gridC.fill = GridBagConstraints.HORIZONTAL;
gridC.weighty = 0.0;
gridC.gridwidth = GridBagConstraints.REMAINDER;
gridC.gridx = 0;
gridC.anchor = GridBagConstraints.WEST;
JTextArea textArea = new JTextArea( text );
textArea.setBackground(null);
textArea.setEditable( false );
textArea.setBorder(null);
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
textArea.setFocusable( false );
textArea.setFont( UIManager.getFont("Label.font") );
this.add( textArea, gridC );
gridC.gridy++;
}
public void addSeparatorRow() {
gridC.fill = GridBagConstraints.HORIZONTAL;
gridC.weighty = 0.0;
gridC.gridwidth = GridBagConstraints.REMAINDER;
gridC.gridx = 0;
JPanel panel = new JPanel();
panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) );
panel.add( Box.createVerticalStrut(10) );
JSeparator sep = new JSeparator();
sep.setPreferredSize( new Dimension(1, sep.getPreferredSize().height) );
panel.add( sep );
panel.add( Box.createVerticalStrut(10) );
this.add( panel, gridC );
gridC.gridy++;
}
public void addBlankRow() {
gridC.fill = GridBagConstraints.NONE;
gridC.weighty = 0.0;
gridC.gridwidth = GridBagConstraints.REMAINDER;
gridC.gridx = 0;
this.add( Box.createVerticalStrut(12), gridC );
gridC.gridy++;
}
public void addFillRow() {
gridC.fill = GridBagConstraints.VERTICAL;
gridC.weighty = 1.0;
gridC.gridwidth = GridBagConstraints.REMAINDER;
gridC.gridx = 0;
this.add( Box.createVerticalGlue(), gridC );
gridC.gridy++;
}
public void setStringAndReminder( String valueName, String s ) {
JTextField valueField = stringMap.get( valueName );
if ( valueField != null ) valueField.setText(s);
if ( remindersVisible ) setReminder( valueName, s );
}
public void setIntAndReminder( String valueName, int n ) {
setIntAndReminder( valueName, n, ""+n );
}
public void setIntAndReminder( String valueName, int n, String s ) {
JTextField valueField = intMap.get( valueName );
if ( valueField != null ) valueField.setText( ""+n );
if ( remindersVisible ) setReminder( valueName, s );
}
public void setBoolAndReminder( String valueName, boolean b ) {
setBoolAndReminder( valueName, b, ""+b );
}
public void setBoolAndReminder( String valueName, boolean b, String s ) {
JCheckBox valueCheck = boolMap.get( valueName );
if ( valueCheck != null ) valueCheck.setSelected(b);
if ( remindersVisible ) setReminder( valueName, s );
}
public void setSliderAndReminder( String valueName, int n ) {
setSliderAndReminder( valueName, n, ""+n );
}
public void setSliderAndReminder( String valueName, int n, String s ) {
JSlider valueSlider = sliderMap.get( valueName );
if ( valueSlider != null ) valueSlider.setValue(n);
if ( remindersVisible ) setReminder( valueName, s );
}
public void setComboAndReminder( String valueName, Object o ) {
setComboAndReminder( valueName, o, o.toString() );
}
public void setComboAndReminder( String valueName, Object o, String s ) {
JComboBox valueCombo = comboMap.get( valueName );
if ( valueCombo != null ) valueCombo.setSelectedItem(o);
if ( remindersVisible ) setReminder( valueName, s );
}
public void setChooserAndReminder( String valueName, String s ) {
Chooser valueChooser = chooserMap.get( valueName );
if ( valueChooser != null ) valueChooser.getTextField().setText(s);
if ( remindersVisible ) setReminder( valueName, s );
}
public void setReminder( String valueName, String s ) {
JLabel valueReminder = reminderMap.get( valueName );
if ( valueReminder != null ) valueReminder.setText( "( "+ s +" )" );
}
public JTextArea getWrappedLabel( String valueName ) {
return wrappedLabelMap.get( valueName );
}
public JLabel getLabel( String valueName ) {
return labelMap.get( valueName );
}
public JTextField getString( String valueName ) {
return stringMap.get( valueName );
}
public JTextField getInt( String valueName ) {
return intMap.get( valueName );
}
public JCheckBox getBoolean( String valueName ) {
return boolMap.get( valueName );
}
public JSlider getSlider( String valueName ) {
return sliderMap.get( valueName );
}
public JComboBox getCombo( String valueName ) {
return comboMap.get( valueName );
}
public Chooser getChooser( String valueName ) {
return chooserMap.get( valueName );
}
public void reset() {
for ( JTextArea valueArea : wrappedLabelMap.values() )
valueArea.setText("");
for ( JLabel valueLbl : labelMap.values() )
valueLbl.setText("");
for ( JTextField valueField : stringMap.values() )
valueField.setText("");
for ( JTextField valueField : intMap.values() )
valueField.setText("");
for ( JCheckBox valueCheck : boolMap.values() )
valueCheck.setSelected(false);
for ( JSlider valueSlider : sliderMap.values() )
valueSlider.setValue(0);
for ( JComboBox valueCombo : comboMap.values() )
valueCombo.removeAllItems();
for ( Chooser valueChooser : chooserMap.values() )
valueChooser.getTextField().setText("");
for ( JLabel valueReminder : reminderMap.values() )
valueReminder.setText("");
}
@Override
public void removeAll() {
labelMap.clear();
stringMap.clear();
intMap.clear();
boolMap.clear();
sliderMap.clear();
comboMap.clear();
reminderMap.clear();
super.removeAll();
gridC = new GridBagConstraints();
gridC.anchor = GridBagConstraints.WEST;
gridC.fill = GridBagConstraints.HORIZONTAL;
gridC.weightx = 0.0;
gridC.weighty = 0.0;
gridC.gridwidth = 1;
gridC.gridx = 0;
gridC.gridy = 0;
// No default width for col 0.
gridC.gridx = 0;
this.add( Box.createVerticalStrut(1), gridC );
gridC.gridx++;
this.add( valueStrut, gridC );
gridC.gridx++;
if ( remindersVisible ) {
this.add( reminderStrut, gridC );
gridC.gridy++;
}
gridC.insets = new Insets(2, 4, 2, 4);
}
public static class Chooser {
private JTextField textField;
private JButton button;
public Chooser( JTextField textField, JButton button ) {
this.textField = textField;
this.button = button;
}
public JTextField getTextField() { return textField; }
public JButton getButton() { return button; }
}
}

View file

@ -84,6 +84,7 @@ import net.vhati.modmanager.ui.InertPanel;
import net.vhati.modmanager.ui.ModInfoArea; import net.vhati.modmanager.ui.ModInfoArea;
import net.vhati.modmanager.ui.ModPatchDialog; import net.vhati.modmanager.ui.ModPatchDialog;
import net.vhati.modmanager.ui.ModXMLSandbox; import net.vhati.modmanager.ui.ModXMLSandbox;
import net.vhati.modmanager.ui.SlipstreamConfigDialog;
import net.vhati.modmanager.ui.Statusbar; import net.vhati.modmanager.ui.Statusbar;
import net.vhati.modmanager.ui.StatusbarMouseListener; import net.vhati.modmanager.ui.StatusbarMouseListener;
import net.vhati.modmanager.ui.TableRowTransferHandler; import net.vhati.modmanager.ui.TableRowTransferHandler;
@ -131,6 +132,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
private JMenuItem rescanMenuItem; private JMenuItem rescanMenuItem;
private JMenuItem extractDatsMenuItem; private JMenuItem extractDatsMenuItem;
private JMenuItem sandboxMenuItem; private JMenuItem sandboxMenuItem;
private JMenuItem configMenuItem;
private JMenuItem exitMenuItem; private JMenuItem exitMenuItem;
private JMenu helpMenu; private JMenu helpMenu;
private JMenuItem aboutMenuItem; private JMenuItem aboutMenuItem;
@ -296,6 +298,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
log.error( String.format( "Error writing config to \"%s\".", appConfig.getConfigFile() ), f ); log.error( String.format( "Error writing config to \"%s\".", appConfig.getConfigFile() ), f );
} }
System.gc(); // Ward off an intermittent InterruptedException from exit()?
System.exit( 0 ); System.exit( 0 );
} }
}); });
@ -367,6 +370,10 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
sandboxMenuItem.addMouseListener( new StatusbarMouseListener( this, "Experiment with advanced mod syntax." ) ); sandboxMenuItem.addMouseListener( new StatusbarMouseListener( this, "Experiment with advanced mod syntax." ) );
sandboxMenuItem.addActionListener(this); sandboxMenuItem.addActionListener(this);
fileMenu.add( sandboxMenuItem ); fileMenu.add( sandboxMenuItem );
configMenuItem = new JMenuItem( "Preferences..." );
configMenuItem.addMouseListener( new StatusbarMouseListener( this, "Edit preferences." ) );
configMenuItem.addActionListener(this);
fileMenu.add( configMenuItem );
fileMenu.add( new JSeparator() ); fileMenu.add( new JSeparator() );
exitMenuItem = new JMenuItem( "Exit" ); exitMenuItem = new JMenuItem( "Exit" );
exitMenuItem.addMouseListener( new StatusbarMouseListener( this, "Exit this application." ) ); exitMenuItem.addMouseListener( new StatusbarMouseListener( this, "Exit this application." ) );
@ -915,6 +922,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
extractDlg.setVisible( true ); extractDlg.setVisible( true );
} }
else if ( source == sandboxMenuItem ) { else if ( source == sandboxMenuItem ) {
setStatusText( "" );
File datsDir = new File( appConfig.getProperty( "ftl_dats_path" ) ); File datsDir = new File( appConfig.getProperty( "ftl_dats_path" ) );
File dataDatFile = new File( datsDir, "data.dat" ); File dataDatFile = new File( datsDir, "data.dat" );
@ -924,6 +932,15 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
sandboxFrame.setLocationRelativeTo( null ); sandboxFrame.setLocationRelativeTo( null );
sandboxFrame.setVisible( true ); sandboxFrame.setVisible( true );
} }
else if ( source == configMenuItem ) {
setStatusText( "" );
SlipstreamConfigDialog configFrame = new SlipstreamConfigDialog( appConfig );
configFrame.addWindowListener( nerfListener );
//configFrame.setSize( 300, 400 );
configFrame.setLocationRelativeTo( null );
configFrame.setVisible( true );
}
else if ( source == exitMenuItem ) { else if ( source == exitMenuItem ) {
setStatusText( "" ); setStatusText( "" );
exitApp(); exitApp();
@ -995,6 +1012,11 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
/**
* Toggles a main window's nerfed state as popups are opened/disposed.
*
* Requires: setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE ).
*/
private static class NerfListener extends WindowAdapter { private static class NerfListener extends WindowAdapter {
private Nerfable nerfObj; private Nerfable nerfObj;
@ -1007,7 +1029,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
nerfObj.setNerfed( true ); nerfObj.setNerfed( true );
} }
@Override @Override
public void windowClosing( WindowEvent e ) { public void windowClosed( WindowEvent e ) {
nerfObj.setNerfed( false ); nerfObj.setNerfed( false );
} }
} }

View file

@ -93,6 +93,7 @@ public class ModXMLSandbox extends JFrame implements ActionListener {
public ModXMLSandbox( File dataDatFile ) { public ModXMLSandbox( File dataDatFile ) {
super( "Mod XML Sandbox" ); super( "Mod XML Sandbox" );
this.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
this.dataDatFile = dataDatFile; this.dataDatFile = dataDatFile;

View file

@ -0,0 +1,62 @@
package net.vhati.modmanager.ui;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
/**
* When applied to a JTextField via setDocument(), you can only enter a limited set of characters.
*/
public class RegexDocument extends PlainDocument {
private boolean dontCheck = false;
private Pattern p = null;
public RegexDocument( String regex ) {
if ( regex == null || regex.length()==0 ) dontCheck = true;
try {
p = Pattern.compile(regex);
} catch (PatternSyntaxException e) {dontCheck = true;}
}
public RegexDocument() {
dontCheck = true;
}
@Override
public void insertString( int offs, String str, AttributeSet a ) throws BadLocationException {
if ( str == null ) return;
boolean proceed = true;
if ( dontCheck == false ) {
String tmp = super.getText(0, offs) + str + (super.getLength()>offs ? super.getText(offs,super.getLength()-offs) : "");
Matcher m = p.matcher(tmp);
proceed = m.matches();
}
if ( proceed == true ) super.insertString( offs, str, a );
}
@Override
public void remove( int offs, int len ) throws BadLocationException {
boolean proceed = true;
if ( dontCheck == false ) {
try {
String tmp = super.getText(0, offs) + (super.getLength()>(offs+len) ? super.getText(offs+len, super.getLength()-(offs+len)) : "");
Matcher m = p.matcher(tmp);
proceed = m.matches();
} catch (BadLocationException f) {}
}
if ( proceed == true ) super.remove( offs, len );
}
}

View file

@ -0,0 +1,171 @@
package net.vhati.modmanager.ui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import net.vhati.modmanager.core.FTLUtilities;
import net.vhati.modmanager.core.SlipstreamConfig;
import net.vhati.modmanager.ui.FieldEditorPanel;
import net.vhati.modmanager.ui.FieldEditorPanel.ContentType;
public class SlipstreamConfigDialog extends JFrame implements ActionListener {
protected static final String ALLOW_ZIP = "allow_zip";
protected static final String NEVER_RUN_FTL = "never_run_ftl";
protected static final String USE_DEFAULT_UI = "use_default_ui";
protected static final String REMEMBER_GEOMETRY = "remember_geometry";
protected static final String UPDATE_CATALOG = "update_catalog";
protected static final String UPDATE_APP = "update_app";
protected static final String FTL_DATS_PATH = "ftl_dats_path";
protected SlipstreamConfig appConfig;
protected FieldEditorPanel editorPanel;
protected JButton applyBtn;
public SlipstreamConfigDialog( SlipstreamConfig appConfig ) {
super( "Preferences..." );
this.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
this.appConfig = appConfig;
editorPanel = new FieldEditorPanel( false );
editorPanel.setBorder( BorderFactory.createEmptyBorder( 10, 10, 0, 10 ) );
editorPanel.setNameWidth( 250 );
editorPanel.addRow( ALLOW_ZIP, ContentType.BOOLEAN );
editorPanel.addTextRow( "Treat .zip files as .ftl files." );
editorPanel.addSeparatorRow();
editorPanel.addRow( NEVER_RUN_FTL, ContentType.BOOLEAN );
editorPanel.addTextRow( "Don't offer to run FTL after patching." );
editorPanel.addSeparatorRow();
editorPanel.addRow( USE_DEFAULT_UI, ContentType.BOOLEAN );
editorPanel.addTextRow( "Don't attempt to resemble a native GUI." );
editorPanel.addSeparatorRow();
editorPanel.addRow( REMEMBER_GEOMETRY, ContentType.BOOLEAN );
editorPanel.addTextRow( "Save window geometry on exit." );
editorPanel.addSeparatorRow();
editorPanel.addRow( UPDATE_CATALOG, ContentType.INTEGER );
editorPanel.addTextRow( "Check for new mod descriptions every N days. (0 to disable)" );
editorPanel.addSeparatorRow();
editorPanel.addRow( UPDATE_APP, ContentType.INTEGER );
editorPanel.addTextRow( "Check for newer app versions every N days. (0 to disable)" );
editorPanel.addSeparatorRow();
editorPanel.addRow( FTL_DATS_PATH, ContentType.CHOOSER );
editorPanel.addTextRow( "Path to FTL's resources folder." );
editorPanel.addSeparatorRow();
editorPanel.addBlankRow();
editorPanel.addTextRow( "Note: Some changes may have no immediate effect." );
editorPanel.addBlankRow();
editorPanel.addFillRow();
editorPanel.getBoolean( ALLOW_ZIP ).setSelected( appConfig.getProperty( ALLOW_ZIP, "false" ).equals( "true" ) );
editorPanel.getBoolean( NEVER_RUN_FTL ).setSelected( appConfig.getProperty( NEVER_RUN_FTL, "false" ).equals( "true" ) );
editorPanel.getBoolean( USE_DEFAULT_UI ).setSelected( appConfig.getProperty( USE_DEFAULT_UI, "false" ).equals( "true" ) );
editorPanel.getBoolean( REMEMBER_GEOMETRY ).setSelected( appConfig.getProperty( REMEMBER_GEOMETRY, "true" ).equals( "true" ) );
editorPanel.getInt( UPDATE_CATALOG ).setText( Integer.toString(appConfig.getPropertyAsInt( UPDATE_CATALOG, 0 )) );
editorPanel.getInt( UPDATE_APP ).setText( Integer.toString(appConfig.getPropertyAsInt( UPDATE_APP, 0 )) );
JTextField ftlDatsPathField = editorPanel.getChooser( FTL_DATS_PATH ).getTextField();
ftlDatsPathField.setText( appConfig.getProperty( FTL_DATS_PATH, "" ) );
ftlDatsPathField.setPreferredSize( new Dimension(150, ftlDatsPathField.getPreferredSize().height) );
editorPanel.getChooser( FTL_DATS_PATH ).getButton().addActionListener(this);
JPanel ctrlPanel = new JPanel();
ctrlPanel.setLayout( new BoxLayout( ctrlPanel, BoxLayout.X_AXIS ) );
ctrlPanel.setBorder( BorderFactory.createEmptyBorder( 10, 0, 10, 0 ) );
ctrlPanel.add( Box.createHorizontalGlue() );
applyBtn = new JButton( "Apply" );
applyBtn.addActionListener(this);
ctrlPanel.add( applyBtn );
ctrlPanel.add( Box.createHorizontalGlue() );
final JScrollPane editorScroll = new JScrollPane( editorPanel );
editorScroll.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );
editorScroll.getVerticalScrollBar().setUnitIncrement( 10 );
int vbarWidth = editorScroll.getVerticalScrollBar().getPreferredSize().width;
editorScroll.setPreferredSize( new Dimension(editorPanel.getPreferredSize().width+vbarWidth+5, 400) );
JPanel contentPane = new JPanel( new BorderLayout() );
contentPane.add( editorScroll, BorderLayout.CENTER );
contentPane.add( ctrlPanel, BorderLayout.SOUTH );
this.setContentPane( contentPane );
this.pack();
this.setMinimumSize( new Dimension(250, 250) );
editorScroll.addAncestorListener(new AncestorListener() {
@Override
public void ancestorAdded( AncestorEvent e ) {
editorScroll.getViewport().setViewPosition( new Point(0, 0) );
}
@Override
public void ancestorMoved( AncestorEvent e ) {
}
@Override
public void ancestorRemoved( AncestorEvent e ) {
}
});
}
@Override
public void actionPerformed( ActionEvent e ) {
Object source = e.getSource();
if ( source == applyBtn ) {
String tmp;
appConfig.setProperty( ALLOW_ZIP, editorPanel.getBoolean( ALLOW_ZIP ).isSelected() ? "true" : "false" );
appConfig.setProperty( NEVER_RUN_FTL, editorPanel.getBoolean( NEVER_RUN_FTL ).isSelected() ? "true" : "false" );
appConfig.setProperty( USE_DEFAULT_UI, editorPanel.getBoolean( USE_DEFAULT_UI ).isSelected() ? "true" : "false" );
appConfig.setProperty( REMEMBER_GEOMETRY, editorPanel.getBoolean( REMEMBER_GEOMETRY ).isSelected() ? "true" : "false" );
tmp = editorPanel.getInt( UPDATE_CATALOG ).getText();
try {
int n = Integer.parseInt( tmp );
n = Math.max( 0, n );
appConfig.setProperty( UPDATE_CATALOG, Integer.toString( n ) );
}
catch ( NumberFormatException f ) {}
tmp = editorPanel.getInt( UPDATE_APP ).getText();
try {
int n = Integer.parseInt( tmp );
n = Math.max( 0, n );
appConfig.setProperty( UPDATE_APP, Integer.toString( n ) );
}
catch ( NumberFormatException f ) {}
tmp = editorPanel.getChooser( FTL_DATS_PATH ).getTextField().getText();
if ( tmp.length() > 0 && FTLUtilities.isDatsDirValid( new File(tmp) ) ) {
appConfig.setProperty( FTL_DATS_PATH, tmp );
}
this.setVisible( false );
this.dispose();
}
else if ( source == editorPanel.getChooser( FTL_DATS_PATH ).getButton() ) {
File datsDir = FTLUtilities.promptForDatsDir( this );
if ( datsDir != null ) {
editorPanel.getChooser( FTL_DATS_PATH ).getTextField().setText( datsDir.getAbsolutePath() );
}
}
}
}