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 }