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 CellEditorSupport cellEditorSupport = new CellEditorSupport(this);
041
042    private ActionListener al = new ActionListener() {
043        @Override
044        public void actionPerformed(ActionEvent e) {
045            cellEditorSupport.fireEditingStopped();
046        }
047    };
048
049    public ActionFlagsTableCell() {
050        checkBoxes[0] = new JCheckBox(tr("Upload"));
051        checkBoxes[1] = new JCheckBox(tr("Save"));
052        setLayout(new GridBagLayout());
053
054        ActionMap am = getActionMap();
055        for (final JCheckBox b : checkBoxes) {
056            add(b, GBC.eol().fill(GBC.HORIZONTAL));
057            b.setPreferredSize(new Dimension(b.getPreferredSize().width, 19));
058            b.addActionListener(al);
059            am.put(b.getText(), new AbstractAction() {
060                @Override
061                public void actionPerformed(ActionEvent e) {
062                    b.setSelected(!b.isSelected());
063                    cellEditorSupport.fireEditingStopped();
064                }
065            });
066        }
067
068        setToolTipText(tr("<html>Select which actions to perform for this layer, if you click the leftmost button.<br/>Check \"upload\" to upload the changes to the OSM server.<br/>Check \"Save\" to save the layer to the file specified on the left.</html>"));
069    }
070
071    protected void updateCheckboxes(Object v) {
072        if (v != null && checkBoxes[0] != null && checkBoxes[1] != null) {
073            boolean[] values;
074            if(v instanceof SaveLayerInfo) {
075                values = new boolean[2];
076                values[0] = ((SaveLayerInfo) v).isDoUploadToServer();
077                values[1] = ((SaveLayerInfo) v).isDoSaveToFile();
078            } else {
079                values = (boolean[]) v;
080            }
081            checkBoxes[0].setSelected(values[0]);
082            checkBoxes[1].setSelected(values[1]);
083        }
084    }
085
086    @Override
087    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
088        updateCheckboxes(value);
089        return this;
090    }
091
092    @Override
093    public void addCellEditorListener(CellEditorListener l) {
094        cellEditorSupport.addCellEditorListener(l);
095    }
096
097    @Override
098    public void cancelCellEditing() {
099        cellEditorSupport.fireEditingCanceled();
100    }
101
102    @Override
103    public Object getCellEditorValue() {
104        boolean[] values = new boolean[2];
105        values[0] = checkBoxes[0].isSelected();
106        values[1] = checkBoxes[1].isSelected();
107        return values;
108    }
109
110    @Override
111    public boolean isCellEditable(EventObject anEvent) {
112        return true;
113    }
114
115    @Override
116    public void removeCellEditorListener(CellEditorListener l) {
117        cellEditorSupport.removeCellEditorListener(l);
118    }
119
120    @Override
121    public boolean shouldSelectCell(EventObject anEvent) {
122        return true;
123    }
124
125    @Override
126    public boolean stopCellEditing() {
127        cellEditorSupport.fireEditingStopped();
128        return true;
129    }
130
131    @Override
132    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
133        updateCheckboxes(value);
134        return this;
135    }
136}