001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import java.awt.Color;
005import java.awt.Component;
006import java.awt.event.ActionEvent;
007import java.awt.event.ActionListener;
008
009import javax.swing.AbstractCellEditor;
010import javax.swing.Action;
011import javax.swing.Icon;
012import javax.swing.JButton;
013import javax.swing.JTable;
014import javax.swing.UIManager;
015import javax.swing.border.LineBorder;
016import javax.swing.table.TableCellEditor;
017import javax.swing.table.TableCellRenderer;
018
019/**
020 * Class based on:  http://www.camick.com/java/source/ButtonColumn.java
021 * https://tips4java.wordpress.com/2009/07/12/table-button-column/
022 * @since 10536
023 */
024public class ButtonColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor, ActionListener {
025    private final Action action;
026    private final JButton renderButton;
027    private final JButton editButton;
028    private Object editorValue;
029    private String buttonName;
030
031    /**
032     * Creates a column that is rendered as a button with no action bound to the click event
033     */
034    public ButtonColumn() {
035        this(null);
036    }
037
038    /**
039     * Constructs a new {@code ButtonColumn}.
040     * @param action action
041     * @param buttonName button name
042     */
043    public ButtonColumn(Action action, String buttonName) {
044        this(action);
045        this.buttonName = buttonName;
046    }
047
048    /**
049     * Creates a column that is rendered as a button
050     *
051     * @param action action to be performed when button is pressed
052     */
053    public ButtonColumn(Action action) {
054        this.action = action;
055        renderButton = new JButton();
056        editButton = new JButton();
057        editButton.setFocusPainted(false);
058        editButton.addActionListener(this);
059        editButton.setBorder(new LineBorder(Color.BLUE));
060    }
061
062    @Override
063    public Object getCellEditorValue() {
064        return editorValue;
065    }
066
067    @Override
068    public void actionPerformed(ActionEvent e) {
069        this.action.actionPerformed(e);
070    }
071
072    @Override
073    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
074        this.editorValue = value;
075        if (buttonName != null) {
076            editButton.setText(buttonName);
077            editButton.setIcon(null);
078        } else if (value == null) {
079            editButton.setText("");
080            editButton.setIcon(null);
081        } else if (value instanceof Icon) {
082            editButton.setText("");
083            editButton.setIcon((Icon) value);
084        } else {
085            editButton.setText(value.toString());
086            editButton.setIcon(null);
087        }
088        return editButton;
089    }
090
091    @Override
092    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
093            boolean hasFocus, int row, int column) {
094        if (isSelected) {
095            renderButton.setForeground(table.getSelectionForeground());
096            renderButton.setBackground(table.getSelectionBackground());
097        } else {
098            renderButton.setForeground(table.getForeground());
099            renderButton.setBackground(UIManager.getColor("Button.background"));
100        }
101
102        renderButton.setFocusPainted(hasFocus);
103
104        if (buttonName != null) {
105            renderButton.setText(buttonName);
106            renderButton.setIcon(null);
107        } else if (value == null) {
108            renderButton.setText("");
109            renderButton.setIcon(null);
110        } else if (value instanceof Icon) {
111            renderButton.setText("");
112            renderButton.setIcon((Icon) value);
113        } else {
114            renderButton.setText(value.toString());
115            renderButton.setIcon(null);
116        }
117        return renderButton;
118    }
119}