source: josm/trunk/src/org/openstreetmap/josm/gui/history/VersionTable.java@ 6806

Last change on this file since 6806 was 6806, checked in by Don-vip, 10 years ago

fix some Sonar issues introduced recently

  • Property svn:eol-style set to native
File size: 11.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.history;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.awt.Dimension;
8import java.awt.Point;
9import java.awt.Rectangle;
10import java.awt.event.ActionEvent;
11import java.awt.event.ItemEvent;
12import java.awt.event.ItemListener;
13import java.awt.event.KeyAdapter;
14import java.awt.event.KeyEvent;
15import java.awt.event.MouseEvent;
16import java.util.Observable;
17import java.util.Observer;
18
19import javax.swing.DefaultCellEditor;
20import javax.swing.JCheckBox;
21import javax.swing.JLabel;
22import javax.swing.JPopupMenu;
23import javax.swing.JRadioButton;
24import javax.swing.JTable;
25import javax.swing.SwingConstants;
26import javax.swing.UIManager;
27import javax.swing.event.TableModelEvent;
28import javax.swing.event.TableModelListener;
29import javax.swing.table.TableCellRenderer;
30
31import org.openstreetmap.josm.Main;
32import org.openstreetmap.josm.actions.AbstractInfoAction;
33import org.openstreetmap.josm.data.osm.User;
34import org.openstreetmap.josm.data.osm.history.History;
35import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
36import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
37import org.openstreetmap.josm.io.XmlWriter;
38import org.openstreetmap.josm.tools.ImageProvider;
39import org.openstreetmap.josm.tools.OpenBrowser;
40
41/**
42 * VersionTable shows a list of version in a {@link org.openstreetmap.josm.data.osm.history.History}
43 * of an {@link org.openstreetmap.josm.data.osm.OsmPrimitive}.
44 *
45 */
46public class VersionTable extends JTable implements Observer{
47 private VersionTablePopupMenu popupMenu;
48 private final HistoryBrowserModel model;
49
50 protected void build() {
51 getTableHeader().setFont(getTableHeader().getFont().deriveFont(9f));
52 setRowSelectionAllowed(false);
53 setShowGrid(false);
54 setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
55 setBackground(UIManager.getColor("Button.background"));
56 setIntercellSpacing(new Dimension(6, 0));
57 putClientProperty("terminateEditOnFocusLost", true);
58 popupMenu = new VersionTablePopupMenu();
59 addMouseListener(new MouseListener());
60 addKeyListener(new KeyAdapter() {
61 @Override
62 public void keyReleased(KeyEvent e) {
63 // navigate history down/up using the corresponding arrow keys.
64 long ref = model.getReferencePointInTime().getVersion();
65 long cur = model.getCurrentPointInTime().getVersion();
66 if (e.getKeyCode() == KeyEvent.VK_DOWN) {
67 History refNext = model.getHistory().from(ref);
68 History curNext = model.getHistory().from(cur);
69 if (refNext.getNumVersions() > 1 && curNext.getNumVersions() > 1) {
70 model.setReferencePointInTime(refNext.sortAscending().get(1));
71 model.setCurrentPointInTime(curNext.sortAscending().get(1));
72 }
73 } else if (e.getKeyCode() == KeyEvent.VK_UP) {
74 History refNext = model.getHistory().until(ref);
75 History curNext = model.getHistory().until(cur);
76 if (refNext.getNumVersions() > 1 && curNext.getNumVersions() > 1) {
77 model.setReferencePointInTime(refNext.sortDescending().get(1));
78 model.setCurrentPointInTime(curNext.sortDescending().get(1));
79 }
80 }
81 }
82 });
83 getModel().addTableModelListener(new TableModelListener() {
84 @Override
85 public void tableChanged(TableModelEvent e) {
86 adjustColumnWidth(VersionTable.this, 0, 0);
87 adjustColumnWidth(VersionTable.this, 1, -8);
88 adjustColumnWidth(VersionTable.this, 2, -8);
89 adjustColumnWidth(VersionTable.this, 3, 0);
90 adjustColumnWidth(VersionTable.this, 4, 0);
91 }
92 });
93 }
94
95 public VersionTable(HistoryBrowserModel model) {
96 super(model.getVersionTableModel(), new VersionTableColumnModel());
97 model.addObserver(this);
98 build();
99 this.model = model;
100 }
101
102 // some kind of hack to prevent the table from scrolling to the
103 // right when clicking on the cells
104 @Override
105 public void scrollRectToVisible(Rectangle aRect) {
106 super.scrollRectToVisible(new Rectangle(0, aRect.y, aRect.width, aRect.height));
107 }
108
109 protected HistoryBrowserModel.VersionTableModel getVersionTableModel() {
110 return (HistoryBrowserModel.VersionTableModel) getModel();
111 }
112
113 @Override
114 public void update(Observable o, Object arg) {
115 repaint();
116 }
117
118 class MouseListener extends PopupMenuLauncher {
119 public MouseListener() {
120 super(popupMenu);
121 }
122 @Override
123 public void mousePressed(MouseEvent e) {
124 super.mousePressed(e);
125 if (!e.isPopupTrigger() && e.getButton() == MouseEvent.BUTTON1) {
126 int row = rowAtPoint(e.getPoint());
127 int col = columnAtPoint(e.getPoint());
128 if (row > 0 && (col == VersionTableColumnModel.COL_DATE || col == VersionTableColumnModel.COL_USER)) {
129 model.getVersionTableModel().setCurrentPointInTime(row);
130 model.getVersionTableModel().setReferencePointInTime(row - 1);
131 }
132 }
133 }
134 @Override
135 protected int checkTableSelection(JTable table, Point p) {
136 HistoryBrowserModel.VersionTableModel model = getVersionTableModel();
137 int row = rowAtPoint(p);
138 if (row > -1 && !model.isLatest(row)) {
139 popupMenu.prepare(model.getPrimitive(row));
140 }
141 return row;
142 }
143 }
144
145 static class ChangesetInfoAction extends AbstractInfoAction {
146 private HistoryOsmPrimitive primitive;
147
148 public ChangesetInfoAction() {
149 super(true);
150 putValue(NAME, tr("Changeset info"));
151 putValue(SHORT_DESCRIPTION, tr("Launch browser with information about the changeset"));
152 putValue(SMALL_ICON, ImageProvider.get("about"));
153 }
154
155 @Override
156 protected String createInfoUrl(Object infoObject) {
157 HistoryOsmPrimitive primitive = (HistoryOsmPrimitive) infoObject;
158 return getBaseBrowseUrl() + "/changeset/" + primitive.getChangesetId();
159 }
160
161 @Override
162 public void actionPerformed(ActionEvent e) {
163 if (!isEnabled())
164 return;
165 String url = createInfoUrl(primitive);
166 OpenBrowser.displayUrl(url);
167 }
168
169 public void prepare(HistoryOsmPrimitive primitive) {
170 putValue(NAME, tr("Show changeset {0}", primitive.getChangesetId()));
171 this.primitive = primitive;
172 }
173 }
174
175 static class UserInfoAction extends AbstractInfoAction {
176 private HistoryOsmPrimitive primitive;
177
178 public UserInfoAction() {
179 super(true);
180 putValue(NAME, tr("User info"));
181 putValue(SHORT_DESCRIPTION, tr("Launch browser with information about the user"));
182 putValue(SMALL_ICON, ImageProvider.get("about"));
183 }
184
185 @Override
186 protected String createInfoUrl(Object infoObject) {
187 HistoryOsmPrimitive hp = (HistoryOsmPrimitive) infoObject;
188 return hp.getUser() == null ? null : getBaseBrowseUrl() + "/user/" + hp.getUser().getName();
189 }
190
191 @Override
192 public void actionPerformed(ActionEvent e) {
193 if (!isEnabled())
194 return;
195 String url = createInfoUrl(primitive);
196 OpenBrowser.displayUrl(url);
197 }
198
199 public void prepare(HistoryOsmPrimitive primitive) {
200 final User user = primitive.getUser();
201 putValue(NAME, "<html>" + tr("Show user {0}", user == null ? "?" :
202 XmlWriter.encode(user.getName(), true) + " <font color=gray>(" + user.getId() + ")</font>") + "</html>");
203 this.primitive = primitive;
204 }
205 }
206
207 static class VersionTablePopupMenu extends JPopupMenu {
208
209 private ChangesetInfoAction changesetInfoAction;
210 private UserInfoAction userInfoAction;
211
212 protected void build() {
213 changesetInfoAction = new ChangesetInfoAction();
214 add(changesetInfoAction);
215 userInfoAction = new UserInfoAction();
216 add(userInfoAction);
217 }
218 public VersionTablePopupMenu() {
219 super();
220 build();
221 }
222
223 public void prepare(HistoryOsmPrimitive primitive) {
224 changesetInfoAction.prepare(primitive);
225 userInfoAction.prepare(primitive);
226 invalidate();
227 }
228 }
229
230 public static class RadioButtonRenderer extends JRadioButton implements TableCellRenderer {
231
232 @Override
233 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
234 setSelected(value != null && (Boolean)value);
235 setHorizontalAlignment(SwingConstants.CENTER);
236 return this;
237 }
238 }
239
240 public static class RadioButtonEditor extends DefaultCellEditor implements ItemListener {
241
242 private JRadioButton btn;
243
244 public RadioButtonEditor() {
245 super(new JCheckBox());
246 btn = new JRadioButton();
247 btn.setHorizontalAlignment(SwingConstants.CENTER);
248 }
249
250 @Override
251 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
252 if (value == null) return null;
253 boolean val = (Boolean) value;
254 btn.setSelected(val);
255 btn.addItemListener(this);
256 return btn;
257 }
258
259 @Override
260 public Object getCellEditorValue() {
261 btn.removeItemListener(this);
262 return btn.isSelected();
263 }
264
265 @Override
266 public void itemStateChanged(ItemEvent e) {
267 fireEditingStopped();
268 }
269 }
270
271 public static class AlignedRenderer extends JLabel implements TableCellRenderer {
272 public AlignedRenderer(int hAlignment) {
273 setHorizontalAlignment(hAlignment);
274 }
275 @Override
276 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
277 String v = value.toString();
278 setText(v);
279 return this;
280 }
281 }
282
283 private static void adjustColumnWidth(JTable tbl, int col, int cellInset) {
284 int maxwidth = 0;
285
286 for (int row=0; row<tbl.getRowCount(); row++) {
287 TableCellRenderer tcr = tbl.getCellRenderer(row, col);
288 Object val = tbl.getValueAt(row, col);
289 Component comp = tcr.getTableCellRendererComponent(tbl, val, false, false, row, col);
290 maxwidth = Math.max(comp.getPreferredSize().width + cellInset, maxwidth);
291 }
292 TableCellRenderer tcr = tbl.getTableHeader().getDefaultRenderer();
293 Object val = tbl.getColumnModel().getColumn(col).getHeaderValue();
294 Component comp = tcr.getTableCellRendererComponent(tbl, val, false, false, -1, col);
295 maxwidth = Math.max(comp.getPreferredSize().width + Main.pref.getInteger("table.header-inset", 0), maxwidth);
296
297 int spacing = tbl.getIntercellSpacing().width;
298 tbl.getColumnModel().getColumn(col).setPreferredWidth(maxwidth + spacing);
299 }
300
301}
Note: See TracBrowser for help on using the repository browser.