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