source: josm/trunk/src/org/openstreetmap/josm/gui/io/ActionFlagsTableCell.java@ 17318

Last change on this file since 17318 was 17308, checked in by Don-vip, 3 years ago

fix #19995 - upload dialog: separate instances for cell renderer and editor (patch by DevCharly, modified)

  • Property svn:eol-style set to native
File size: 5.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.awt.Dimension;
8import java.awt.GridBagLayout;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.util.EventObject;
12
13import javax.swing.AbstractAction;
14import javax.swing.ActionMap;
15import javax.swing.JCheckBox;
16import javax.swing.JPanel;
17import javax.swing.JTable;
18import javax.swing.event.CellEditorListener;
19import javax.swing.table.TableCellEditor;
20import javax.swing.table.TableCellRenderer;
21
22import org.openstreetmap.josm.gui.util.CellEditorSupport;
23import org.openstreetmap.josm.tools.GBC;
24
25/**
26 * This class creates a table cell that features two checkboxes, Upload and Save. It
27 * handles everything on its own, in other words it renders itself and also functions
28 * as editor so the checkboxes may be set by the user.
29 *
30 * Intended usage is like this:
31 * <code>
32 * <br>ActionFlagsTableCell aftc = new ActionFlagsTableCell();
33 * <br>col = new TableColumn(0);
34 * <br>col.setCellRenderer(aftc);
35 * <br>col.setCellEditor(aftc);
36 * </code>
37 *
38 * Note: Do not use the same object both as <code>TableCellRenderer</code> and
39 * <code>TableCellEditor</code> - this can mess up the current editor component
40 * by subsequent calls to the renderer (#19995 and #12462).
41 */
42class ActionFlagsTableCell extends JPanel implements TableCellRenderer, TableCellEditor {
43 private final JCheckBox[] checkBoxes = new JCheckBox[2];
44 private final transient CellEditorSupport cellEditorSupport = new CellEditorSupport(this);
45
46 /**
47 * Constructs a new {@code ActionFlagsTableCell}.
48 */
49 ActionFlagsTableCell() {
50 checkBoxes[0] = new JCheckBox(tr("Upload"));
51 checkBoxes[1] = new JCheckBox(tr("Save"));
52 setLayout(new GridBagLayout());
53
54 ActionListener al = e -> cellEditorSupport.fireEditingStopped();
55 ActionMap am = getActionMap();
56 for (final JCheckBox b : checkBoxes) {
57 b.setPreferredSize(new Dimension(b.getPreferredSize().width, 19));
58 b.addActionListener(al);
59 am.put(b.getText(), new AbstractAction() {
60 @Override
61 public void actionPerformed(ActionEvent e) {
62 b.setSelected(!b.isSelected());
63 cellEditorSupport.fireEditingStopped();
64 }
65 });
66 }
67 }
68
69 protected void updateCheckboxes(Object v) {
70 if (v != null && checkBoxes[0] != null && checkBoxes[1] != null) {
71 boolean[] values;
72 if (v instanceof SaveLayerInfo) {
73 values = new boolean[2];
74 values[0] = ((SaveLayerInfo) v).isDoUploadToServer();
75 values[1] = ((SaveLayerInfo) v).isDoSaveToFile();
76 } else {
77 values = (boolean[]) v;
78 }
79 checkBoxes[0].setSelected(values[0]);
80 checkBoxes[1].setSelected(values[1]);
81 }
82 }
83
84 private void updatePanel(SaveLayerInfo info) {
85 StringBuilder sb = new StringBuilder(128)
86 .append("<html>")
87 .append(tr("Select which actions to perform for this layer, if you click the leftmost button."));
88 removeAll();
89 if (info != null) {
90 if (info.isUploadable()) {
91 sb.append("<br/>")
92 .append(tr("Check \"Upload\" to upload the changes to the OSM server."));
93 add(checkBoxes[0], GBC.eol().fill(GBC.HORIZONTAL));
94 }
95 if (info.isSavable()) {
96 sb.append("<br/>")
97 .append(tr("Check \"Save\" to save the layer to the file specified on the left."));
98 add(checkBoxes[1], GBC.eol().fill(GBC.HORIZONTAL));
99 }
100 }
101 sb.append("</html>");
102 setToolTipText(sb.toString());
103 }
104
105 @Override
106 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
107 return getTableCellEditorComponent(table, value, isSelected, row, column);
108 }
109
110 @Override
111 public void addCellEditorListener(CellEditorListener l) {
112 cellEditorSupport.addCellEditorListener(l);
113 }
114
115 @Override
116 public void cancelCellEditing() {
117 cellEditorSupport.fireEditingCanceled();
118 }
119
120 @Override
121 public Object getCellEditorValue() {
122 boolean[] values = new boolean[2];
123 values[0] = checkBoxes[0].isSelected();
124 values[1] = checkBoxes[1].isSelected();
125 return values;
126 }
127
128 @Override
129 public boolean isCellEditable(EventObject anEvent) {
130 return true;
131 }
132
133 @Override
134 public void removeCellEditorListener(CellEditorListener l) {
135 cellEditorSupport.removeCellEditorListener(l);
136 }
137
138 @Override
139 public boolean shouldSelectCell(EventObject anEvent) {
140 return true;
141 }
142
143 @Override
144 public boolean stopCellEditing() {
145 cellEditorSupport.fireEditingStopped();
146 return true;
147 }
148
149 @Override
150 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
151 updatePanel((SaveLayerInfo) value);
152 updateCheckboxes(value);
153 return this;
154 }
155}
Note: See TracBrowser for help on using the repository browser.