/* * SpellChoicePanel.java * Copyright 2013 (C) James Dempsey <jdempsey@users.sourceforge.net> * * 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 09/10/2013 * * $Id$ */ package pcgen.gui2.equip; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import pcgen.facade.core.AbilityFacade; import pcgen.facade.core.InfoFacade; import pcgen.facade.core.SpellBuilderFacade; import pcgen.facade.util.event.ListEvent; import pcgen.gui2.tabs.models.CharacterComboBoxModel; import pcgen.gui2.util.FacadeListModel; import pcgen.system.LanguageBundle; /** * SpellChoicePanel provides the user interface for the user to select a spell. * * @author James Dempsey <jdempsey@users.sourceforge.net> */ @SuppressWarnings("serial") public class SpellChoicePanel extends JPanel { private final JComboBox classComboBox; private final JComboBox spellLevelComboBox; private final JComboBox spellComboBox; private final JComboBox variantComboBox; private final JComboBox casterLevelComboBox; private final JComboBox spellTypeComboBox; private final JList metamagicList; private CharacterComboBoxModel<InfoFacade> classModel; private CharacterComboBoxModel<Integer> spellLevelModel; private CharacterComboBoxModel<InfoFacade> spellModel; private CharacterComboBoxModel<String> variantModel; private CharacterComboBoxModel<Integer> casterLevelModel; private CharacterComboBoxModel<String> spellTypeModel; private SpellBuilderFacade spellBuilderFacade; private MetamagicFeatListModel metamgicModel; /** * Create a new spell choice panel instance. * @param spellBuilderFacade The facade that manages the selection. */ public SpellChoicePanel(SpellBuilderFacade spellBuilderFacade) { this.spellBuilderFacade = spellBuilderFacade; this.classComboBox = new JComboBox(); this.spellLevelComboBox = new JComboBox(); this.spellComboBox = new JComboBox(); this.variantComboBox = new JComboBox(); this.casterLevelComboBox = new JComboBox(); this.spellTypeComboBox = new JComboBox(); this.metamagicList = new JList(); initModels(); initComponents(); } /** * Create the various box models which will drive the choices. */ private void initModels() { classModel = new CharacterComboBoxModel<InfoFacade>() { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setClass((InfoFacade) anItem); } }; classModel.setListFacade(spellBuilderFacade.getClasses()); classModel.setReference(spellBuilderFacade.getClassRef()); classComboBox.setModel(classModel); spellLevelModel = new CharacterComboBoxModel<Integer>() { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setSpellLevel((Integer) anItem); } }; spellLevelModel.setListFacade(spellBuilderFacade.getLevels()); spellLevelModel.setReference(spellBuilderFacade.getSpellLevelRef()); spellLevelComboBox.setModel(spellLevelModel); spellModel = new CharacterComboBoxModel<InfoFacade>() { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setSpell((InfoFacade) anItem); } }; spellModel.setListFacade(spellBuilderFacade.getSpells()); spellModel.setReference(spellBuilderFacade.getSpellRef()); spellComboBox.setModel(spellModel); variantModel = new DisablingCharacterComboBoxModel(variantComboBox) { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setVariant((String) anItem); } }; variantModel.setListFacade(spellBuilderFacade.getVariants()); variantModel.setReference(spellBuilderFacade.getVariantRef()); variantComboBox.setModel(variantModel); casterLevelModel = new CharacterComboBoxModel<Integer>() { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setCasterLevel((Integer) anItem); } }; casterLevelModel.setListFacade(spellBuilderFacade.getCasterLevels()); casterLevelModel.setReference(spellBuilderFacade.getCasterLevelRef()); casterLevelComboBox.setModel(casterLevelModel); spellTypeModel = new CharacterComboBoxModel<String>() { @Override public void setSelectedItem(Object anItem) { spellBuilderFacade.setSpellType((String) anItem); } }; spellTypeModel.setListFacade(spellBuilderFacade.getSpellTypes()); spellTypeModel.setReference(spellBuilderFacade.getSpellTypeRef()); spellTypeComboBox.setModel(spellTypeModel); metamgicModel = new MetamagicFeatListModel(); metamgicModel.setListFacade(spellBuilderFacade.getAvailMetamagicFeats()); metamagicList.setModel(metamgicModel); metamagicList.addListSelectionListener(metamgicModel); } /** * Initialise the on screen components. */ private void initComponents() { setLayout(new GridBagLayout()); addGridBagLayer(this, "in_sumClass", classComboBox); //$NON-NLS-1$ addGridBagLayer(this, "in_csdSpLvl", spellLevelComboBox); //$NON-NLS-1$ spellComboBox .setPrototypeDisplayValue("PrototypeDisplayValueForAVeryLongSpellName"); //$NON-NLS-1$ addGridBagLayer(this, "in_spellName", spellComboBox); //$NON-NLS-1$ addGridBagLayer(this, "in_csdVariant", variantComboBox); //$NON-NLS-1$ if (metamgicModel.getSize() > 0) { metamagicList .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); metamagicList.setVisibleRowCount(4); JScrollPane listScroller = new JScrollPane(metamagicList); listScroller.setPreferredSize(new Dimension(250, 80)); addGridBagLayer(this, "in_metaFeat", listScroller); //$NON-NLS-1$ } addGridBagLayer(this, "in_casterLvl", casterLevelComboBox); //$NON-NLS-1$ addGridBagLayer(this, "in_csdSpellType", spellTypeComboBox); //$NON-NLS-1$ setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); } private void addGridBagLayer(JPanel panel, String text, JComponent comp) { Insets insets = new Insets(0, 0, 3, 2); GridBagConstraints gbc = new GridBagConstraints(); JLabel label = new JLabel(LanguageBundle.getString(text)); gbc.anchor = java.awt.GridBagConstraints.WEST; gbc.gridwidth = 2; panel.add(label, gbc); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; if (insets != null) { gbc.insets = insets; } panel.add(comp, gbc); } /** * DisablingCharacterComboBoxModel is a model that disables its combo box * when there are no possible selections. */ private abstract class DisablingCharacterComboBoxModel extends CharacterComboBoxModel<String> { private JComboBox box; DisablingCharacterComboBoxModel(JComboBox box) { this.box = box; } @Override public void elementsChanged(ListEvent<String> e) { super.elementsChanged(e); box.setEnabled(getSize() > 0); } } /** * MetamagicFeatListModel holds the data for a list of metamagic feats and * commits the choices mode into the facade. */ private class MetamagicFeatListModel extends FacadeListModel<AbilityFacade> implements ListSelectionListener { @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } List selectedValues = metamagicList.getSelectedValuesList(); spellBuilderFacade.setSelectedMetamagicFeats(selectedValues.toArray()); } } }