// // @(#)NGDStartOptions.java 4/2002 // // Copyright 2002 Zachary DelProposto. All rights reserved. // Use is subject to license terms. // // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Or from http://www.gnu.org/ // package dip.gui.dialog.newgame; import dip.world.*; import dip.world.variant.data.Variant; import dip.gui.swing.*; import dip.misc.Utils; import cz.autel.dmi.HIGConstraints; import cz.autel.dmi.HIGLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.JSeparator; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * * Defines the game starting options for the New Game dialog. * <p> * This allows the user to alter any game parameters before the * game starts. * <p> * Reset button allows reversion to defaults. */ public class NGDStartOptions extends JPanel implements NewGameDialog.NGDTabPane { // constants private static final int BORDER = 5; private static final String TAB_NAME = "NGDoptions.tab.name"; private static final String BUTTON_RESET = "NGDoptions.button_reset"; private static final String LABEL_TIME = "NGDoptions.label_time"; private static final String LABEL_VC = "NGDoptions.label_vc"; private static final String LABEL_VC_SC_REQ = "NGDoptions.label_vc_sc_req"; private static final String LABEL_VC_SC_NOCHANGE = "NGDoptions.label_vc_sc_nochange"; private static final String LABEL_VC_DURATION = "NGDoptions.label_vc_duration"; private static final String INTRO_TEXT_LOCATION = "NGDoptions.location_intro_text"; // instance variables private Variant current = null; // current variant private Variant original = null; // GUI controls private JComboBox phaseBox; private BCSpinner year; private JSpinner vcSC; private JSpinner vcSCChange; private JSpinner vcDuration; private JButton reset; private JEditorPane introText; /** Create the StartOptions panel for the New Game dialog */ public NGDStartOptions() { // create GUI controls phaseBox = new JComboBox(); phaseBox.setEditable(false); year = new BCSpinner(1, 1, 9999); vcSC = makeCustomSpinner(true); vcSCChange = makeCustomSpinner(true); vcDuration = makeCustomSpinner(true); reset = new JButton( Utils.getLocalString(BUTTON_RESET) ); reset.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(original != null) { resetData(); } } }); introText = Utils.createTextLabel(true); introText.setText( Utils.getText(Utils.getLocalString(INTRO_TEXT_LOCATION)) ); introText.setMargin(new Insets(10,0,10,0)); makeLayout(); }// NGDStartOptions() /** Gets the (possibly) modified Variant */ public synchronized Variant getVariant() { // set game time StringBuffer sb = new StringBuffer(); sb.append( phaseBox.getSelectedItem() ); sb.append(' '); sb.append( year.getValue() ); current.setStartingPhase( Phase.parse(sb.toString()) ); // set victory conditions current.setNumSCForVictory( getSpinnerValue(vcSC) ); current.setMaxYearsNoSCChange( getSpinnerValue(vcSCChange) ); current.setMaxGameTimeYears( getSpinnerValue(vcDuration) ); return current; }// getVariant() /** Enables & Disables controls on this panel */ public void setEnabled(boolean value) { phaseBox.setEnabled(value); year.setEnabled(value); vcSC.setEnabled(value); vcSCChange.setEnabled(value); vcDuration.setEnabled(value); reset.setEnabled(value); introText.setEnabled(value); super.setEnabled(value); }// setEnabled() /** Set data from originally passed reference */ private void resetData() { Phase phase = original.getStartingPhase(); // set combo box phaseBox.removeAllItems(); String[] combos = Phase.getAllSeasonPhaseCombos(); String protoType = combos[0]; for(int i=0; i<combos.length; i++) { phaseBox.addItem(combos[i]); protoType = (combos[i].length() > protoType.length()) ? combos[i] : protoType; } phaseBox.setPrototypeDisplayValue(protoType+"M"); // set currently selected phaseBox.setSelectedItem(phase.getSeasonType() + " " +phase.getPhaseType()); // set if we can display 'bc' years if(original.getBCYearsAllowed()) { year.setMinimum(-9999); // 9999 BC is earliest } else { year.setMinimum(1); // no earlier than 1 AD } // set year year.setValue(phase.getYear()); // set spinners setSpinner(vcSC, original.getNumSCForVictory(), 1, original.getSupplyCenters().length); setSpinner(vcSCChange, original.getMaxYearsNoSCChange(), 0, 9999); setSpinner(vcDuration, original.getMaxGameTimeYears(), 0, 9999); }// resetData() /** Layout the panel */ private void makeLayout() { int w1[] = { BORDER, 15, 0, 0, BORDER }; int h1[] = { BORDER, 0,10, 0,5, 0,20, 0,5, 0,5, 0,5, 0,5, 0, 0, 5, 0, BORDER }; // create 'minipanels': these put labels and spinners horizontally adjacent JPanel timePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); timePanel.add(phaseBox); timePanel.add(year); JPanel vc1 = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); vc1.add(vcSC); vc1.add(new JLabel( Utils.getLocalString(LABEL_VC_SC_REQ) )); JPanel vc2 = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); vc2.add(vcSCChange); vc2.add(new JLabel( Utils.getLocalString(LABEL_VC_SC_NOCHANGE) )); JPanel vc3 = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); vc3.add(vcDuration); vc3.add(new JLabel( Utils.getLocalString(LABEL_VC_DURATION) )); // higlayout HIGLayout l1 = new HIGLayout(w1, h1); l1.setColumnWeight(4, 1); l1.setRowWeight(16, 1); setLayout(l1); HIGConstraints c = new HIGConstraints(); add(introText, c.rcwh(2,2,3,1,"lrtb")); add(new GradientJLabel(Utils.getLocalString(LABEL_TIME)), c.rcwh(4,2,2,1,"lr")); add(timePanel, c.rc(6,3,"l")); add(new GradientJLabel(Utils.getLocalString(LABEL_VC)), c.rcwh(8,2,2,1,"lr")); add(vc1, c.rc(10,3,"l")); add(vc2, c.rc(12,3,"l")); add(vc3, c.rc(14,3,"l")); add(new JSeparator(), c.rcwh(17,2,3,1,"lr")); add(reset, c.rcwh(19,2,2,1,"l")); }// makeLayout() /** * Creates a custom spinner. Custom spinners have no commas in the numbers, * and cannot be negative. 0 is acceptable. Maximum is set to 9999 by default. * <p> * useSeparator: determine if grouping separator is used for numbers. */ private JSpinner makeCustomSpinner(boolean useSeparator) { SpinnerNumberModel model = new SpinnerNumberModel(0, 0, 9999, 1); JSpinner spinner = new JSpinner(model); new JSpinner.NumberEditor(spinner, "0000"); if(!useSeparator) { // remove comma (grouping separator) ((JSpinner.NumberEditor) spinner.getEditor()).getFormat().setGroupingUsed(false); } return spinner; }// makeCustomSpinner() /** Conveniently sets spinner values & handles any details */ private void setSpinner(JSpinner spinner, int value, int min, int max) { SpinnerNumberModel snn = (SpinnerNumberModel) spinner.getModel(); snn.setMinimum(new Integer(min)); snn.setMaximum(new Integer(max)); snn.setValue(new Integer(value)); }// setSpinner() /** Convenience method: get int from spinner */ private int getSpinnerValue(JSpinner spinner) { return ((Integer) spinner.getValue()).intValue(); }// getSpinnerValue() /** Get the tab name. */ public String getTabName() { return Utils.getLocalString(TAB_NAME); }// getTabName() /** The Variant has Changed. */ public void variantChanged(Variant variant) { // store passed reference, but modify the cloned version original = variant; try { current = (Variant) variant.clone(); } catch(CloneNotSupportedException e) { throw new IllegalStateException(e.getMessage()); } resetData(); revalidate(); }// variantChanged() /** The Enabled status has Changed. */ public void enablingChanged(boolean enabled) { setEnabled(enabled); }// enablingChanged() }// class NGDStartOptions