29
29
30
30
package org .scijava .ui .swing .viewer .table ;
31
31
32
+ import java .awt .Component ;
33
+ import java .awt .Toolkit ;
34
+ import java .awt .event .ActionEvent ;
35
+ import java .awt .event .ComponentAdapter ;
36
+ import java .awt .event .ComponentEvent ;
37
+ import java .awt .event .KeyEvent ;
38
+ import java .util .Arrays ;
39
+
40
+ import javax .swing .AbstractAction ;
41
+ import javax .swing .Action ;
42
+ import javax .swing .JComponent ;
43
+ import javax .swing .JMenuItem ;
44
+ import javax .swing .JPopupMenu ;
32
45
import javax .swing .JScrollPane ;
33
46
import javax .swing .JTable ;
47
+ import javax .swing .KeyStroke ;
34
48
import javax .swing .table .AbstractTableModel ;
49
+ import javax .swing .table .TableCellRenderer ;
50
+ import javax .swing .table .TableColumn ;
35
51
36
52
import org .scijava .table .Table ;
37
53
import org .scijava .table .TableDisplay ;
@@ -65,9 +81,25 @@ public SwingTableDisplayPanel(final TableDisplay display,
65
81
this .window = window ;
66
82
nullModel = new NullTableModel ();
67
83
table = makeTable ();
84
+
68
85
table .setAutoCreateRowSorter (true );
86
+ table .setRowSelectionAllowed (true );
87
+ new TablePopupMenu ().install ();
88
+
89
+ //table.setPreferredScrollableViewportSize(getPreferredSize());
90
+ addComponentListener (new ComponentAdapter () {
91
+ @ Override
92
+ public void componentResized (final ComponentEvent e ) {
93
+ if (table .getPreferredSize ().width < getWidth ()) {
94
+ table .setAutoResizeMode (JTable .AUTO_RESIZE_ALL_COLUMNS );
95
+ } else {
96
+ table .setAutoResizeMode (JTable .AUTO_RESIZE_OFF );
97
+ }
98
+ }
99
+ });
69
100
setViewportView (table );
70
101
window .setContent (this );
102
+
71
103
}
72
104
73
105
// -- TableDisplayPanel methods --
@@ -133,6 +165,7 @@ private JTable makeTable() {
133
165
134
166
// -- Helper classes --
135
167
168
+ @ SuppressWarnings ("serial" )
136
169
public static class NullTableModel extends AbstractTableModel {
137
170
138
171
@ Override
@@ -209,6 +242,14 @@ public void setValueAt(final Object value, final int row, final int col) {
209
242
fireTableCellUpdated (row , col );
210
243
}
211
244
245
+ public void removeRows (int [] indices ) {
246
+ Arrays .sort (indices );
247
+ for (int i = indices .length - 1 ; i >= 0 ; i --) {
248
+ tab .removeRow (indices [i ]);
249
+ fireTableRowsDeleted (indices [i ], indices [i ]);
250
+ }
251
+ }
252
+
212
253
// -- Helper methods --
213
254
214
255
private <T > void set (final Table <?, T > table ,
@@ -221,4 +262,91 @@ private <T> void set(final Table<?, T> table,
221
262
222
263
}
223
264
265
+ @ SuppressWarnings ("serial" )
266
+ class TablePopupMenu extends JPopupMenu {
267
+ public TablePopupMenu () {
268
+ super ();
269
+ JMenuItem mi ;
270
+ mi = new JMenuItem (new ActionMapAction ("Copy" , table , "copy" ));
271
+ final int MASK = Toolkit .getDefaultToolkit ().getMenuShortcutKeyMask ();
272
+ mi .setAccelerator (KeyStroke .getKeyStroke (KeyEvent .VK_C , MASK ));
273
+ add (mi );
274
+ mi = new JMenuItem (new ActionMapAction ("Select All" , table , "selectAll" ));
275
+ mi .setAccelerator (KeyStroke .getKeyStroke (KeyEvent .VK_A , MASK ));
276
+ add (mi );
277
+ addSeparator ();
278
+ mi = new JMenuItem ("Delete Selected Row(s)" );
279
+ mi .addActionListener (e -> {
280
+ final int [] selectedRows = table .getSelectedRows ();
281
+ if (selectedRows .length > 0 )
282
+ ((TableModel ) table .getModel ()).removeRows (selectedRows );
283
+ });
284
+ add (mi );
285
+ mi = new JMenuItem ("Resize Column Widths" );
286
+ mi .addActionListener (e -> resizeColumns ());
287
+ add (mi );
288
+ }
289
+
290
+ private void resizeColumns () {
291
+ // https://stackoverflow.com/a/30355804
292
+ table .setAutoResizeMode (JTable .AUTO_RESIZE_OFF );
293
+ table .getTableHeader ();
294
+ for (int column = 0 ; column < table .getColumnCount (); column ++) {
295
+ final TableColumn tableColumn = table .getColumnModel ().getColumn (column );
296
+ int preferredWidth = Math .max (tableColumn .getMinWidth (), getColumnHeaderWidth (tableColumn , column ));
297
+ final int maxWidth = tableColumn .getMaxWidth ();
298
+ for (int row = 0 ; row < table .getRowCount (); row ++) {
299
+ final TableCellRenderer cellRenderer = table .getCellRenderer (row , column );
300
+ final Component c = table .prepareRenderer (cellRenderer , row , column );
301
+ final int width = c .getPreferredSize ().width + table .getIntercellSpacing ().width ;
302
+ preferredWidth = Math .max (preferredWidth , width );
303
+ if (preferredWidth >= maxWidth ) {
304
+ preferredWidth = maxWidth ;
305
+ break ;
306
+ }
307
+ }
308
+ tableColumn .setPreferredWidth (preferredWidth );
309
+ }
310
+ }
311
+
312
+ private int getColumnHeaderWidth (final TableColumn tableColumn , final int column ) {
313
+ final Object value = tableColumn .getHeaderValue ();
314
+ TableCellRenderer renderer = tableColumn .getHeaderRenderer ();
315
+ if (renderer == null ) {
316
+ renderer = table .getTableHeader ().getDefaultRenderer ();
317
+ }
318
+ final Component c = renderer .getTableCellRendererComponent (table , value , false , false , -1 , column );
319
+ return c .getPreferredSize ().width ;
320
+ }
321
+
322
+ void install () {
323
+ table .setComponentPopupMenu (this );
324
+ SwingTableDisplayPanel .this .setComponentPopupMenu (this );
325
+ }
326
+
327
+ }
328
+
329
+ @ SuppressWarnings ("serial" )
330
+ private class ActionMapAction extends AbstractAction {
331
+
332
+ private final Action originalAction ;
333
+ private final JComponent component ;
334
+ private final String actionCommand = "" ;
335
+
336
+ ActionMapAction (final String name , final JComponent component , final String actionKey ) {
337
+ super (name );
338
+ originalAction = component .getActionMap ().get (actionKey );
339
+ if (originalAction == null ) {
340
+ throw new IllegalArgumentException ("No Action for action key: " + actionKey );
341
+ }
342
+ this .component = component ;
343
+ }
344
+
345
+ @ Override
346
+ public void actionPerformed (ActionEvent e ) {
347
+ e = new ActionEvent (component , ActionEvent .ACTION_PERFORMED , actionCommand , e .getWhen (), e .getModifiers ());
348
+ originalAction .actionPerformed (e );
349
+ }
350
+
351
+ }
224
352
}
0 commit comments