/* * CharacterStatsPanel.java * Copyright 2008 (C) James Dempsey * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on 26/10/2008 14:38:01 * * $Id: $ */ package pcgen.gui2.prefs; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Collection; import java.util.List; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JRadioButton; import javax.swing.border.Border; import javax.swing.border.TitledBorder; import pcgen.cdom.base.Constants; import pcgen.cdom.content.RollMethod; import pcgen.cdom.reference.ReferenceManufacturer; import pcgen.core.GameMode; import pcgen.core.PointBuyMethod; import pcgen.core.SettingsHandler; import pcgen.gui2.util.JComboBoxEx; import pcgen.gui2.tools.Utility; import pcgen.system.LanguageBundle; /** * The Class {@code CharacterStatsPanel} is responsible for managing * the character stats preferences. * * * @author James Dempsey <jdempsey@users.sourceforge.net> */ @SuppressWarnings("serial") public class CharacterStatsPanel extends PCGenPrefsPanel { private static String in_abilities = LanguageBundle.getString("in_Prefs_abilities"); private String[] pMode; private String[] pModeMethodName; private JDialog parent; private JRadioButton abilitiesAllSameButton; private JRadioButton abilitiesPurchasedButton; private JRadioButton abilitiesRolledButton; private JRadioButton abilitiesUserRolledButton; private JComboBoxEx abilityPurchaseModeCombo; private JComboBoxEx abilityRolledModeCombo = null; private JComboBoxEx abilityScoreCombo; private JButton purchaseModeButton; private PurchaseModeFrame pmsFrame = null; private ActionListener rolledModeListener; private ActionListener purchaseModeListener; private ActionListener scoreListener; /** * Instantiates a new character stats panel. * * @param parent the parent dialog */ public CharacterStatsPanel(JDialog parent) { this.parent = parent; initComponents(); addAbilitiesPanelListeners(); } /** * Build and initialise the user interface. */ private void initComponents() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); JLabel label; ButtonGroup exclusiveGroup; Border etched = null; TitledBorder title1 = BorderFactory.createTitledBorder(etched, in_abilities); title1.setTitleJustification(TitledBorder.LEFT); this.setBorder(title1); this.setLayout(gridbag); c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.NORTHWEST; c.insets = new Insets(2, 2, 2, 2); final GameMode gameMode = SettingsHandler.getGame(); int row = 0; exclusiveGroup = new ButtonGroup(); Utility.buildConstraints(c, 0, row++, 3, 1, 0, 0); label = new JLabel(LanguageBundle.getFormattedString( "in_Prefs_abilitiesGenLabel", gameMode.getDisplayName())); //$NON-NLS-1$ gridbag.setConstraints(label, c); this.add(label); Utility.buildConstraints(c, 0, row, 1, 1, 0, 0); label = new JLabel(" "); gridbag.setConstraints(label, c); this.add(label); Utility.buildConstraints(c, 1, row++, 2, 1, 0, 0); abilitiesUserRolledButton = new JRadioButton(LanguageBundle .getString("in_Prefs_abilitiesUserRolled")); gridbag.setConstraints(abilitiesUserRolledButton, c); this.add(abilitiesUserRolledButton); exclusiveGroup.add(abilitiesUserRolledButton); Utility.buildConstraints(c, 1, row++, 2, 1, 0, 0); abilitiesAllSameButton = new JRadioButton(LanguageBundle .getString("in_Prefs_abilitiesAllSame") + ": "); gridbag.setConstraints(abilitiesAllSameButton, c); this.add(abilitiesAllSameButton); exclusiveGroup.add(abilitiesAllSameButton); Utility.buildConstraints(c, 1, row, 1, 1, 0, 0); label = new JLabel(" "); gridbag.setConstraints(label, c); this.add(label); Utility.buildConstraints(c, 2, row++, 2, 1, 0, 0); abilityScoreCombo = new JComboBoxEx(); for (int i = gameMode.getStatMin(); i <= gameMode.getStatMax(); ++i) { abilityScoreCombo.addItem(String.valueOf(i)); } gridbag.setConstraints(abilityScoreCombo, c); this.add(abilityScoreCombo); ReferenceManufacturer<RollMethod> mfg = gameMode.getModeContext().getReferenceContext() .getManufacturer(RollMethod.class); List<RollMethod> rollMethods = mfg.getOrderSortedObjects(); if (!rollMethods.isEmpty()) { Utility.buildConstraints(c, 1, row++, 2, 1, 0, 0); abilitiesRolledButton = new JRadioButton("Rolled:"); gridbag.setConstraints(abilitiesRolledButton, c); this.add(abilitiesRolledButton); exclusiveGroup.add(abilitiesRolledButton); Utility.buildConstraints(c, 2, row++, 2, 1, 0, 0); abilityRolledModeCombo = new JComboBoxEx(); for (RollMethod rm : rollMethods) { abilityRolledModeCombo.addItem(rm.getDisplayName()); } gridbag.setConstraints(abilityRolledModeCombo, c); this.add(abilityRolledModeCombo); } Collection<PointBuyMethod> methods = SettingsHandler.getGame() .getModeContext().getReferenceContext() .getConstructedCDOMObjects(PointBuyMethod.class); final int purchaseMethodCount = methods.size(); Utility.buildConstraints(c, 1, row++, 2, 1, 0, 0); abilitiesPurchasedButton = new JRadioButton(LanguageBundle .getString("in_Prefs_abilitiesPurchased") + ": "); gridbag.setConstraints(abilitiesPurchasedButton, c); this.add(abilitiesPurchasedButton); exclusiveGroup.add(abilitiesPurchasedButton); Utility.buildConstraints(c, 2, row++, 2, 1, 0, 0); pMode = new String[purchaseMethodCount]; pModeMethodName = new String[purchaseMethodCount]; int i = 0; for (PointBuyMethod pbm : methods) { pMode[i] = pbm.getDescription(); pModeMethodName[i] = pbm.getDisplayName(); i++; } abilityPurchaseModeCombo = new JComboBoxEx(pMode); gridbag.setConstraints(abilityPurchaseModeCombo, c); this.add(abilityPurchaseModeCombo); // // Hide controls if there are no entries to select // if (purchaseMethodCount == 0) { abilityPurchaseModeCombo.setVisible(false); abilitiesPurchasedButton.setVisible(false); } Utility.buildConstraints(c, 1, row++, 1, 1, 0, 0); label = new JLabel(" "); gridbag.setConstraints(label, c); this.add(label); Utility.buildConstraints(c, 1, row++, 3, 1, 0, 0); purchaseModeButton = new JButton(LanguageBundle .getString("in_Prefs_purchaseModeConfig")); gridbag.setConstraints(purchaseModeButton, c); this.add(purchaseModeButton); purchaseModeButton.addActionListener(new PurchaseModeButtonListener()); Utility.buildConstraints(c, 5, 20, 1, 1, 1, 1); c.fill = GridBagConstraints.BOTH; label = new JLabel(" "); gridbag.setConstraints(label, c); this.add(label); } /* (non-Javadoc) * @see pcgen.gui2.prefs.PCGenPrefsPanel#applyOptionValuesToControls() */ @Override public void applyOptionValuesToControls() { stopListeners(); final GameMode gameMode = SettingsHandler.getGame(); boolean bValid = true; final int rollMethod = gameMode.getRollMethod(); switch (rollMethod) { case Constants.CHARACTER_STAT_METHOD_USER: abilitiesUserRolledButton.setSelected(true); break; case Constants.CHARACTER_STAT_METHOD_ALL_THE_SAME: abilitiesAllSameButton.setSelected(true); break; case Constants.CHARACTER_STAT_METHOD_PURCHASE: if (!abilitiesPurchasedButton.isVisible() || (pMode.length == 0)) { bValid = false; } else { abilitiesPurchasedButton.setSelected(true); } break; case Constants.CHARACTER_STAT_METHOD_ROLLED: if (abilitiesRolledButton == null) { bValid = false; } else { abilitiesRolledButton.setSelected(true); abilityRolledModeCombo.setSelectedItem(gameMode .getRollMethodExpressionName()); } break; default: bValid = false; break; } if (!bValid) { abilitiesUserRolledButton.setSelected(true); gameMode.setRollMethod(Constants.CHARACTER_STAT_METHOD_USER); } int allStatsValue = Math.min(gameMode.getStatMax(), gameMode.getAllStatsValue()); allStatsValue = Math.max(gameMode.getStatMin(), allStatsValue); gameMode.setAllStatsValue(allStatsValue); abilityScoreCombo.setSelectedIndex(allStatsValue - gameMode.getStatMin()); if ((pMode != null) && (pModeMethodName != null)) { final String methodName = gameMode.getPurchaseModeMethodName(); for (int i = 0; i < pMode.length; ++i) { if (pModeMethodName[i].equals(methodName)) { abilityPurchaseModeCombo.setSelectedIndex(i); } } } startListeners(); } /** * Create and display purchase mode stats popup frame. */ private void showPurchaseModeConfiguration() { if (pmsFrame == null) { pmsFrame = new PurchaseModeFrame(parent); final GameMode gameMode = SettingsHandler.getGame(); pmsFrame.setStatMin(gameMode.getStatMin()); pmsFrame.setStatMax(gameMode.getStatMax()); // add a listener to know when the window has closed pmsFrame.addWindowListener(new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { Collection<PointBuyMethod> methods = SettingsHandler .getGame().getModeContext().getReferenceContext() .getConstructedCDOMObjects(PointBuyMethod.class); final int purchaseMethodCount = methods.size(); pMode = new String[purchaseMethodCount]; pModeMethodName = new String[purchaseMethodCount]; final String methodName = SettingsHandler.getGame() .getPurchaseModeMethodName(); abilityPurchaseModeCombo.removeAllItems(); int i = 0; for (PointBuyMethod pbm : methods) { pMode[i] = pbm.getDescription(); pModeMethodName[i] = pbm.getDisplayName(); abilityPurchaseModeCombo.addItem(pMode[i]); if (pModeMethodName[i].equals(methodName)) { abilityPurchaseModeCombo.setSelectedIndex(i); } i++; } // free resources pmsFrame = null; // // If user has added at least one method, then make the controls visible. Otherwise // it is not a valid choice and cannot be selected, so hide it. // abilityPurchaseModeCombo .setVisible(purchaseMethodCount != 0); abilitiesPurchasedButton .setVisible(purchaseMethodCount != 0); // // If no longer visible, but was selected, then use 'user rolled' instead // if (!abilitiesPurchasedButton.isVisible() && abilitiesPurchasedButton.isSelected()) { abilitiesUserRolledButton.setSelected(true); } } }); } Utility.centerComponent(pmsFrame); // ensure the frame is visible (in case user selects menu item again). pmsFrame.setVisible(true); } /** * Create and add the listeners for the panel. */ private void addAbilitiesPanelListeners() { scoreListener = evt -> abilitiesAllSameButton.setSelected(true); purchaseModeListener = evt -> abilitiesPurchasedButton.setSelected(true); rolledModeListener = evt -> abilitiesRolledButton.setSelected(true); startListeners(); } /** * Start the listeners that track changing data. These have to * be stopped when updating data programatically to avoid * spurious setting of dirty flags etc. */ private void startListeners() { abilityScoreCombo.addActionListener(scoreListener); abilityPurchaseModeCombo.addActionListener(purchaseModeListener); if (abilityRolledModeCombo != null) { abilityRolledModeCombo.addActionListener(rolledModeListener); } } /** * Stop the listeners that track changing data. These have to * be stopped when updating data programatically to avoid * spurious setting of dirty flags etc. */ private void stopListeners() { abilityScoreCombo.removeActionListener(scoreListener); abilityPurchaseModeCombo.removeActionListener(purchaseModeListener); if (abilityRolledModeCombo != null) { abilityRolledModeCombo.removeActionListener(rolledModeListener); } } /* (non-Javadoc) * @see pcgen.gui2.prefs.PCGenPrefsPanel#getTitle() */ @Override public String getTitle() { return in_abilities; } /* (non-Javadoc) * @see pcgen.gui2.prefs.PCGenPrefsPanel#setOptionsBasedOnControls() */ @Override public void setOptionsBasedOnControls() { final GameMode gameMode = SettingsHandler.getGame(); gameMode.setAllStatsValue(abilityScoreCombo.getSelectedIndex() + gameMode.getStatMin()); if (abilitiesUserRolledButton.isSelected()) { gameMode.setRollMethod(Constants.CHARACTER_STAT_METHOD_USER); } else if (abilitiesAllSameButton.isSelected()) { gameMode.setRollMethod(Constants.CHARACTER_STAT_METHOD_ALL_THE_SAME); } else if (abilitiesPurchasedButton.isSelected()) { if (abilityPurchaseModeCombo.isVisible() && (abilityPurchaseModeCombo.getSelectedIndex() >= 0)) { gameMode .setPurchaseMethodName(pModeMethodName[abilityPurchaseModeCombo .getSelectedIndex()]); } else { gameMode.setRollMethod(Constants.CHARACTER_STAT_METHOD_USER); } } else if ((abilitiesRolledButton != null) && (abilitiesRolledButton.isSelected())) { if (abilityRolledModeCombo.getSelectedIndex() >= 0) { gameMode.setRollMethodExpressionByName(abilityRolledModeCombo .getSelectedItem().toString()); } else { gameMode.setRollMethod(Constants.CHARACTER_STAT_METHOD_USER); } } } /** * Handler for the Purchase Mode Config button. */ private final class PurchaseModeButtonListener implements ActionListener { /* (non-Javadoc) * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) */ @Override public void actionPerformed(ActionEvent actionEvent) { showPurchaseModeConfiguration(); } } /** * @param parent the parent to set */ public void setParent(JDialog parent) { this.parent = parent; } }