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