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; 012import java.util.concurrent.CopyOnWriteArrayList; 013 014import javax.swing.AbstractAction; 015import javax.swing.ActionMap; 016import javax.swing.JCheckBox; 017import javax.swing.JPanel; 018import javax.swing.JTable; 019import javax.swing.event.CellEditorListener; 020import javax.swing.event.ChangeEvent; 021import javax.swing.table.TableCellEditor; 022import javax.swing.table.TableCellRenderer; 023 024import 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 */ 037class 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 @Override 043 public void actionPerformed(ActionEvent e) { 044 fireEditingStopped(); 045 } 046 }; 047 048 public ActionFlagsTableCell() { 049 super(); 050 listeners = new CopyOnWriteArrayList<CellEditorListener>(); 051 052 checkBoxes[0] = new JCheckBox(tr("Upload")); 053 checkBoxes[1] = new JCheckBox(tr("Save")); 054 setLayout(new GridBagLayout()); 055 056 ActionMap am = getActionMap(); 057 for (final JCheckBox b : checkBoxes) { 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 @Override 063 public void actionPerformed(ActionEvent e) { 064 b.setSelected(!b.isSelected()); 065 fireEditingStopped(); 066 } 067 }); 068 } 069 070 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>")); 071 } 072 073 protected void updateCheckboxes(Object v) { 074 if (checkBoxes[0] != null && checkBoxes[1] != null) { 075 boolean[] values; 076 if(v instanceof SaveLayerInfo) { 077 values = new boolean[2]; 078 values[0] = ((SaveLayerInfo) v).isDoUploadToServer(); 079 values[1] = ((SaveLayerInfo) v).isDoSaveToFile(); 080 } else { 081 values = (boolean[]) v; 082 } 083 checkBoxes[0].setSelected(values[0]); 084 checkBoxes[1].setSelected(values[1]); 085 } 086 } 087 088 @Override 089 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 090 updateCheckboxes(value); 091 return this; 092 } 093 094 @Override 095 public void addCellEditorListener(CellEditorListener l) { 096 if (l != null) { 097 listeners.addIfAbsent(l); 098 } 099 } 100 101 protected void fireEditingCanceled() { 102 for (CellEditorListener l: listeners) { 103 l.editingCanceled(new ChangeEvent(this)); 104 } 105 } 106 107 protected void fireEditingStopped() { 108 for (CellEditorListener l: listeners) { 109 l.editingStopped(new ChangeEvent(this)); 110 } 111 } 112 113 @Override 114 public void cancelCellEditing() { 115 fireEditingCanceled(); 116 } 117 118 @Override 119 public Object getCellEditorValue() { 120 boolean[] values = new boolean[2]; 121 values[0] = checkBoxes[0].isSelected(); 122 values[1] = checkBoxes[1].isSelected(); 123 return values; 124 } 125 126 @Override 127 public boolean isCellEditable(EventObject anEvent) { 128 return true; 129 } 130 131 @Override 132 public void removeCellEditorListener(CellEditorListener l) { 133 listeners.remove(l); 134 } 135 136 @Override 137 public boolean shouldSelectCell(EventObject anEvent) { 138 return true; 139 } 140 141 @Override 142 public boolean stopCellEditing() { 143 fireEditingStopped(); 144 return true; 145 } 146 147 @Override 148 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 149 updateCheckboxes(value); 150 return this; 151 } 152}