/*
* PurchaseModeFrame.java
* Copyright 2002 (C) Chris Ryan
*
* 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
*
*/
package pcgen.gui2.prefs;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.AbstractButton;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.table.AbstractTableModel;
import pcgen.cdom.base.Constants;
import pcgen.core.CustomData;
import pcgen.core.Globals;
import pcgen.core.PointBuyCost;
import pcgen.core.PointBuyMethod;
import pcgen.core.RuleConstants;
import pcgen.core.SettingsHandler;
import pcgen.core.utils.MessageType;
import pcgen.core.utils.ShowMessageDelegate;
import pcgen.gui2.util.JComboBoxEx;
import pcgen.rules.context.AbstractReferenceContext;
import pcgen.system.LanguageBundle;
/**
* The Class {@code PurchaseModeFrame} is responsible for displaying
* the character stats purchase mode (aka point buy) configuration dialog.
*
*
* @author Chris Ryan
*/
public final class PurchaseModeFrame extends JDialog
{
private static final long serialVersionUID = -5244500546425680322L;
private static final String TITLE = LanguageBundle.getString("in_Prefs_purModConf"); //$NON-NLS-1$
private static final int STANDARD_MIN_PURCHASE_SCORE = 8;
private static final int STANDARD_MAX_PURCHASE_SCORE = 18;
private JButton removeMethodButton = null;
private JComboBoxEx currentPurchaseMethods = null;
private JLabel statusBar;
private JScrollPane jScrollPane1;
private JTextField purchaseMethodPointsEdit;
private JTextField purchaseScoreMaxEdit;
private JTextField purchaseScoreMinEdit;
private PurchaseModel purchaseModel = null;
private int statMin = PurchaseModeFrame.STANDARD_MIN_PURCHASE_SCORE;
private int statMax = PurchaseModeFrame.STANDARD_MAX_PURCHASE_SCORE;
/** Creates new form PurchaseModeFrame */
private PurchaseModeFrame()
{
initComponents();
}
/** Creates new form PurchaseModeFrame
* @param parent
* */
PurchaseModeFrame(Dialog parent)
{
super(parent);
initComponents();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
new PurchaseModeFrame().setVisible(true);
}
//
// Pop up a window to get information about a new purchase method
//
private void addMethodButtonActionPerformed()
{
NewPurchaseMethodDialog npmd = new NewPurchaseMethodDialog(this, true);
npmd.setVisible(true);
if (!npmd.getWasCancelled())
{
final String methodName = npmd.getEnteredName();
if (SettingsHandler.getGame().getModeContext().getReferenceContext().silentlyGetConstructedCDOMObject(
PointBuyMethod.class, methodName) == null)
{
PointBuyMethod pbm = new PointBuyMethod();
pbm.setName(methodName);
pbm.setPointFormula(Integer.toString(npmd.getEnteredPoints()));
currentPurchaseMethods.addItem(pbm);
currentPurchaseMethods.setSelectedItem(pbm);
}
else
{
ShowMessageDelegate.showMessageDialog(
LanguageBundle.getString("in_Prefs_cannotAdd"), //$NON-NLS-1$
Constants.APPLICATION_NAME, MessageType.ERROR);
}
}
}
private void cancelButtonActionPerformed()
{
dispose();
}
private static int convertStringToInt(String valueString)
{
int value;
try
{
value = Integer.parseInt(valueString);
}
catch (final NumberFormatException nfe)
{
// bad value
value = -1;
}
return value;
}
/**
* Display info about the selected purchase method.
*/
private void currentPurchaseMethodsActionPerformed()
{
final PointBuyMethod method = (PointBuyMethod) currentPurchaseMethods.getSelectedItem();
if (method == null)
{
removeMethodButton.setEnabled(false);
purchaseMethodPointsEdit.setText(""); //$NON-NLS-1$
}
else
{
purchaseMethodPointsEdit.setText(method.getPointFormula());
removeMethodButton.setEnabled(true);
}
}
/** Exit Purchase Mode Frame */
private void exitForm()
{
// TODO
}
private void initComponents()
{
purchaseScoreMinEdit = new JTextField(3);
purchaseScoreMaxEdit = new JTextField(3);
statusBar = new JLabel();
currentPurchaseMethods = new JComboBoxEx();
currentPurchaseMethods.setAutoSort(true);
purchaseMethodPointsEdit = new JTextField(4);
removeMethodButton = new JButton();
AbstractButton okButton = new JButton();
okButton.addActionListener(e -> CustomData.writePurchaseModeConfiguration());
jScrollPane1 = new JScrollPane();
getContentPane().setLayout(new GridBagLayout());
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setTitle(PurchaseModeFrame.TITLE);
addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent evt)
{
exitForm();
}
});
Container jPanel1 = new JPanel();
jPanel1.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5));
JLabel purchaseScoreMinLabel = new JLabel();
purchaseScoreMinLabel.setText(LanguageBundle.getString("in_Prefs_purchMin")); //$NON-NLS-1$
purchaseScoreMinLabel.setToolTipText(LanguageBundle.getString("in_Prefs_purchMinTip")); //$NON-NLS-1$
purchaseScoreMinLabel.setPreferredSize(new Dimension(140, 15));
jPanel1.add(purchaseScoreMinLabel);
purchaseScoreMinEdit.setHorizontalAlignment(SwingConstants.RIGHT);
purchaseScoreMinEdit.addActionListener(evt -> purchaseScoreMinValueActionPerformed());
purchaseScoreMinEdit.addFocusListener(new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
purchaseScoreMinValueActionPerformed();
}
});
jPanel1.add(purchaseScoreMinEdit);
AbstractButton purchaseScoreMinIncreaseButton = new JButton();
purchaseScoreMinIncreaseButton.setText(LanguageBundle.getString("in_Prefs_plus")); //$NON-NLS-1$
purchaseScoreMinIncreaseButton.setToolTipText(LanguageBundle.getString("in_Prefs_incMin")); //$NON-NLS-1$
purchaseScoreMinIncreaseButton.addActionListener(evt -> purchaseScoreMinIncreaseButtonActionPerformed());
jPanel1.add(purchaseScoreMinIncreaseButton);
AbstractButton purchaseScoreMinDecreaseButton = new JButton();
purchaseScoreMinDecreaseButton.setText(LanguageBundle.getString("in_Prefs_minus")); //$NON-NLS-1$
purchaseScoreMinDecreaseButton.setToolTipText(LanguageBundle.getString("in_Prefs_decMin")); //$NON-NLS-1$
purchaseScoreMinDecreaseButton.addActionListener(evt -> purchaseScoreMinDecreaseButtonActionPerformed());
jPanel1.add(purchaseScoreMinDecreaseButton);
GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
getContentPane().add(jPanel1, gridBagConstraints);
Container jPanel2 = new JPanel();
jPanel2.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5));
JLabel purchaseScoreMaxLabel = new JLabel();
purchaseScoreMaxLabel.setText(LanguageBundle.getString("in_Prefs_purchMax")); //$NON-NLS-1$
purchaseScoreMaxLabel.setToolTipText(LanguageBundle.getString("in_Prefs_purchMaxTip")); //$NON-NLS-1$
purchaseScoreMaxLabel.setPreferredSize(new Dimension(140, 15));
jPanel2.add(purchaseScoreMaxLabel);
purchaseScoreMaxEdit.setHorizontalAlignment(SwingConstants.RIGHT);
purchaseScoreMaxEdit.addActionListener(evt -> purchaseScoreMaxValueActionPerformed());
purchaseScoreMaxEdit.addFocusListener(new FocusAdapter()
{
@Override
public void focusLost(FocusEvent e)
{
purchaseScoreMaxValueActionPerformed();
}
});
jPanel2.add(purchaseScoreMaxEdit);
AbstractButton purchaseScoreMaxIncreaseButton = new JButton();
purchaseScoreMaxIncreaseButton.setText(LanguageBundle.getString("in_Prefs_plus")); //$NON-NLS-1$
purchaseScoreMaxIncreaseButton.setToolTipText(LanguageBundle.getString("in_Prefs_incMax")); //$NON-NLS-1$
purchaseScoreMaxIncreaseButton.addActionListener(evt -> purchaseScoreMaxIncreaseButtonActionPerformed());
jPanel2.add(purchaseScoreMaxIncreaseButton);
AbstractButton purchaseScoreMaxDecreaseButton = new JButton();
purchaseScoreMaxDecreaseButton.setText(LanguageBundle.getString("in_Prefs_minus")); //$NON-NLS-1$
purchaseScoreMaxDecreaseButton.setToolTipText(LanguageBundle.getString("in_Prefs_decMax")); //$NON-NLS-1$
purchaseScoreMaxDecreaseButton.addActionListener(evt -> purchaseScoreMaxDecreaseButtonActionPerformed());
jPanel2.add(purchaseScoreMaxDecreaseButton);
GridBagConstraints bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 2;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
getContentPane().add(jPanel2, bagConstraints);
JComponent purchaseMethodPanel = new JPanel();
purchaseMethodPanel.setLayout(new GridBagLayout());
purchaseMethodPanel.setBorder(BorderFactory.createTitledBorder(
LanguageBundle.getString("in_Prefs_allowPoints"))); //$NON-NLS-1$
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 3;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
getContentPane().add(purchaseMethodPanel, bagConstraints);
Container purchaseMethodNamePanel = new JPanel();
purchaseMethodNamePanel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5));
JLabel savedMethodLabel = new JLabel();
savedMethodLabel.setText(LanguageBundle.getString("in_Prefs_savedMethods")); //$NON-NLS-1$
savedMethodLabel.setPreferredSize(new Dimension(140, 15));
purchaseMethodNamePanel.add(savedMethodLabel);
purchaseMethodNamePanel.add(currentPurchaseMethods);
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 0;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
getContentPane().add(purchaseMethodNamePanel, bagConstraints);
purchaseMethodPanel.add(purchaseMethodNamePanel, bagConstraints);
Container purchaseMethodPointsPanel = new JPanel();
purchaseMethodPointsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 5));
JLabel methodPointsLabel = new JLabel();
methodPointsLabel.setText(LanguageBundle.getString("in_Prefs_points")); //$NON-NLS-1$
methodPointsLabel.setPreferredSize(new Dimension(140, 15));
purchaseMethodPointsPanel.add(methodPointsLabel);
purchaseMethodPointsEdit.setHorizontalAlignment(SwingConstants.RIGHT);
purchaseMethodPointsEdit.setEditable(false);
//purchaseMethodPointsEdit.setText("10");
purchaseMethodPointsPanel.add(purchaseMethodPointsEdit);
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 1;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
// getContentPane().add(purchaseMethodPointsPanel, gridBagConstraints);
purchaseMethodPanel.add(purchaseMethodPointsPanel, bagConstraints);
currentPurchaseMethods.setPreferredSize(new Dimension(140, 21));
currentPurchaseMethods.addItemListener(evt -> currentPurchaseMethodsActionPerformed());
Container purchaseMethodButtonPanel = new JPanel();
purchaseMethodButtonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
AbstractButton addMethodButton = new JButton();
addMethodButton.setText(LanguageBundle.getString("in_Prefs_new")); //$NON-NLS-1$
addMethodButton.addActionListener(evt -> addMethodButtonActionPerformed());
purchaseMethodButtonPanel.add(addMethodButton);
removeMethodButton.setText(LanguageBundle.getString("in_Prefs_remove")); //$NON-NLS-1$
removeMethodButton.addActionListener(evt -> removeMethodButtonActionPerformed());
purchaseMethodButtonPanel.add(removeMethodButton);
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 2;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
purchaseMethodPanel.add(purchaseMethodButtonPanel, bagConstraints);
statusBar.setText(LanguageBundle.getString("in_Prefs_setCost")); //$NON-NLS-1$
statusBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 6;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.ipadx = 1;
bagConstraints.ipady = 1;
bagConstraints.insets = new Insets(1, 1, 1, 1);
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
getContentPane().add(statusBar, bagConstraints);
Container jPanel3 = new JPanel();
jPanel3.setLayout(new FlowLayout(FlowLayout.RIGHT));
okButton.setText(LanguageBundle.getString("in_Prefs_OK")); //$NON-NLS-1$
okButton.setToolTipText(LanguageBundle.getString("in_Prefs_OKTip")); //$NON-NLS-1$
okButton.addActionListener(evt -> okButtonActionPerformed());
jPanel3.add(okButton);
AbstractButton resetButton = new JButton();
resetButton.setText(LanguageBundle.getString("in_Prefs_Reset")); //$NON-NLS-1$
resetButton.setToolTipText(LanguageBundle.getString("in_Prefs_ResetTip")); //$NON-NLS-1$
resetButton.addActionListener(evt -> resetButtonActionPerformed());
jPanel3.add(resetButton);
AbstractButton cancelButton = new JButton();
cancelButton.setText(LanguageBundle.getString("in_cancel")); //$NON-NLS-1$
cancelButton.setToolTipText(LanguageBundle.getString("in_Prefs_CancelTip")); //$NON-NLS-1$
cancelButton.addActionListener(evt -> cancelButtonActionPerformed());
jPanel3.add(cancelButton);
/////////////////////////////////////////////////
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 5;
bagConstraints.fill = GridBagConstraints.HORIZONTAL;
bagConstraints.anchor = GridBagConstraints.EAST;
bagConstraints.weightx = 1.0;
getContentPane().add(jPanel3, bagConstraints);
jScrollPane1.setViewportBorder(new BevelBorder(BevelBorder.LOWERED));
jScrollPane1.setPreferredSize(new Dimension(100, 200));
purchaseModel = new PurchaseModel();
renewAbilityScoreCostTable();
bagConstraints = new GridBagConstraints();
bagConstraints.gridx = 0;
bagConstraints.gridy = 0;
bagConstraints.fill = GridBagConstraints.BOTH;
bagConstraints.anchor = GridBagConstraints.NORTHWEST;
bagConstraints.weightx = 1.0;
bagConstraints.weighty = 1.0;
getContentPane().add(jScrollPane1, bagConstraints);
pack();
initializeCurrentPurchaseMethods();
}
private void initializeCurrentPurchaseMethods()
{
//
// Set up the current methods combo's contents
//
Collection<PointBuyMethod> methods = SettingsHandler.getGame()
.getModeContext().getReferenceContext()
.getConstructedCDOMObjects(PointBuyMethod.class);
if (!methods.isEmpty())
{
currentPurchaseMethods.setModel(new DefaultComboBoxModel(methods.toArray()));
}
currentPurchaseMethodsActionPerformed(); // Get into correct state
}
private void okButtonActionPerformed()
{
purchaseModel.keepNewValues();
dispose();
}
private void purchaseScoreMaxDecreaseButtonActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMax();
// get the current value from the edit field
String valueString = purchaseScoreMaxEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMaxValue(value-1))
{
return;
}
// decrease the value in the model
statusBar.setText(""); //$NON-NLS-1$
if (!purchaseModel.setPurchaseScoreMax(value - 1))
{
// set a status message
statusBar.setText(LanguageBundle.getString("in_Prefs_maxBelowMin")); //$NON-NLS-1$
}
// ensure the edit value gets updated correctly
updatePurchaseScoreMax(oldValue);
}
private void purchaseScoreMaxIncreaseButtonActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMax();
// get the current value from the edit field
String valueString = purchaseScoreMaxEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMaxValue(value+1))
{
return;
}
// increase the value in the model
statusBar.setText(""); //$NON-NLS-1$
boolean updateOk = purchaseModel.setPurchaseScoreMax(value + 1);
// ensure the edit value gets updated correctly
updatePurchaseScoreMax(oldValue);
if (updateOk)
{
purchaseModel.setValueAt(purchaseModel.predictNextPurchaseCostMax(),
purchaseModel.getRowCount() - 1, 1);
}
}
private void purchaseScoreMaxValueActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMax();
// get the current value from the edit field
String valueString = purchaseScoreMaxEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMaxValue(value))
{
return;
}
// increase the value in the model
statusBar.setText(""); //$NON-NLS-1$
boolean updateOk = purchaseModel.setPurchaseScoreMax(value);
// ensure the edit value gets updated correctly
updatePurchaseScoreMax(oldValue);
if (updateOk)
{
purchaseModel.setValueAt(purchaseModel.predictNextPurchaseCostMax(),
purchaseModel.getRowCount() - 1, 1);
}
}
private boolean validateNewMaxValue(int value)
{
if (!Globals.checkRule(RuleConstants.ABILRANGE))
{
if (value > statMax)
{
statusBar.setText(
LanguageBundle.getFormattedString("in_Prefs_mayNotInc", //$NON-NLS-1$
statMax));
return false;
}
}
return true;
}
private void purchaseScoreMinDecreaseButtonActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMin();
// get the current value from the edit field
String valueString = purchaseScoreMinEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMinValue(value-1))
{
return;
}
boolean updateOk = purchaseModel.setPurchaseScoreMin(value - 1);
// decrease the value in the model
if (updateOk)
{
statusBar.setText("");
}
else
{
// set a status message
statusBar.setText(LanguageBundle.getString("in_Prefs_noMinBelow0")); //$NON-NLS-1$
}
// ensure the edit value gets updated correctly
updatePurchaseScoreMin(oldValue);
if (updateOk)
{
purchaseModel.setValueAt(purchaseModel.predictNextPurchaseCostMin(), 0, 1);
}
}
private void purchaseScoreMinIncreaseButtonActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMin();
// get the current value from the edit field
String valueString = purchaseScoreMinEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMinValue(value+1))
{
return;
}
// increase the value in the model
statusBar.setText(""); //$NON-NLS-1$
if (!purchaseModel.setPurchaseScoreMin(value + 1))
{
// TODO Disable buttons (then no need for those messages)
// set a status message
statusBar.setText(LanguageBundle.getString("in_Prefs_minExceedMax")); //$NON-NLS-1$
}
// ensure the edit value gets updated correctly
updatePurchaseScoreMin(oldValue);
}
private void purchaseScoreMinValueActionPerformed()
{
int oldValue = purchaseModel.getPurchaseScoreMin();
// get the current value from the edit field
String valueString = purchaseScoreMinEdit.getText();
// convert it to an integer
int value = PurchaseModeFrame.convertStringToInt(valueString);
if (!validateNewMinValue(value))
{
return;
}
// change the value in the model
statusBar.setText(""); //$NON-NLS-1$
if (!purchaseModel.setPurchaseScoreMin(value))
{
// set a status message
statusBar.setText(LanguageBundle.getString("in_Prefs_minExceedMax")); //$NON-NLS-1$
}
// ensure the edit value gets updated correctly
updatePurchaseScoreMin(oldValue);
}
private boolean validateNewMinValue(int value)
{
int unconditionalMin = Math.min(0, statMin);
if (!Globals.checkRule(RuleConstants.ABILRANGE))
{
if (value < statMin)
{
statusBar.setText(
LanguageBundle.getFormattedString("in_Prefs_mayNotDec", //$NON-NLS-1$
statMin));
return false;
}
}
// bad value?
if (value < unconditionalMin)
{
// set a status message
statusBar.setText(LanguageBundle.getFormattedString("in_Prefs_mayNotDec", //$NON-NLS-1$
unconditionalMin)); //$NON-NLS-1$
return false;
}
return true;
}
/**
* Remove the current selection from the list of purchase methods.
*/
private void removeMethodButtonActionPerformed()
{
final PointBuyMethod method = (PointBuyMethod) currentPurchaseMethods.getSelectedItem();
if (method != null)
{
currentPurchaseMethods.removeItem(method);
}
}
private void renewAbilityScoreCostTable()
{
JTable abilityScoreCostTable = new JTable();
abilityScoreCostTable.setBorder(new BevelBorder(BevelBorder.LOWERED));
abilityScoreCostTable.setModel(purchaseModel);
abilityScoreCostTable.setToolTipText(LanguageBundle.getString("in_Prefs_setCost")); //$NON-NLS-1$
jScrollPane1.setViewportView(abilityScoreCostTable);
}
private void resetButtonActionPerformed()
{
//renewAbilityScoreCostTable();
purchaseModel.copySavedToCurrent();
updatePurchaseScoreMin(purchaseModel.getPurchaseScoreMin());
updatePurchaseScoreMax(purchaseModel.getPurchaseScoreMax());
purchaseModel.fireTableStructureChanged();
initializeCurrentPurchaseMethods();
}
private void updatePurchaseScoreMax(int oldValue)
{
int score = purchaseModel.getPurchaseScoreMax();
purchaseScoreMaxEdit.setText(Integer.toString(score));
if (oldValue != score)
{
purchaseModel.appendRows(score - oldValue);
purchaseModel.fireTableStructureChanged();
}
}
private void updatePurchaseScoreMin(int oldValue)
{
int score = purchaseModel.getPurchaseScoreMin();
purchaseScoreMinEdit.setText(Integer.toString(score));
if (oldValue != score)
{
purchaseModel.prependRows(score - oldValue);
purchaseModel.resetAllCosts();
purchaseModel.fireTableStructureChanged();
}
}
/**
* @param statMin The new lowest value a purchase mode can take a stat to.
*/
void setStatMin(int statMin)
{
this.statMin = statMin;
}
/**
* @param statMax The new highest value a purchase mode can take a stat to.
*/
void setStatMax(int statMax)
{
this.statMax = statMax;
}
private final class PurchaseModel extends AbstractTableModel
{
private static final long serialVersionUID = 8257526994109828957L;
private final boolean[] canEdit = {false, true};
private final String[] columnHeaders = {LanguageBundle.getString("in_Prefs_abScore"), //$NON-NLS-1$
LanguageBundle.getString("in_Prefs_cost")}; //$NON-NLS-1$
private Object[][] currentValues = null;
private Object[][] savedValues = null;
private final Class<?>[] types = new Class[]{Integer.class, Integer.class};
private int currentPurchaseScoreMax = 10;
private int currentPurchaseScoreMin = 10; // Start at the average stat
private int savedPurchaseScoreMax = 0;
private int savedPurchaseScoreMin = 0;
private PurchaseModel()
{
// Initialize the saved values
initValues();
// copy the saved values to the current values
copySavedToCurrent();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex)
{
return canEdit[columnIndex];
}
@Override
public Class<?> getColumnClass(int columnIndex)
{
return types[columnIndex];
}
@Override
public int getColumnCount()
{
return columnHeaders.length;
}
@Override
public String getColumnName(int param)
{
return columnHeaders[param];
}
@Override
public int getRowCount()
{
return currentValues.length;
}
@Override
public void setValueAt(Object obj, int row, int column)
{
if ((row < 0) || (row >= currentValues.length))
{
throw new ArrayIndexOutOfBoundsException(
LanguageBundle.getFormattedString("in_Prefs_rowOutBound", row)); //$NON-NLS-1$
}
if ((column == 0) || (column == 1))
{
currentValues[row][column] = obj;
fireTableCellUpdated(row, column);
}
else
{
throw new ArrayIndexOutOfBoundsException(
LanguageBundle.getFormattedString("in_Prefs_columnOutBound", column)); //$NON-NLS-1$
}
}
@Override
public Object getValueAt(int row, int column)
{
if ((row < 0) || (row >= currentValues.length))
{
throw new ArrayIndexOutOfBoundsException(
LanguageBundle.getFormattedString("in_Prefs_rowOutBound", row)); //$NON-NLS-1$
}
if ((column == 0) || (column == 1))
{
return currentValues[row][column];
}
throw new ArrayIndexOutOfBoundsException(
LanguageBundle.getFormattedString("in_Prefs_columnOutBound", column)); //$NON-NLS-1$
}
/**
* Copy the saved purchase mode to the current one
*/
private void copySavedToCurrent()
{
if (savedValues != null)
{
currentPurchaseScoreMin = savedPurchaseScoreMin;
currentPurchaseScoreMax = savedPurchaseScoreMax;
final int nrEntries = (currentPurchaseScoreMax - currentPurchaseScoreMin) + 1;
currentValues = new Object[nrEntries][2];
for (int i = 0; i < nrEntries; ++i)
{
currentValues[i][0] = savedValues[i][0];
currentValues[i][1] = savedValues[i][1];
}
}
}
/**
* Initialise the values
*/
private void initValues()
{
// get the ability score costs from settings
int[] scoreCosts = SettingsHandler.getGame().getAbilityScoreCost();
if (scoreCosts != null)
{
// get the save values from the settings
savedPurchaseScoreMin = SettingsHandler.getGame().getPurchaseScoreMin();
savedPurchaseScoreMax = SettingsHandler.getGame().getPurchaseScoreMax();
savedValues = new Object[scoreCosts.length][2];
for (int i = savedPurchaseScoreMin; i <= savedPurchaseScoreMax; ++i)
{
int index = i - savedPurchaseScoreMin;
savedValues[index][0] = i;
savedValues[index][1] = scoreCosts[index];
}
}
else
{
savedPurchaseScoreMin = 10;
savedPurchaseScoreMax = 10;
savedValues = new Object[1][2];
savedValues[0][0] = 10;
savedValues[0][1] = 0;
}
//
// Make sure the min/max buttons have the correct info
//
purchaseScoreMinEdit.setText(Integer.toString(savedPurchaseScoreMin));
purchaseScoreMaxEdit.setText(Integer.toString(savedPurchaseScoreMax));
}
/** Scale rises in the maximum purchase cost <strong>after</strong> a new, empty cost row has been added.
* @return int
*/
private int predictNextPurchaseCostMax()
{
int maxIndex = getRowCount() - 2; // have already added the new row
int max = (Integer) getValueAt(maxIndex, 1);
if (getRowCount() == 2) // initial and one empty
{
return max + 1;
}
int penultimate = (Integer) getValueAt(maxIndex - 1, 1);
return max + (max - penultimate);
}
/** Scale drops in the minimum purchase cost <strong>after</strong> a new, empty cost row has been added.
* @return int
*/
private int predictNextPurchaseCostMin()
{
int minIndex = 1; // Have already added the new row
int min = (Integer) getValueAt(minIndex, 1);
if (getRowCount() == 2) // initial and one empty
{
return min - 1;
}
int penultimate = (Integer) getValueAt(minIndex + 1, 1);
return min - (penultimate - min);
}
/** Setter for property purchaseScoreMax.
* @param purchaseScoreMax New value of property purchaseScoreMax.
* @return true or false
*/
private boolean setPurchaseScoreMax(int purchaseScoreMax)
{
if ((purchaseScoreMax >= 0) && (purchaseScoreMax >= currentPurchaseScoreMin))
{
currentPurchaseScoreMax = purchaseScoreMax;
return true;
}
return false;
}
/** Getter for property purchaseScoreMax.
* @return Value of property purchaseScoreMax.
*/
private int getPurchaseScoreMax()
{
return currentPurchaseScoreMax;
}
/** Setter for property purchaseScoreMin.
* @param purchaseScoreMin New value of property purchaseScoreMin.
* @return true or false
*/
private boolean setPurchaseScoreMin(int purchaseScoreMin)
{
if (purchaseScoreMin <= currentPurchaseScoreMax)
{
currentPurchaseScoreMin = purchaseScoreMin;
return true;
}
return false;
}
/** Getter for property purchaseScoreMin.
* @return Value of property purchaseScoreMin.
*/
private int getPurchaseScoreMin()
{
return currentPurchaseScoreMin;
}
private void appendRows(int nrRows)
{
final int nrEntries = (currentPurchaseScoreMax - currentPurchaseScoreMin) + 1;
Object[][] newValues = new Object[nrEntries][2];
if (nrRows < 0)
{
// removing rows
System.arraycopy(currentValues, 0, newValues, 0, nrEntries);
}
else
{
// adding rows
System.arraycopy(currentValues, 0, newValues, 0, currentValues.length);
final int preLength = currentValues.length;
for (int i = 0; i < nrRows; ++i)
{
final int score = ((i + currentPurchaseScoreMax) - nrRows) + 1;
newValues[i + preLength][0] = score;
int preVal = -1;
if ((i + preLength) != 0)
{
preVal = (Integer) newValues[(i + preLength) - 1][1];
}
newValues[i + preLength][1] = preVal + 1;
}
}
currentValues = newValues;
}
private void keepNewValues()
{
// set the current values into the settings
SettingsHandler.getGame().clearPointBuyStatCosts();
for (int i = currentPurchaseScoreMin; i <= currentPurchaseScoreMax; ++i)
{
PointBuyCost pbc = new PointBuyCost();
pbc.setName(Integer.toString(i));
pbc.setBuyCost((Integer) currentValues[i - currentPurchaseScoreMin][1]);
SettingsHandler.getGame().addPointBuyStatCost(pbc);
}
AbstractReferenceContext ref = SettingsHandler.getGame().getModeContext().getReferenceContext();
Collection<PointBuyMethod> methods = new ArrayList<>(ref
.getConstructedCDOMObjects(PointBuyMethod.class));
for (int i = 0, x = currentPurchaseMethods.getItemCount(); i < x; ++i)
{
final PointBuyMethod pbm = (PointBuyMethod) currentPurchaseMethods.getItemAt(i);
PointBuyMethod masterPBM = ref
.silentlyGetConstructedCDOMObject(PointBuyMethod.class,
pbm.getKeyName());
if (masterPBM == null)
{
ref.importObject(pbm);
}
else
{
methods.remove(masterPBM);
masterPBM.setPointFormula(pbm.getPointFormula());
}
}
for (final PointBuyMethod pbm : methods)
{
ref.forget(pbm);
}
}
private void prependRows(int nrRows)
{
final int nrEntries = (currentPurchaseScoreMax - currentPurchaseScoreMin) + 1;
Object[][] newValues = new Object[nrEntries][2];
if (nrRows > 0)
{
// removing rows
System.arraycopy(currentValues, nrRows, newValues, 0, nrEntries);
}
else
{
// adding rows
nrRows = Math.abs(nrRows);
System.arraycopy(currentValues, 0, newValues, nrRows, currentValues.length);
//final int tblStart = ((Integer) currentValues[0][1]).intValue();
for (int i = 0; i < nrRows; ++i)
{
final int score = i + currentPurchaseScoreMin;
newValues[i][0] = score;
// newValues[i][1] = Integer.valueOf(tblStart - nrRows + i);
}
}
currentValues = newValues;
}
/**
* Reset the cost of all rows, starting from 0 for the lowest.
*/
private void resetAllCosts()
{
int cost = 0;
for (int i = 0; i < currentValues.length; i++)
{
currentValues[i][1] = cost++;
}
}
}
}