/**
* eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the
* <e-UCM> research group.
*
* Copyright 2005-2010 <e-UCM> research group.
*
* You can access a list of all the contributors to eAdventure at:
* http://e-adventure.e-ucm.es/contributors
*
* <e-UCM> is a research group of the Department of Software Engineering
* and Artificial Intelligence at the Complutense University of Madrid
* (School of Computer Science).
*
* C Profesor Jose Garcia Santesmases sn,
* 28040 Madrid (Madrid), Spain.
*
* For more info please visit: <http://e-adventure.e-ucm.es> or
* <http://www.e-ucm.es>
*
* ****************************************************************************
*
* This file is part of eAdventure, version 2.0
*
* eAdventure 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 3 of the License, or
* (at your option) any later version.
*
* eAdventure 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 eAdventure. If not, see <http://www.gnu.org/licenses/>.
*/
package es.eucm.ead.editor.view.generic.table;
import es.eucm.ead.editor.R;
import es.eucm.ead.editor.util.i18n.Resource;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Map;
import javax.swing.AbstractCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Support class for table-like options
*
* @author mfreire
*/
public class TableSupport {
static private Logger logger = LoggerFactory.getLogger(TableSupport.class);
public static class Row<V, K> implements Map.Entry<K, V> {
private K key;
private V value;
public Row(Map.Entry<K, V> e) {
this(e.getValue(), e.getKey());
}
public Row(V value, K key) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
throw new UnsupportedOperationException();
}
}
public static abstract class AbstractRowTableModel<V, K> extends
AbstractTableModel {
protected ColumnSpec<V, K>[] cols;
protected Row<V, K>[] rows;
protected final TableLikeControl<V, K> control;
public abstract void reindex();
protected AbstractRowTableModel(TableLikeControl<V, K> control) {
this.control = control;
}
public K keyForRow(int row) {
return rows[row].getKey();
}
@Override
public int getRowCount() {
return rows.length;
}
@Override
public int getColumnCount() {
return cols.length;
}
@Override
public String getColumnName(int columnIndex) {
return cols[columnIndex].getName();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return cols[columnIndex].getClazz();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return cols[columnIndex].isEditable();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return cols[columnIndex].getValue(rows[rowIndex], columnIndex);
}
@Override
public abstract void setValueAt(Object value, int rowIndex,
int columnIndex);
@Override
public void fireTableDataChanged() {
reindex();
super.fireTableDataChanged();
}
}
// marking class for a cell containing move buttons
public static class MoveIt {
}
// marking class for a cell containing a delete button
public static class DeleteIt {
}
private static JButton createMinimalButton(String icon, String tooltip) {
JButton b = new JButton();
BufferedImage image = Resource.loadImage(icon);
logger.info("Loading {} for '{}': {}x{}", icon, tooltip, image
.getWidth(), image.getHeight());
b.setIcon(new ImageIcon(image));
b.setPreferredSize(new Dimension(16, 16));
b.setToolTipText(tooltip);
b.setMargin(new Insets(0, 0, 0, 0));
b.setBorderPainted(false);
b.setContentAreaFilled(false);
return b;
}
/**
* Renderer and editor for vertical 'move' buttons
*/
public static class MoveButtonWidget<T> extends AbstractCellEditor
implements TableCellEditor, TableCellRenderer {
private final JButton upButton = createMinimalButton(
R.Drawable.interface__upArrow_png,
Messages.options_table_upArrow);
private final JButton downButton = createMinimalButton(
R.Drawable.interface__downArrow_png,
Messages.options_table_downArrow);
private final JPanel fillerPanel = new JPanel();
private final JPanel buttonPanel = new JPanel(new BorderLayout());
private Object v; // whatever was last set for editing
private int editPos;
private TableLikeControl<T, Integer> control;
public MoveButtonWidget(TableLikeControl<T, Integer> control) {
this.control = control;
upButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
MoveButtonWidget.this.control.moveUp(editPos);
}
});
downButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
MoveButtonWidget.this.control.moveDown(editPos);
}
});
buttonPanel.add(upButton, BorderLayout.NORTH);
buttonPanel.add(fillerPanel, BorderLayout.CENTER);
buttonPanel.add(downButton, BorderLayout.SOUTH);
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
return buttonPanel;
}
@Override
public Object getCellEditorValue() {
return v;
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
this.v = value;
this.editPos = row;
return buttonPanel;
}
}
/**
* Renderer and editor for 'delete' buttons
*/
public static class DeleteButtonWidget<T, K> extends AbstractCellEditor
implements TableCellEditor, TableCellRenderer {
private final JButton deleteButton = createMinimalButton(
R.Drawable.interface__delete_png, Messages.options_table_delete);
private final JPanel fillerPanel = new JPanel();
private final JPanel buttonPanel = new JPanel(new BorderLayout());
private Object v; // whatever was last set for editing
private K deletePos;
private TableLikeControl<T, K> control;
public DeleteButtonWidget(TableLikeControl<T, K> control) {
this.control = control;
deleteButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
DeleteButtonWidget.this.control.remove(deletePos);
}
});
buttonPanel.add(deleteButton, BorderLayout.NORTH);
buttonPanel.add(fillerPanel, BorderLayout.CENTER);
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
return buttonPanel;
}
@Override
public Object getCellEditorValue() {
return v;
}
@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
this.v = value;
this.deletePos = control.keyForRow(row);
return buttonPanel;
}
}
}