package org.freeplane.plugin.script.addons;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.AbstractCellEditor;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import org.freeplane.main.addons.AddOnProperties;
/**
* Editor and Renderer for multiple buttons inside a table cell.
* @author Mag. Stefan Hagmann
* @see http://www.bgbaden-frauen.ac.at/frauengasse20/uploads/files/Informatik/java/ButtonsInColumn.java
*/
@SuppressWarnings("serial")
class ButtonsInCellRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener,
MouseListener {
static final int BUTTON_SPACER = 4;
private final JTable table;
private final Border border;
private Border fborder;
private Object editorValue;
private boolean isButtonColumnEditor;
private JPanel panel;
private final Action[] actions;
private final JButton[] buttons;
public ButtonsInCellRenderer(JTable table, JButton[] buttons, Action[] actions, int column) {
this.table = table;
this.actions = actions;
this.buttons = buttons;
for (JButton btn : buttons) {
btn.setFocusPainted(false);
btn.addActionListener(this);
}
border = buttons[0].getBorder();
setFocusBorder(new LineBorder(Color.BLUE));
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(column).setCellRenderer(this);
columnModel.getColumn(column).setCellEditor(this);
table.addMouseListener(this);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(Box.createHorizontalGlue());
if (buttons.length > 0)
panel.add(buttons[0]);
for (int i = 1; i < buttons.length; i++) {
panel.add(Box.createHorizontalStrut(BUTTON_SPACER));
panel.add(buttons[i]);
}
panel.add(Box.createHorizontalStrut(BUTTON_SPACER));
}
private void setFocusBorder(Border focusBorder) {
this.fborder = focusBorder;
for (JButton btn : buttons) {
btn.setBorder(focusBorder);
}
}
public Object getCellEditorValue() {
return editorValue;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
//FIXME: Java 6
// final AddOnProperties addOn = model.getAddOnAt(table.convertRowIndexToModel(row));
setButtonsVisible(table, row);
for (JButton btn : buttons) {
if (isSelected) {
btn.setForeground(table.getSelectionForeground());
btn.setBackground(table.getSelectionBackground());
panel.setBackground(table.getSelectionBackground());
}
else {
btn.setForeground(table.getForeground());
btn.setBackground(UIManager.getColor("Button.background"));
panel.setBackground(table.getBackground());
}
if (hasFocus) {
btn.setBorder(fborder);
}
else {
btn.setBorder(border);
}
}
return panel;
}
protected void setButtonsVisible(JTable table, int row) {
final ManageAddOnsPanel.AddOnTableModel model = (ManageAddOnsPanel.AddOnTableModel) table.getModel();
final AddOnProperties addOn = model.getAddOnAt(row);
for (JButton btn : buttons) {
final boolean supportsOperation = addOn.supportsOperation(btn.getName());
btn.setVisible(supportsOperation);
}
}
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
this.editorValue = value;
setButtonsVisible(table, row);
return panel;
}
public void actionPerformed(ActionEvent e) {
//FIXME: Java 6
// int row = table.convertRowIndexToModel(table.getEditingRow());
int row = table.getEditingRow();
fireEditingStopped();
for (int i = 0; i < buttons.length; i++) {
if (e.getSource().equals(buttons[i])) {
final ActionEvent event = new ActionEvent(table, ActionEvent.ACTION_PERFORMED, "" + row);
actions[i].actionPerformed(event);
break;
}
}
}
/*
* When the mouse is pressed the editor is invoked. If you then then drag
* the mouse to another cell before releasing it, the editor is still
* active. Make sure editing is stopped when the mouse is released.
*/
public void mousePressed(MouseEvent e) {
if (table.isEditing() && table.getCellEditor() == this)
isButtonColumnEditor = true;
}
public void mouseReleased(MouseEvent e) {
if (isButtonColumnEditor && table.isEditing())
table.getCellEditor().stopCellEditing();
isButtonColumnEditor = false;
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}