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