/* * Copyright (c) 2014 tabletoptool.com team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * rptools.com team - initial implementation * tabletoptool.com team - further development */ package com.t3.client.ui.lookuptable; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JList; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; import com.t3.MD5Key; import com.t3.client.T3Util; import com.t3.client.TabletopTool; import com.t3.client.swing.AbeillePanel; import com.t3.client.swing.ImageChooserDialog; import com.t3.client.ui.lookuptable.EditLookupTablePanel.LookupTableTableModel; import com.t3.client.ui.token.ImageAssetPanel; import com.t3.language.I18N; import com.t3.model.AssetManager; import com.t3.model.LookupTable; import com.t3.model.LookupTable.LookupEntry; public class EditLookupTablePanel extends AbeillePanel<LookupTableTableModel> { private static final long serialVersionUID = 2341539768448195059L; private LookupTable lookupTable; private ImageAssetPanel tableImageAssetPanel; private int defaultRowHeight; private boolean accepted = false; private boolean newTable = false; public EditLookupTablePanel() { super("com/t3/client/ui/forms/editLookupTablePanel.xml"); panelInit(); } public void initTableDefinitionTable() { defaultRowHeight = getTableDefinitionTable().getRowHeight(); getTableDefinitionTable().setDefaultRenderer(ImageAssetPanel.class, new ImageCellRenderer()); getTableDefinitionTable().setModel(createLookupTableModel(new LookupTable())); getTableDefinitionTable().addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int column = getTableDefinitionTable().columnAtPoint(e.getPoint()); if (column < 2) { return; } int row = getTableDefinitionTable().rowAtPoint(e.getPoint()); String imageIdStr = (String) getTableDefinitionTable().getModel().getValueAt(row, column); // HACK: this is a hacky way to figure out if the button was pushed :P if (e.getPoint().x > getTableDefinitionTable().getSize().width - 15) { if (imageIdStr == null || imageIdStr.length() == 0) { // Add ImageChooserDialog chooserDialog = TabletopTool.getFrame().getImageChooserDialog(); chooserDialog.setVisible(true); MD5Key imageId = chooserDialog.getImageId(); if (imageId == null) { return; } imageIdStr = imageId.toString(); } else { // Cancel imageIdStr = null; } } else if (e.getPoint().x > getTableDefinitionTable().getSize().width - 30) { // Add ImageChooserDialog chooserDialog = TabletopTool.getFrame().getImageChooserDialog(); chooserDialog.setVisible(true); MD5Key imageId = chooserDialog.getImageId(); if (imageId == null) { return; } imageIdStr = imageId.toString(); } getTableDefinitionTable().getModel().setValueAt(imageIdStr, row, column); updateDefinitionTableRowHeights(); getTableDefinitionTable().repaint(); } }); } public void initTableImage() { tableImageAssetPanel = new ImageAssetPanel(); tableImageAssetPanel.setPreferredSize(new Dimension(150, 150)); tableImageAssetPanel.setBorder(BorderFactory.createLineBorder(Color.black)); replaceComponent("mainForm", "tableImage", tableImageAssetPanel); } public void attach(LookupTable luTable) { newTable = luTable == null; lookupTable = newTable ? new LookupTable() : luTable; accepted = false; getTableNameTextField().setText(this.lookupTable.getName()); getTableRollTextField().setText(this.lookupTable.getRoll()); tableImageAssetPanel.setImageId(this.lookupTable.getTableImage()); getVisibleCheckbox().setSelected(this.lookupTable.getVisible()); getAllowLookupCheckbox().setSelected(this.lookupTable.getAllowLookup()); getTableNameTextField().requestFocusInWindow(); EventQueue.invokeLater(new Runnable() { @Override public void run() { getTableDefinitionTable().setModel(createLookupTableModel(EditLookupTablePanel.this.lookupTable)); updateDefinitionTableRowHeights(); } }); } public boolean accepted() { return accepted; } public JTextField getTableNameTextField() { return (JTextField) getComponent("tableName"); } public JTextField getTableRollTextField() { return (JTextField) getComponent("defaultTableRoll"); } public JTable getTableDefinitionTable() { return (JTable) getComponent("definitionTable"); } public JList getTableList() { return (JList) getComponent("tableList"); } public JCheckBox getVisibleCheckbox() { return (JCheckBox) getComponent("visibleCheckbox"); } public JCheckBox getAllowLookupCheckbox() { return (JCheckBox) getComponent("allowLookupCheckbox"); } public void initCancelButton() { JButton button = (JButton) getComponent("cancelButton"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { accepted = false; close(); } }); } public void initAcceptButton() { JButton button = (JButton) getComponent("acceptButton"); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // Commit any in-process edits if (getTableDefinitionTable().isEditing()) { getTableDefinitionTable().getCellEditor().stopCellEditing(); } String name = getTableNameTextField().getText().trim(); if (name.length() == 0) { TabletopTool.showError("EditLookupTablePanel.error.noName"); return; } LookupTable existingTable = TabletopTool.getCampaign().getLookupTableMap().get(name); if (existingTable != null && existingTable != lookupTable) { TabletopTool.showError(I18N.getText("EditLookupTablePanel.error.sameName", name)); return; } TableModel tableModel = getTableDefinitionTable().getModel(); if (tableModel.getRowCount() < 1) { TabletopTool.showError(I18N.getText("EditLookupTablePanel.error.invalidSize", name)); return; } String origname = lookupTable.getName(); // save existing name for later removal from LookupTableMap lookupTable.setName(name); lookupTable.setRoll(getTableRollTextField().getText()); lookupTable.setTableImage(tableImageAssetPanel.getImageId()); lookupTable.setVisible(getVisibleCheckbox().isSelected()); lookupTable.setAllowLookup(getAllowLookupCheckbox().isSelected()); lookupTable.clearEntries(); for (int i = 0; i < tableModel.getRowCount(); i++) { String range = ((String) tableModel.getValueAt(i, 0)).trim(); if (range.length() == 0) { continue; } String value = ((String) tableModel.getValueAt(i, 1)).trim(); String imageId = (String) tableModel.getValueAt(i, 2); int min = 0; int max = 0; int split = range.indexOf("-", range.charAt(0) == '-' ? 1 : 0); // Allow negative numbers try { if (split < 0) { min = Integer.parseInt(range); max = min; } else { min = Integer.parseInt(range.substring(0, split).trim()); max = Integer.parseInt(range.substring(split + 1).trim()); } } catch (NumberFormatException nfe) { TabletopTool.showError(I18N.getText("EditLookupTablePanel.error.badRange", name, range, i)); return; } MD5Key image = null; if (imageId != null && imageId.length() > 0) { image = new MD5Key(imageId); T3Util.uploadAsset(AssetManager.getAsset(image)); } lookupTable.addEntry(min, max, value, image); } if (!name.equals(origname)) { // New name is not the same as the existing name TabletopTool.getCampaign().getLookupTableMap().remove(origname); } // This will add it if it is new T3Util.uploadAsset(AssetManager.getAsset(tableImageAssetPanel.getImageId())); TabletopTool.getCampaign().getLookupTableMap().put(name, lookupTable); TabletopTool.serverCommand().updateCampaign(TabletopTool.getCampaign().getCampaignProperties()); accepted = true; close(); } }); } private void close() { SwingUtilities.getWindowAncestor(this).setVisible(false); } private void updateDefinitionTableRowHeights() { JTable table = getTableDefinitionTable(); for (int row = 0; row < table.getRowCount(); row++) { String imageId = (String) table.getModel().getValueAt(row, 2); table.setRowHeight(row, imageId != null && imageId.length() > 0 ? 100 : defaultRowHeight); } } private LookupTableTableModel createLookupTableModel(LookupTable lookupTable) { List<List<String>> rows = new ArrayList<List<String>>(); if (lookupTable != null) { for (LookupEntry entry : lookupTable.getEntryList()) { String range = entry.getMax() != entry.getMin() ? entry.getMin() + "-" + entry.getMax() : "" + entry.getMin(); String value = entry.getValue(); MD5Key imageId = entry.getImageId(); rows.add(Arrays.asList(new String[] { range, value, imageId != null ? imageId.toString() : null })); } } return new LookupTableTableModel(rows, "Range", "Value", "Image"); } private class ImageCellRenderer extends ImageAssetPanel implements TableCellRenderer { private static final long serialVersionUID = 183503471819640825L; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setImageId(value != null && ((String) value).length() > 0 ? new MD5Key((String) value) : null, EditLookupTablePanel.this); return this; } } static class LookupTableTableModel extends AbstractTableModel { private static final long serialVersionUID = -6310344745803084970L; private List<String> newRow = new ArrayList<String>(); private final List<List<String>> rowList; private final String[] cols; public LookupTableTableModel(List<List<String>> rowList, String... cols) { this.rowList = rowList; this.cols = cols; } @Override public int getColumnCount() { return cols.length; } @Override public int getRowCount() { return rowList.size() + 1; } @Override public Object getValueAt(int rowIndex, int columnIndex) { List<String> row = null; // Existing value if (rowIndex < rowList.size()) { row = rowList.get(rowIndex); } else { row = newRow; } return columnIndex < row.size() ? row.get(columnIndex) : ""; } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { boolean hasNewRow = false; List<String> row = null; if (rowIndex < rowList.size()) { row = rowList.get(rowIndex); } else { row = newRow; rowList.add(newRow); newRow = new ArrayList<String>(); hasNewRow = true; } while (columnIndex >= row.size()) { row.add(""); } row.set(columnIndex, (String) aValue); if (hasNewRow) { fireTableRowsInserted(rowList.size(), rowList.size()); } } @Override public Class<?> getColumnClass(int columnIndex) { return columnIndex < 2 ? String.class : ImageAssetPanel.class; } @Override public String getColumnName(int column) { return cols[column]; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex != 2; } } public void initToolTips() { getVisibleCheckbox().setToolTipText(I18N.getString("EditLookupTablePanel.tooltip.visible")); getAllowLookupCheckbox().setToolTipText(I18N.getString("EditLookupTablePanel.tooltip.allowLookup")); } }