/** * CharacterSheetInfoTab.java Copyright James Dempsey, 2010 * * 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 29/09/2010 7:16:42 PM * * $Id: CharacterSheetInfoTab.java 14593 2011-02-23 06:16:07Z cpmeister $ */ package pcgen.gui2.tabs; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dimension; import java.io.File; import java.util.Arrays; import javax.swing.Box; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.event.ListDataEvent; import pcgen.facade.core.CharacterFacade; import pcgen.facade.core.EquipmentSetFacade; import pcgen.facade.core.GameModeFacade; import pcgen.facade.core.TempBonusFacade; import pcgen.facade.util.event.ListEvent; import pcgen.facade.util.event.ListListener; import pcgen.facade.util.event.ReferenceEvent; import pcgen.facade.util.event.ReferenceListener; import pcgen.facade.util.ListFacades; import pcgen.gui2.csheet.CharacterSheetPanel; import pcgen.gui2.filter.Filter; import pcgen.gui2.filter.FilteredListFacadeTableModel; import pcgen.gui2.tools.FlippingSplitPane; import pcgen.gui2.util.DisplayAwareTab; import pcgen.gui2.util.event.ListDataAdapter; import pcgen.gui2.util.table.TableUtils; import pcgen.system.ConfigurationSettings; import pcgen.system.LanguageBundle; import pcgen.util.Logging; import pcgen.util.enumeration.Tab; /** * The Class {@code CharacterSheetInfoTab} is a placeholder for the * character sheet tab. * * <br> * -0800 (Tue, 22 Feb 2011) $ * * @author James Dempsey <jdempsey@users.sourceforge.net> */ public class CharacterSheetInfoTab extends FlippingSplitPane implements CharacterInfoTab, DisplayAwareTab { /** * Version for serialisation. */ private static final long serialVersionUID = -4957524684640929994L; private final TabTitle tabTitle = new TabTitle(Tab.CHARACTERSHEET); private final CharacterSheetPanel csheet; private final JComboBox sheetBox; private final JTable equipSetTable; private final JTable tempBonusTable; private final JTable tempBonusRowTable; private final JTable equipSetRowTable; /** * Create a new instance of CharacterSheetInfoTab */ @SuppressWarnings("serial") public CharacterSheetInfoTab() { super("CharSheet"); this.csheet = new CharacterSheetPanel(); this.sheetBox = new JComboBox(); this.equipSetTable = TableUtils.createDefaultTable(); this.equipSetRowTable = TableUtils.createDefaultTable(); this.tempBonusTable = TableUtils.createDefaultTable(); this.tempBonusRowTable = TableUtils.createDefaultTable(); setOneTouchExpandable(true); JPanel panel = new JPanel(new BorderLayout()); Box box = Box.createHorizontalBox(); box.add(new JLabel(LanguageBundle.getString("in_character_sheet_label"))); //$NON-NLS-1$ sheetBox.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value instanceof File) { value = ((File) value).getName(); } return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } }); box.add(sheetBox); panel.add(box, BorderLayout.NORTH); FlippingSplitPane subPane = new FlippingSplitPane("CharSheetLeft"); subPane.setOrientation(VERTICAL_SPLIT); equipSetTable.getTableHeader().setReorderingAllowed(false); JScrollPane pane = TableUtils.createRadioBoxSelectionPane(equipSetTable, equipSetRowTable); pane.setPreferredSize(new Dimension(200, 100)); subPane.setTopComponent(pane); tempBonusTable.getTableHeader().setReorderingAllowed(false); pane = TableUtils.createCheckBoxSelectionPane(tempBonusTable, tempBonusRowTable); pane.setPreferredSize(new Dimension(200, 100)); subPane.setBottomComponent(pane); panel.add(subPane, BorderLayout.CENTER); panel.setPreferredSize(panel.getMinimumSize()); setLeftComponent(panel); csheet.setPreferredSize(new Dimension(600, 300)); setRightComponent(csheet); } @Override public ModelMap createModels(CharacterFacade character) { ModelMap models = new ModelMap(); models.put(BoxHandler.class, new BoxHandler(character)); models.put(CSheetHandler.class, new CSheetHandler(character)); models.put(TempBonusTableModel.class, new TempBonusTableModel(character)); models.put(EquipSetTableModel.class, new EquipSetTableModel(character)); return models; } @Override public void restoreModels(ModelMap models) { models.get(BoxHandler.class).install(); models.get(CSheetHandler.class).install(); EquipSetTableModel equipSetModel = models.get(EquipSetTableModel.class); equipSetTable.setModel(equipSetModel); equipSetRowTable.setModel(equipSetModel); TempBonusTableModel tempBonusModel = models.get(TempBonusTableModel.class); tempBonusTable.setModel(tempBonusModel); tempBonusRowTable.setModel(tempBonusModel); } @Override public void storeModels(ModelMap models) { models.get(CSheetHandler.class).uninstall(); } @Override public TabTitle getTabTitle() { return tabTitle; } @Override public void tabSelected() { // Refresh the character sheet as we have been displayed. csheet.refresh(); } private class BoxHandler extends ListDataAdapter { /** * Prefs key for the character sheet for a game mode. */ private CharacterFacade character; private ComboBoxModel model; public BoxHandler(CharacterFacade character) { this.character = character; GameModeFacade game = character.getDataSet().getGameMode(); String previewDir = ConfigurationSettings.getPreviewDir(); File sheetDir = new File(previewDir, game.getCharSheetDir()); if (sheetDir.exists() && sheetDir.isDirectory()) { File[] files = sheetDir.listFiles(pathname -> pathname.isFile() && !pathname.isHidden()); Arrays.sort(files, (f1, f2) -> { // TODO I18N Use a Collator return f1.toString().compareToIgnoreCase(f2.toString()); }); model = new DefaultComboBoxModel(files); File file = null; String previewSheet = character.getPreviewSheetRef().toString(); if (previewSheet == null) { previewSheet = game.getDefaultCharSheet(); } if (previewSheet != null) { file = new File(sheetDir, previewSheet); if (!file.isFile()) { Logging.errorPrint("Invalid Character Sheet: " + file.getAbsolutePath()); //$NON-NLS-1$ } } if ((file == null || !file.isFile()) && game.getDefaultCharSheet() != null) { file = new File(sheetDir, game.getDefaultCharSheet()); } model.setSelectedItem(file); } else { model = new DefaultComboBoxModel(); } model.addListDataListener(this); } public void install() { sheetBox.setModel(model); csheet.setCharacterSheet((File) model.getSelectedItem()); } @Override public void listDataChanged(ListDataEvent e) { if (e.getIndex0() == -1 && e.getIndex1() == -1) { File outputSheet = (File) sheetBox.getSelectedItem(); csheet.setCharacterSheet(outputSheet); csheet.refresh(); character.setPreviewSheet(outputSheet.getName()); } } } private class CSheetHandler implements ListListener<Object>, ReferenceListener<Object> { private CharacterFacade character; private String sheetDir; public CSheetHandler(CharacterFacade character) { this.character = character; } public void install() { csheet.setCharacter(character); // character.getAgeCategoryRef().addReferenceListener(this); // character.getAgeRef().addReferenceListener(this); // character.getAlignmentRef().addReferenceListener(this); // character.getCarriedWeightRef().addReferenceListener(this); // character.getDeityRef().addReferenceListener(this); // character.getGenderRef().addReferenceListener(this); // character.getHandedRef().addReferenceListener(this); // character.getLoadRef().addReferenceListener(this); // character.getNameRef().addReferenceListener(this); // character.getPlayersNameRef().addReferenceListener(this); // character.getRaceRef().addReferenceListener(this); // character.getStatTotalTextRef().addReferenceListener(this); // character.getTotalHPRef().addReferenceListener(this); // character.getXPRef().addReferenceListener(this); // // character.getDomains().addListListener(this); // character.getLanguages().addListListener(this); // character.getTempBonuses().addListListener(this); // character.getTemplates().addListListener(this); } public void uninstall() { // character.getAgeCategoryRef().removeReferenceListener(this); // character.getAgeRef().removeReferenceListener(this); // character.getAlignmentRef().removeReferenceListener(this); // character.getCarriedWeightRef().removeReferenceListener(this); // character.getDeityRef().removeReferenceListener(this); // character.getGenderRef().removeReferenceListener(this); // character.getHandedRef().removeReferenceListener(this); // character.getLoadRef().removeReferenceListener(this); // character.getNameRef().removeReferenceListener(this); // character.getPlayersNameRef().removeReferenceListener(this); // character.getRaceRef().removeReferenceListener(this); // character.getStatTotalTextRef().removeReferenceListener(this); // character.getTotalHPRef().removeReferenceListener(this); // character.getXPRef().removeReferenceListener(this); // // character.getDomains().removeListListener(this); // character.getLanguages().removeListListener(this); // character.getTempBonuses().removeListListener(this); // character.getTemplates().removeListListener(this); } @Override public void elementAdded(ListEvent<Object> e) { csheet.refresh(); } @Override public void elementRemoved(ListEvent<Object> e) { csheet.refresh(); } @Override public void elementsChanged(ListEvent<Object> e) { csheet.refresh(); } @Override public void referenceChanged(ReferenceEvent<Object> e) { csheet.refresh(); } @Override public void elementModified(ListEvent<Object> e) { csheet.refresh(); } } private class TempBonusTableModel extends FilteredListFacadeTableModel<TempBonusFacade> implements Filter<CharacterFacade, TempBonusFacade> { /** * Version for serialisation. */ private static final long serialVersionUID = -2157540968522498242L; private ListListener<TempBonusFacade> listener = new ListListener<TempBonusFacade>() { @Override public void elementAdded(ListEvent<TempBonusFacade> e) { int index = ListFacades.wrap(sortedList).indexOf(e.getElement()); TempBonusTableModel.this.fireTableCellUpdated(index, -1); } @Override public void elementRemoved(ListEvent<TempBonusFacade> e) { int index = ListFacades.wrap(sortedList).indexOf(e.getElement()); TempBonusTableModel.this.fireTableCellUpdated(index, -1); } @Override public void elementsChanged(ListEvent<TempBonusFacade> e) { TempBonusTableModel.this.fireTableRowsUpdated(0, sortedList.getSize() - 1); } @Override public void elementModified(ListEvent<TempBonusFacade> e) { } }; public TempBonusTableModel(CharacterFacade character) { super(character); setDelegate(character.getTempBonuses()); setFilter(this); character.getTempBonuses().addListListener(listener); } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex == -1) { return Boolean.class; } return super.getColumnClass(columnIndex); } @Override protected Object getValueAt(TempBonusFacade element, int column) { switch (column) { case -1: return element.isActive(); case 0: return element; default: return null; } } @Override public int getColumnCount() { return 1; } @Override public String getColumnName(int column) { if (column == 0) { return LanguageBundle.getString("in_InfoTempMod"); //$NON-NLS-1$ } return null; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { TempBonusFacade bonus = sortedList.getElementAt(rowIndex); character.setTempBonusActive(bonus, aValue == Boolean.TRUE); csheet.refresh(); } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex < 0; } @Override public boolean accept(CharacterFacade context, TempBonusFacade element) { return true; } } private class EquipSetTableModel extends FilteredListFacadeTableModel<EquipmentSetFacade> implements ReferenceListener<EquipmentSetFacade>, Filter<CharacterFacade, EquipmentSetFacade> { /** * Version for serialisation. */ private static final long serialVersionUID = 5028006226606996671L; public EquipSetTableModel(CharacterFacade character) { super(character); character.getEquipmentSetRef().addReferenceListener(this); setDelegate(character.getEquipmentSets()); setFilter(this); } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex == -1) { return Boolean.class; } return super.getColumnClass(columnIndex); } @Override protected Object getValueAt(EquipmentSetFacade element, int column) { switch (column) { case -1: return character.getEquipmentSetRef().get() == element; case 0: return element; default: return null; } } @Override public int getColumnCount() { return 1; } @Override public String getColumnName(int column) { if (column == 0) { return LanguageBundle.getString("in_csEquipSets"); //$NON-NLS-1$ } return null; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex < 0; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { EquipmentSetFacade eqset = sortedList.getElementAt(rowIndex); character.setEquipmentSet(eqset); csheet.refresh(); } @Override public void referenceChanged(ReferenceEvent<EquipmentSetFacade> e) { fireTableRowsUpdated(0, character.getEquipmentSets().getSize() - 1); } @Override public boolean accept(CharacterFacade context, EquipmentSetFacade element) { return true; } } }