001 package jigcell.compare.views;
002
003 import java.awt.BorderLayout;
004 import java.awt.Point;
005 import java.awt.event.MouseEvent;
006 import java.awt.event.MouseListener;
007 import javax.swing.JPopupMenu;
008 import javax.swing.JScrollPane;
009 import javax.swing.ListSelectionModel;
010 import javax.swing.event.ListSelectionEvent;
011 import javax.swing.event.ListSelectionListener;
012 import jigcell.compare.impl.ClipboardDataSource;
013 import jigcell.compare.impl.Compare;
014 import jigcell.compare.impl.DataManager;
015 import jigcell.compare.impl.PrinterDataSource;
016 import jigcell.compare.ui.BasicTable;
017 import jigcell.compare.ui.CompareFrontEnd;
018 import jigcell.compare.ui.DataEditorPanelTab;
019 import jigcell.compare.ui.FindAccessory;
020 import jigcell.compare.ui.IBasicTableHost;
021 import jigcell.compare.ui.IColumnSelectionTab;
022 import jigcell.compare.ui.INameFinderTab;
023 import jigcell.compare.ui.IRowSelectionTab;
024 import jigcell.compare.ui.InterfaceBuilder;
025
026 /**
027 * A default implementation for displaying data in a table.
028 *
029 * <p>
030 * This code is licensed under the DARPA BioCOMP Open Source License. See LICENSE for more details.
031 * </p>
032 *
033 * @author Nicholas Allen
034 */
035
036 public abstract class BasicTableView extends DataEditorPanelTab implements IBasicTableHost, INameFinderTab, ListSelectionListener,
037 MouseListener {
038
039 /**
040 * Resource key for last table selection
041 */
042
043 public final static String RESOURCE_LASTTABLESELECTION = "jigcell_last_table_selection";
044
045 /**
046 * Resource key for table selection
047 */
048
049 public final static String RESOURCE_TABLESELECTION = "jigcell_table_selection";
050
051 /**
052 * Name of default popup
053 */
054
055 protected final static String POPUP_DEFAULT = "default";
056
057 /**
058 * Display
059 */
060
061 protected BasicTable table;
062
063 /**
064 * Data model
065 */
066
067 protected BasicTable.BasicTableModel model;
068
069 /**
070 * Clipboard to use
071 */
072
073 protected ClipboardDataSource clipboard;
074
075 /**
076 * Context menu
077 */
078
079 protected JPopupMenu popup;
080
081 /**
082 * Location of last popup invocation
083 */
084
085 protected Point popupPoint;
086
087 /**
088 * Printer to use
089 */
090
091 protected PrinterDataSource printer;
092
093 /**
094 * Last name searched for
095 */
096
097 protected String lastSearchName;
098
099 /**
100 * Selection group to be a part of
101 */
102
103 protected String selectionGroup;
104
105 /**
106 * Creates a new table view with no additional functionality.
107 *
108 * @param compare Comparator backend to interface with
109 * @param configMarker Marker for retrieving configuration information from Comparator backend
110 */
111
112 public BasicTableView (Compare compare, String configMarker) {
113 super (compare, configMarker);
114 DataManager data = compare.getDataManager ();
115 clipboard = (ClipboardDataSource) data.getPreferredSource (ClipboardDataSource.class);
116 printer = (PrinterDataSource) data.getPreferredSource (PrinterDataSource.class);
117 lastSearchName = "";
118 }
119
120 /**
121 * @see jigcell.compare.ui.INameFinderTab#findByName()
122 */
123
124 public void findByName () {
125 findByName (false, true);
126 }
127
128 /**
129 * @see jigcell.compare.ui.INameFinderTab#findByName(boolean)
130 */
131
132 public boolean findByName (boolean forward) {
133 return findByName (lastSearchName, table.getSelectedRow (), forward);
134 }
135
136 /**
137 * @see jigcell.compare.ui.INameFinderTab#findByName(boolean,boolean)
138 */
139
140 public void findByName (boolean resume, boolean forward) {
141 FindAccessory accessory = new FindAccessory ();
142 ((CompareFrontEnd) compare).setTabAccessory (this, accessory);
143 if (resume)
144 accessory.setFound (findByName (lastSearchName, table.getSelectedRow (), forward));
145 }
146
147 /**
148 * @see jigcell.compare.ui.INameFinderTab#findByName(String,boolean)
149 */
150
151 public boolean findByName (String name, boolean forward) {
152 return findByName (name, table.getSelectedRow (), forward);
153 }
154
155 /**
156 * @see jigcell.compare.ui.IColumnEditorTab#getColumnCount()
157 */
158
159 public int getColumnCount () {
160 return table.getColumnCount ();
161 }
162
163 /**
164 * @see jigcell.compare.ui.IColumnEditorTab#getColumnData(int)
165 */
166
167 public Object getColumnData (int column) {
168 throw new UnsupportedOperationException ();
169 }
170
171 /**
172 * @see jigcell.compare.ui.INameFinderTab#getLastSearchName()
173 */
174
175 public String getLastSearchName () {
176 return lastSearchName;
177 }
178
179 /**
180 * @see jigcell.compare.ui.IRowEditorTab#getRowCount()
181 */
182
183 public int getRowCount () {
184 return table.getRowCount ();
185 }
186
187 /**
188 * @see jigcell.compare.ui.IRowEditorTab#getRowData(int)
189 */
190
191 public Object getRowData (int row) {
192 throw new UnsupportedOperationException ();
193 }
194
195 /**
196 * @see jigcell.compare.ui.IColumnSelectionTab#getSelectedColumns
197 */
198
199 public int [] getSelectedColumns () {
200 return table.getSelectedColumns ();
201 }
202
203 /**
204 * @see jigcell.compare.ui.IRowSelectionTab#getSelectedRows
205 */
206
207 public int [] getSelectedRows () {
208 return table.getSelectedRows ();
209 }
210
211 /**
212 * The selection group this view is part of. Null indicates that this view is part of no group.
213 */
214
215 public String getSelectionGroup () {
216 return selectionGroup;
217 }
218
219 /**
220 * {@inheritDoc}
221 */
222
223 public BasicTable getTable () {
224 return table;
225 }
226
227 public void mouseClicked (MouseEvent e) {}
228
229 public void mouseEntered (MouseEvent e) {}
230
231 public void mouseExited (MouseEvent e) {}
232
233 public void mousePressed (MouseEvent e) {
234 popupPoint = e.getPoint ();
235 if (e.isPopupTrigger () && popup != null) {
236 preparePopup (table.rowAtPoint (popupPoint), table.convertColumnIndexToModel (table.columnAtPoint (popupPoint)));
237 popup.show (e.getComponent (), e.getX (), e.getY ());
238 }
239 }
240
241 public void mouseReleased (MouseEvent e) {
242 mousePressed (e);
243 }
244
245 /**
246 * @see jigcell.compare.ui.IRowSelectionTab#selectAll
247 */
248
249 public void selectAll () {
250 table.selectAll ();
251 }
252
253 /**
254 * @see jigcell.compare.ui.IRowSelectionTab#selectInvert
255 */
256
257 public void selectInvert () {
258 if (this instanceof IRowSelectionTab)
259 selectInvertRows ();
260 else if (this instanceof IColumnSelectionTab)
261 selectInvertColumns ();
262 else
263 throw new UnsupportedOperationException ();
264 }
265
266 /**
267 * @see jigcell.compare.ui.IColumnSelectionTab#selectInvertColumns
268 */
269
270 public void selectInvertColumns () {
271 if (!(this instanceof IColumnSelectionTab))
272 throw new UnsupportedOperationException ();
273 int cols [] = table.getSelectedColumns ();
274 table.selectAll ();
275 for (int i = 0, l = cols.length; i < l; i++) {
276 int col = cols [i];
277 table.removeColumnSelectionInterval (col, col);
278 }
279 }
280
281 /**
282 * @see jigcell.compare.ui.IRowSelectionTab#selectInvertRows
283 */
284
285 public void selectInvertRows () {
286 if (!(this instanceof IRowSelectionTab))
287 throw new UnsupportedOperationException ();
288 int rows [] = table.getSelectedRows ();
289 table.selectAll ();
290 for (int i = 0, l = rows.length; i < l; i++) {
291 int row = rows [i];
292 table.removeRowSelectionInterval (row, row);
293 }
294 }
295
296 /**
297 * @see jigcell.compare.ui.IRowSelectionTab#selectNone
298 */
299
300 public void selectNone () {
301 table.clearSelection ();
302 }
303
304 /**
305 * @see jigcell.compare.ui.IColumnSelectionTab#setSelectedColumns(int [])
306 */
307
308 public void setSelectedColumns (int columns []) {
309 if (!(this instanceof IColumnSelectionTab))
310 throw new UnsupportedOperationException ();
311 table.clearSelection ();
312 for (int i = 0, l = columns.length; i < l; i++) {
313 int col = columns [i];
314 table.addColumnSelectionInterval (col, col);
315 }
316 }
317
318 /**
319 * @see jigcell.compare.ui.IRowSelectionTab#setSelectedRows(int [])
320 */
321
322 public void setSelectedRows (int rows []) {
323 if (!(this instanceof IRowSelectionTab))
324 throw new UnsupportedOperationException ();
325 table.clearSelection ();
326 for (int i = 0, l = rows.length; i < l; i++) {
327 int row = rows [i];
328 table.addRowSelectionInterval (row, row);
329 }
330 }
331
332 public void valueChanged (ListSelectionEvent e) {
333 if (selectionGroup == null)
334 return;
335 compare.updateResourceMap (RESOURCE_TABLESELECTION, this, table.getSelectedRows ());
336 compare.replaceResource (RESOURCE_LASTTABLESELECTION, this);
337 compare.firePropertyChange (RESOURCE_LASTTABLESELECTION);
338 compare.firePropertyChange (RESOURCE_TABLESELECTION);
339 }
340
341 /**
342 * Writes data to the clipboard.
343 *
344 * @param data Data
345 * @param message Error message to use in case of error
346 */
347
348 protected boolean clipboardWrite (Object data, String message) {
349 try {
350 clipboard.write (data);
351 return true;
352 } catch (Exception e) {
353 compare.shellHandleException (Compare.MESSAGE_ERROR, message, e);
354 }
355 return false;
356 }
357
358 /**
359 * Creates a context menu for the view.
360 */
361
362 protected JPopupMenu createPopup () {
363 return menuManager.createPopup (POPUP_DEFAULT);
364 }
365
366 /**
367 * {@inheritDoc}
368 */
369
370 protected void createUI () {
371 createUI (null);
372 }
373
374 /**
375 * Creates an interface for the view.
376 *
377 * @param model Table model to use
378 */
379
380 protected void createUI (BasicTable.BasicTableModel model) {
381 setLayout (new BorderLayout ());
382 this.model = model;
383 table = new BasicTable (model);
384 table.setColumnSelectionAllowed (false);
385 table.setDragEnabled (false);
386 table.setRowSelectionAllowed (true);
387 table.setSurrendersFocusOnKeystroke (true);
388 table.setSelectionMode (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
389 table.getSelectionModel ().addListSelectionListener (this);
390 JScrollPane scroll = new JScrollPane (table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
391 add (scroll, BorderLayout.CENTER);
392 scroll.setBorder (InterfaceBuilder.BORDER_NOTHING);
393 popup = createPopup ();
394 table.addMouseListener (this);
395 table.setDefaultEditor (Object.class, new BasicTable.BasicEditor (this));
396 table.setDefaultRenderer (Object.class, new BasicTable.BasicRenderer (this));
397 }
398
399 /**
400 * Searches for a name starting from an initial row in a specified direction. Returns whether an instance was found.
401 *
402 * @param name Name to search for
403 * @param row Starting row
404 * @param forward Whether to search forwards
405 */
406
407 protected boolean findByName (String name, int row, boolean forward) {
408 return false;
409 }
410
411 /**
412 * Prepares the popup for display.
413 *
414 * @param row Model row of the popup point
415 * @param column Model column of the popup point
416 */
417
418 protected void preparePopup (int row, int column) {}
419
420 /**
421 * Sets the selection group to be a part of. Null indicates that this view is part of no group.
422 *
423 * @param group Selection group
424 */
425
426 protected void setSelectionGroup (String group) {
427 selectionGroup = group;
428 }
429 }