001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.io;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.awt.Dimension;
008import java.awt.GridBagLayout;
009import java.awt.event.ActionEvent;
010import java.awt.event.ActionListener;
011import java.util.EventObject;
012
013import javax.swing.AbstractAction;
014import javax.swing.ActionMap;
015import javax.swing.JCheckBox;
016import javax.swing.JPanel;
017import javax.swing.JTable;
018import javax.swing.event.CellEditorListener;
019import javax.swing.table.TableCellEditor;
020import javax.swing.table.TableCellRenderer;
021
022import org.openstreetmap.josm.gui.util.CellEditorSupport;
023import org.openstreetmap.josm.tools.GBC;
024
025/**
026 * This class creates a table cell that features two checkboxes, Upload and Save. It
027 * handles everything on its own, in other words it renders itself and also functions
028 * as editor so the checkboxes may be set by the user.
029 *
030 * Intended usage is like this:
031 * <code>
032 * <br>ActionFlagsTableCell aftc = new ActionFlagsTableCell();
033 * <br>col = new TableColumn(0);
034 * <br>col.setCellRenderer(aftc);
035 * <br>col.setCellEditor(aftc);
036 * </code>
037 */
038class ActionFlagsTableCell extends JPanel implements TableCellRenderer, TableCellEditor {
039    private final JCheckBox[] checkBoxes = new JCheckBox[2];
040    private final transient CellEditorSupport cellEditorSupport = new CellEditorSupport(this);
041
042    private final transient ActionListener al = new ActionListener() {
043        @Override
044        public void actionPerformed(ActionEvent e) {
045            cellEditorSupport.fireEditingStopped();
046        }
047    };
048
049    /**
050     * Constructs a new {@code ActionFlagsTableCell}.
051     */
052    ActionFlagsTableCell() {
053        checkBoxes[0] = new JCheckBox(tr("Upload"));
054        checkBoxes[1] = new JCheckBox(tr("Save"));
055        setLayout(new GridBagLayout());
056
057        ActionMap am = getActionMap();
058        for (final JCheckBox b : checkBoxes) {
059            add(b, GBC.eol().fill(GBC.HORIZONTAL));
060            b.setPreferredSize(new Dimension(b.getPreferredSize().width, 19));
061            b.addActionListener(al);
062            am.put(b.getText(), new AbstractAction() {
063                @Override
064                public void actionPerformed(ActionEvent e) {
065                    b.setSelected(!b.isSelected());
066                    cellEditorSupport.fireEditingStopped();
067                }
068            });
069        }
070
071        setToolTipText(tr("<html>"+
072            "Select which actions to perform for this layer, if you click the leftmost button.<br/>"+
073            "Check \"upload\" to upload the changes to the OSM server.<br/>"+
074            "Check \"Save\" to save the layer to the file specified on the left."+
075            "</html>"));
076    }
077
078    protected void updateCheckboxes(Object v) {
079        if (v != null && checkBoxes[0] != null && checkBoxes[1] != null) {
080            boolean[] values;
081            if (v instanceof SaveLayerInfo) {
082                values = new boolean[2];
083                values[0] = ((SaveLayerInfo) v).isDoUploadToServer();
084                values[1] = ((SaveLayerInfo) v).isDoSaveToFile();
085            } else {
086                values = (boolean[]) v;
087            }
088            checkBoxes[0].setSelected(values[0]);
089            checkBoxes[1].setSelected(values[1]);
090        }
091    }
092
093    @Override
094    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
095        updateCheckboxes(value);
096        return this;
097    }
098
099    @Override
100    public void addCellEditorListener(CellEditorListener l) {
101        cellEditorSupport.addCellEditorListener(l);
102    }
103
104    @Override
105    public void cancelCellEditing() {
106        cellEditorSupport.fireEditingCanceled();
107    }
108
109    @Override
110    public Object getCellEditorValue() {
111        boolean[] values = new boolean[2];
112        values[0] = checkBoxes[0].isSelected();
113        values[1] = checkBoxes[1].isSelected();
114        return values;
115    }
116
117    @Override
118    public boolean isCellEditable(EventObject anEvent) {
119        return true;
120    }
121
122    @Override
123    public void removeCellEditorListener(CellEditorListener l) {
124        cellEditorSupport.removeCellEditorListener(l);
125    }
126
127    @Override
128    public boolean shouldSelectCell(EventObject anEvent) {
129        return true;
130    }
131
132    @Override
133    public boolean stopCellEditing() {
134        cellEditorSupport.fireEditingStopped();
135        return true;
136    }
137
138    @Override
139    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
140        updateCheckboxes(value);
141        return this;
142    }
143}