1 /*******************************************************************************
2 * Copyright (c) 2010 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Matthew Khouzam - Initial API and implementation
11 * Francois Chouinard - Refactoring, slider support, bug fixing
12 * Patrick Tasse - Improvements and bug fixing
13 * Xavier Raynaud - Improvements
14 ******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.widgets
.virtualtable
;
18 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
19 import org
.eclipse
.swt
.SWT
;
20 import org
.eclipse
.swt
.custom
.TableEditor
;
21 import org
.eclipse
.swt
.events
.ControlAdapter
;
22 import org
.eclipse
.swt
.events
.ControlEvent
;
23 import org
.eclipse
.swt
.events
.KeyEvent
;
24 import org
.eclipse
.swt
.events
.KeyListener
;
25 import org
.eclipse
.swt
.events
.MouseEvent
;
26 import org
.eclipse
.swt
.events
.MouseListener
;
27 import org
.eclipse
.swt
.events
.MouseWheelListener
;
28 import org
.eclipse
.swt
.events
.SelectionAdapter
;
29 import org
.eclipse
.swt
.events
.SelectionEvent
;
30 import org
.eclipse
.swt
.events
.SelectionListener
;
31 import org
.eclipse
.swt
.graphics
.Point
;
32 import org
.eclipse
.swt
.graphics
.Rectangle
;
33 import org
.eclipse
.swt
.layout
.FillLayout
;
34 import org
.eclipse
.swt
.layout
.GridData
;
35 import org
.eclipse
.swt
.layout
.GridLayout
;
36 import org
.eclipse
.swt
.widgets
.Composite
;
37 import org
.eclipse
.swt
.widgets
.Control
;
38 import org
.eclipse
.swt
.widgets
.Display
;
39 import org
.eclipse
.swt
.widgets
.Event
;
40 import org
.eclipse
.swt
.widgets
.Label
;
41 import org
.eclipse
.swt
.widgets
.Listener
;
42 import org
.eclipse
.swt
.widgets
.Menu
;
43 import org
.eclipse
.swt
.widgets
.Shell
;
44 import org
.eclipse
.swt
.widgets
.Slider
;
45 import org
.eclipse
.swt
.widgets
.Table
;
46 import org
.eclipse
.swt
.widgets
.TableColumn
;
47 import org
.eclipse
.swt
.widgets
.TableItem
;
48 import org
.eclipse
.ui
.PlatformUI
;
51 * <b><u>TmfVirtualTable</u></b>
53 * TmfVirtualTable allows for the tabular display of arbitrarily large data sets
54 * (well, up to Integer.MAX_VALUE or ~2G rows).
56 * It is essentially a Composite of Table and Slider, where the number of rows
57 * in the table is set to fill the table display area. The slider is rank-based.
59 * It differs from Table with the VIRTUAL style flag where an empty entry is
60 * created for each virtual row. This does not scale well for very large data sets.
63 * H_SCROLL, V_SCROLL, SINGLE, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL
64 * @author Matthew Khouzam, Francois Chouinard, Patrick Tasse, Xavier Raynaud
65 * @version $Revision: 1.0
67 public class TmfVirtualTable
extends Composite
{
77 private int fTableRows
= 0; // Number of table rows
79 * Field fFullyVisibleRows.
81 private int fFullyVisibleRows
= 0; // Number of fully visible table rows
83 * Field fFrozenRowCount.
85 private int fFrozenRowCount
= 0; // Number of frozen table rows at top of table
88 * Field fTableTopEventRank.
90 private int fTableTopEventRank
= 0; // Global rank of the first entry displayed
92 * Field fSelectedEventRank.
94 private int fSelectedEventRank
= 0; // Global rank of the selected event
96 * Field fPendingSelection.
98 private boolean fPendingSelection
= false; // Pending selection update
101 * Field fTableItemCount.
103 private int fTableItemCount
= 0;
109 private Slider fSlider
;
112 * Field fLinuxItemHeight.
114 private int fLinuxItemHeight
= 0; // Calculated item height for Linux workaround
116 * Field tooltipProvider.
118 private TooltipProvider tooltipProvider
= null;
120 * Field doubleClickListener.
122 private IDoubleClickListener doubleClickListener
= null;
124 // ------------------------------------------------------------------------
126 // ------------------------------------------------------------------------
129 * Standard constructor
132 * The parent composite object
136 public TmfVirtualTable(Composite parent
, int style
) {
137 super(parent
, style
& (~SWT
.H_SCROLL
) & (~SWT
.V_SCROLL
) & (~SWT
.SINGLE
) & (~SWT
.FULL_SELECTION
) & (~SWT
.HIDE_SELECTION
) & (~SWT
.CHECK
));
139 // Create the controls
140 createTable(style
& (SWT
.H_SCROLL
| SWT
.SINGLE
| SWT
.FULL_SELECTION
| SWT
.HIDE_SELECTION
| SWT
.CHECK
));
141 createSlider(style
& SWT
.V_SCROLL
);
143 // Prevent the slider from being traversed
144 setTabList(new Control
[] { fTable
});
147 GridLayout gridLayout
= new GridLayout();
148 gridLayout
.numColumns
= 2;
149 gridLayout
.horizontalSpacing
= 0;
150 gridLayout
.verticalSpacing
= 0;
151 gridLayout
.marginWidth
= 0;
152 gridLayout
.marginHeight
= 0;
153 setLayout(gridLayout
);
155 GridData tableGridData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
156 fTable
.setLayoutData(tableGridData
);
158 GridData sliderGridData
= new GridData(SWT
.FILL
, SWT
.FILL
, false, true);
159 fSlider
.setLayoutData(sliderGridData
);
162 fTable
.addMouseWheelListener(new MouseWheelListener() {
164 public void mouseScrolled(MouseEvent event
) {
165 if (fTableItemCount
<= fFullyVisibleRows
) {
168 fTableTopEventRank
-= event
.count
;
169 if (fTableTopEventRank
< 0) {
170 fTableTopEventRank
= 0;
172 int latestFirstRowOffset
= fTableItemCount
- fFullyVisibleRows
;
173 if (fTableTopEventRank
> latestFirstRowOffset
) {
174 fTableTopEventRank
= latestFirstRowOffset
;
177 fSlider
.setSelection(fTableTopEventRank
);
182 fTable
.addListener(SWT
.MouseWheel
, new Listener() {
183 // disable mouse scroll of horizontal scroll bar
185 public void handleEvent(Event event
) {
190 fTable
.addControlListener(new ControlAdapter() {
192 public void controlResized(ControlEvent event
) {
193 int tableHeight
= Math
.max(0, fTable
.getClientArea().height
- fTable
.getHeaderHeight());
194 fFullyVisibleRows
= tableHeight
/ getItemHeight();
195 if (fTableItemCount
> 0) {
196 fSlider
.setThumb(Math
.max(1, Math
.min(fTableRows
, fFullyVisibleRows
)));
200 // Implement a "fake" tooltip
201 final String TOOLTIP_DATA_KEY
= "_TABLEITEM"; //$NON-NLS-1$
202 final Listener labelListener
= new Listener () {
204 public void handleEvent (Event event
) {
205 Label label
= (Label
)event
.widget
;
206 Shell shell
= label
.getShell ();
207 switch (event
.type
) {
209 Event e
= new Event ();
210 e
.item
= (TableItem
) label
.getData (TOOLTIP_DATA_KEY
);
211 // Assuming table is single select, set the selection as if
212 // the mouse down event went through to the table
213 fTable
.setSelection (new TableItem
[] {(TableItem
) e
.item
});
214 fTable
.notifyListeners (SWT
.Selection
, e
);
228 Listener tableListener
= new Listener () {
232 public void handleEvent (Event event
) {
233 switch (event
.type
) {
236 case SWT
.MouseMove
: {
245 case SWT
.MouseHover
: {
246 TableItem item
= fTable
.getItem (new Point(event
.x
, event
.y
));
248 for (int i
=0; i
< fTable
.getColumnCount(); i
++) {
249 Rectangle bounds
= item
.getBounds(i
);
250 if (bounds
.contains(event
.x
,event
.y
)){
251 if (tip
!= null && !tip
.isDisposed()) {
254 if (tooltipProvider
== null) {
257 String tooltipText
= tooltipProvider
.getTooltip(i
, item
.getData());
258 if (tooltipText
== null) {
261 tip
= new Shell(fTable
.getShell(), SWT
.ON_TOP
| SWT
.NO_FOCUS
| SWT
.TOOL
);
262 tip
.setBackground(PlatformUI
.getWorkbench().getDisplay().getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
263 FillLayout layout
= new FillLayout();
264 layout
.marginWidth
= 2;
265 tip
.setLayout(layout
);
266 label
= new Label(tip
, SWT
.WRAP
);
267 label
.setForeground(PlatformUI
.getWorkbench().getDisplay().getSystemColor(SWT
.COLOR_INFO_FOREGROUND
));
268 label
.setBackground(PlatformUI
.getWorkbench().getDisplay().getSystemColor(SWT
.COLOR_INFO_BACKGROUND
));
269 label
.setData(TOOLTIP_DATA_KEY
, item
);
270 label
.setText(tooltipText
);
272 label
.addListener(SWT
.MouseExit
, labelListener
);
273 label
.addListener(SWT
.MouseDown
, labelListener
);
274 label
.addListener(SWT
.MouseWheel
, labelListener
);
275 Point size
= tip
.computeSize(SWT
.DEFAULT
, SWT
.DEFAULT
);
276 Point pt
= fTable
.toDisplay(bounds
.x
, bounds
.y
);
277 tip
.setBounds(pt
.x
, pt
.y
, size
.x
, size
.y
);
278 tip
.setVisible(true);
289 fTable
.addListener(SWT
.Dispose
, tableListener
);
290 fTable
.addListener(SWT
.KeyDown
, tableListener
);
291 fTable
.addListener(SWT
.MouseMove
, tableListener
);
292 fTable
.addListener(SWT
.MouseHover
, tableListener
);
293 addControlListener(new ControlAdapter() {
295 public void controlResized(ControlEvent event
) {
297 if (fTableItemCount
> 0) {
298 fSlider
.setThumb(Math
.max(1, Math
.min(fTableRows
, fFullyVisibleRows
)));
307 // ------------------------------------------------------------------------
309 // ------------------------------------------------------------------------
312 * Create the table and add listeners
313 * @param style int can be H_SCROLL, V_SCROLL, SINGLE, CHECK, FULL_SELECTION, HIDE_SELECTION, NO_SCROLL
315 private void createTable(int style
) {
316 fTable
= new Table(this, style
| SWT
.NO_SCROLL
);
318 fTable
.addSelectionListener(new SelectionAdapter() {
320 public void widgetSelected(SelectionEvent event
) {
321 if (fTable
.getSelectionIndices().length
> 0) {
322 handleTableSelection();
327 fTable
.addKeyListener(new KeyListener() {
329 public void keyPressed(KeyEvent event
) {
330 handleTableKeyEvent(event
);
333 public void keyReleased(KeyEvent event
) {
338 SWT
.MouseDoubleClick
, new Listener() {
340 public void handleEvent(Event event
) {
341 if (doubleClickListener
!= null) {
342 TableItem item
= fTable
.getItem (new Point (event
.x
, event
.y
));
344 for(int i
=0;i
<fTable
.getColumnCount();i
++){
345 Rectangle bounds
= item
.getBounds(i
);
346 if (bounds
.contains(event
.x
,event
.y
)){
347 doubleClickListener
.handleDoubleClick(TmfVirtualTable
.this, item
, i
);
359 * Update the rows and selected item
361 private void handleTableSelection() {
362 int selectedRow
= fTable
.getSelectionIndices()[0];
363 if (selectedRow
< fFrozenRowCount
) {
364 fSelectedEventRank
= selectedRow
;
366 fSelectedEventRank
= fTableTopEventRank
+ selectedRow
;
370 * Feature in Windows. When a partially visible table item is selected,
371 * after ~500 ms the top index is changed to ensure the selected item is
372 * fully visible. This leaves a blank space at the bottom of the virtual
373 * table. The workaround is to update the top event rank, refresh the
374 * table and reset the top index to 0 after a sufficient delay.
376 if (selectedRow
>= fFullyVisibleRows
) {
377 final Display display
= fTable
.getDisplay();
378 Thread thread
= new Thread("Top index check") { //$NON-NLS-1$
383 } catch (InterruptedException e
) {
385 display
.asyncExec(new Runnable() {
388 if (fTable
.isDisposed()) {
391 int topIndex
= fTable
.getTopIndex();
393 fTableTopEventRank
+= topIndex
;
395 fSlider
.setSelection(fTableTopEventRank
);
396 fTable
.setTopIndex(0);
407 * Handle key-based navigation in table.
411 private void handleTableKeyEvent(KeyEvent event
) {
413 int lastEventRank
= fTableItemCount
- 1;
414 int lastPageTopEntryRank
= Math
.max(0, fTableItemCount
- fFullyVisibleRows
);
416 int previousSelectedEventRank
= fSelectedEventRank
;
417 int selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
418 boolean needsRefresh
= false;
420 // In all case, perform the following steps:
421 // - Update the selected entry rank (within valid range)
422 // - Update the selected row
423 // - Update the page's top entry if necessary (which also adjusts the selected row)
424 // - If the top displayed entry was changed, table refresh is needed
425 switch (event
.keyCode
) {
427 case SWT
.ARROW_DOWN
: {
429 if (fSelectedEventRank
< lastEventRank
) {
430 fSelectedEventRank
++;
431 selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
432 if (selectedRow
== fFullyVisibleRows
) {
433 fTableTopEventRank
++;
435 } else if (selectedRow
< fFrozenRowCount
|| selectedRow
> fFullyVisibleRows
) {
436 fTableTopEventRank
= Math
.max(0, Math
.min(fSelectedEventRank
- fFrozenRowCount
, lastPageTopEntryRank
));
445 if (fSelectedEventRank
> 0) {
446 fSelectedEventRank
--;
447 selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
448 if (selectedRow
== fFrozenRowCount
- 1 && fTableTopEventRank
> 0) {
449 fTableTopEventRank
--;
451 } else if (selectedRow
< fFrozenRowCount
|| selectedRow
> fFullyVisibleRows
) {
452 fTableTopEventRank
= Math
.max(0, Math
.min(fSelectedEventRank
- fFrozenRowCount
, lastPageTopEntryRank
));
461 fTableTopEventRank
= lastPageTopEntryRank
;
462 fSelectedEventRank
= lastEventRank
;
469 fSelectedEventRank
= fFrozenRowCount
;
470 fTableTopEventRank
= 0;
475 case SWT
.PAGE_DOWN
: {
477 if (fSelectedEventRank
< lastEventRank
) {
478 fSelectedEventRank
+= fFullyVisibleRows
;
479 if (fSelectedEventRank
> lastEventRank
) {
480 fSelectedEventRank
= lastEventRank
;
482 selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
483 if (selectedRow
> fFullyVisibleRows
+ fFrozenRowCount
- 1 && selectedRow
< 2 * fFullyVisibleRows
) {
484 fTableTopEventRank
+= fFullyVisibleRows
;
485 if (fTableTopEventRank
> lastPageTopEntryRank
) {
486 fTableTopEventRank
= lastPageTopEntryRank
;
489 } else if (selectedRow
< fFrozenRowCount
|| selectedRow
>= 2 * fFullyVisibleRows
) {
490 fTableTopEventRank
= Math
.max(0, Math
.min(fSelectedEventRank
- fFrozenRowCount
, lastPageTopEntryRank
));
499 if (fSelectedEventRank
> 0) {
500 fSelectedEventRank
-= fFullyVisibleRows
;
501 if (fSelectedEventRank
< fFrozenRowCount
) {
502 fSelectedEventRank
= fFrozenRowCount
;
504 selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
505 if (selectedRow
< fFrozenRowCount
&& selectedRow
> -fFullyVisibleRows
) {
506 fTableTopEventRank
-= fFullyVisibleRows
;
507 if (fTableTopEventRank
< 0) {
508 fTableTopEventRank
= 0;
511 } else if (selectedRow
<= -fFullyVisibleRows
|| selectedRow
>= fFullyVisibleRows
) {
512 fTableTopEventRank
= Math
.max(0, Math
.min(fSelectedEventRank
- fFrozenRowCount
, lastPageTopEntryRank
));
525 done
= refreshTable(); // false if table items not updated yet in this thread
527 fTable
.select(selectedRow
);
530 if (fFullyVisibleRows
< fTableItemCount
) {
531 fSlider
.setSelection(fTableTopEventRank
);
534 if (fSelectedEventRank
!= previousSelectedEventRank
&& fSelectedEventRank
< fTableItemCount
) {
536 Event e
= new Event();
537 e
.item
= fTable
.getSelection()[0];
538 fTable
.notifyListeners(SWT
.Selection
, e
);
540 fPendingSelection
= true;
546 * Method setDataItem.
548 * @param item TableItem
551 private boolean setDataItem(int index
, TableItem item
) {
553 Event event
= new Event();
555 if (index
< fFrozenRowCount
) {
558 event
.index
= index
+ fTableTopEventRank
;
561 fTable
.notifyListeners(SWT
.SetData
, event
);
562 return event
.doit
; // false if table item not updated yet in this thread
567 // ------------------------------------------------------------------------
569 // ------------------------------------------------------------------------
572 * Method createSlider.
575 private void createSlider(int style
) {
576 fSlider
= new Slider(this, SWT
.VERTICAL
| SWT
.NO_FOCUS
);
577 fSlider
.setMinimum(0);
578 fSlider
.setMaximum(0);
579 if ((style
& SWT
.V_SCROLL
) == 0) {
580 fSlider
.setVisible(false);
583 fSlider
.addListener(SWT
.Selection
, new Listener() {
585 public void handleEvent(Event event
) {
586 switch (event
.detail
) {
594 fTableTopEventRank
= fSlider
.getSelection();
605 // ------------------------------------------------------------------------
606 // Simulated Table API
607 // ------------------------------------------------------------------------
610 * Method setHeaderVisible.
613 public void setHeaderVisible(boolean b
) {
614 fTable
.setHeaderVisible(b
);
618 * Method setLinesVisible.
621 public void setLinesVisible(boolean b
) {
622 fTable
.setLinesVisible(b
);
626 * Method getSelection.
627 * @return TableItem[] the items that are selected.
629 public TableItem
[] getSelection() {
630 return fTable
.getSelection();
634 * Method addListener.
635 * @param eventType int
636 * @param listener Listener
639 public void addListener(int eventType
, Listener listener
) {
640 fTable
.addListener(eventType
, listener
);
644 * Method addKeyListener.
645 * @param listener KeyListener
648 public void addKeyListener(KeyListener listener
) {
649 fTable
.addKeyListener(listener
);
654 * Method addMouseListener.
655 * @param listener MouseListener
658 public void addMouseListener(MouseListener listener
) {
659 fTable
.addMouseListener(listener
);
663 * Method addSelectionListener.
664 * @param listener SelectionListener
666 public void addSelectionListener(SelectionListener listener
) {
667 fTable
.addSelectionListener(listener
);
671 * Method setMenu sets the menu
672 * @param menu Menu the menu
675 public void setMenu(Menu menu
) {
676 fTable
.setMenu(menu
);
680 * Gets the menu of this table
684 public Menu
getMenu() {
685 return fTable
.getMenu();
689 * Method clearAll empties a table.
691 public void clearAll() {
696 * Method setItemCount
697 * @param nbItems int the number of items in the table
700 public void setItemCount(int nbItems
) {
701 final int nb
= Math
.max(0, nbItems
);
703 if (nb
!= fTableItemCount
) {
704 fTableItemCount
= nb
;
705 fTable
.remove(fTableItemCount
, fTable
.getItemCount() - 1);
706 fSlider
.setMaximum(nb
);
708 int tableHeight
= Math
.max(0, fTable
.getClientArea().height
- fTable
.getHeaderHeight());
709 fFullyVisibleRows
= tableHeight
/ getItemHeight();
710 if (fTableItemCount
> 0) {
711 fSlider
.setThumb(Math
.max(1, Math
.min(fTableRows
, fFullyVisibleRows
)));
717 * Method getItemCount.
718 * @return int the number of items in the table
720 public int getItemCount() {
721 return fTableItemCount
;
725 * Method getItemHeight.
726 * @return int the height of a table item in pixels. (may vary from one os to another)
728 public int getItemHeight() {
730 * Bug in Linux. The method getItemHeight doesn't always return the correct value.
732 if (fLinuxItemHeight
>= 0 && System
.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$
733 if (fLinuxItemHeight
!= 0) {
734 return fLinuxItemHeight
;
736 if (fTable
.getItemCount() > 1) {
737 int itemHeight
= fTable
.getItem(1).getBounds().y
- fTable
.getItem(0).getBounds().y
;
738 if (itemHeight
> 0) {
739 fLinuxItemHeight
= itemHeight
;
740 return fLinuxItemHeight
;
744 fLinuxItemHeight
= -1; // Not Linux, don't perform os.name check anymore
746 return fTable
.getItemHeight();
750 * Method getHeaderHeight.
751 * @return int get the height of the header in pixels.
753 public int getHeaderHeight() {
754 return fTable
.getHeaderHeight();
758 * Method getTopIndex.
759 * @return int get the first data item index, if you have a header it is offset.
761 public int getTopIndex() {
762 return fTableTopEventRank
+ fFrozenRowCount
;
766 * Method setTopIndex.
767 * @param index int suggested top index for the table.
769 public void setTopIndex(int index
) {
770 if (fTableItemCount
> 0) {
771 int i
= Math
.min(index
, fTableItemCount
- 1);
772 i
= Math
.max(i
, fFrozenRowCount
);
774 fTableTopEventRank
= i
- fFrozenRowCount
;
775 if (fFullyVisibleRows
< fTableItemCount
) {
776 fSlider
.setSelection(fTableTopEventRank
);
784 * Method indexOf. Return the index of a table item
785 * @param ti TableItem the table item to search for in the table
786 * @return int the index of the first match. (there should only be one match)
788 public int indexOf(TableItem ti
) {
789 int index
= fTable
.indexOf(ti
);
790 if (index
< fFrozenRowCount
) {
793 return (index
- fFrozenRowCount
) + getTopIndex();
798 * @return TableColumn[] the table columns
800 public TableColumn
[] getColumns() {
801 return fTable
.getColumns();
806 * @param point Point the coordinates in the table
807 * @return TableItem the corresponding table item
809 public TableItem
getItem(Point point
) {
810 return fTable
.getItem(point
);
816 private void resize() {
817 // Compute the numbers of rows that fit the new area
818 int tableHeight
= Math
.max(0, getSize().y
- fTable
.getHeaderHeight());
819 int itemHeight
= getItemHeight();
820 fTableRows
= Math
.min((tableHeight
+ itemHeight
- 1) / itemHeight
, fTableItemCount
);
822 if (fTableTopEventRank
+ fFullyVisibleRows
> fTableItemCount
) {
823 // If we are at the end, get elements before to populate
824 fTableTopEventRank
= Math
.max(0, fTableItemCount
- fFullyVisibleRows
);
826 } else if (fTableRows
> fTable
.getItemCount() || fTableItemCount
< fTable
.getItemCount()) {
827 // Only refresh if new table items are needed or if table items need to be deleted
833 // ------------------------------------------------------------------------
834 // Controls interactions
835 // ------------------------------------------------------------------------
839 * @return boolean is this visible?
842 public boolean setFocus() {
843 boolean isVisible
= isVisible();
853 public void refresh() {
854 boolean done
= refreshTable();
855 if (fPendingSelection
&& done
) {
856 fPendingSelection
= false;
857 if (fTable
.getSelection().length
> 0) {
858 Event e
= new Event();
859 e
.item
= fTable
.getSelection()[0];
860 fTable
.notifyListeners(SWT
.Selection
, e
);
866 * Method setColumnHeaders.
867 * @param columnData ColumnData[] the columndata array.
869 public void setColumnHeaders(ColumnData columnData
[]) {
870 for (int i
= 0; i
< columnData
.length
; i
++) {
871 TableColumn column
= new TableColumn(fTable
, columnData
[i
].alignment
, i
);
872 column
.setText(columnData
[i
].header
);
873 if (columnData
[i
].width
> 0) {
874 column
.setWidth(columnData
[i
].width
);
883 * @return int 0 the number of elements in the table
885 public int removeAll() {
887 fSlider
.setMaximum(0);
889 fSelectedEventRank
= fFrozenRowCount
;
894 * Method refreshTable.
895 * @return boolean did all the items regresh properly?
897 private boolean refreshTable() {
899 for (int i
= 0; i
< fTableRows
; i
++) {
900 if (i
+ fTableTopEventRank
< fTableItemCount
) {
902 if (i
< fTable
.getItemCount()) {
903 tableItem
= fTable
.getItem(i
);
905 tableItem
= new TableItem(fTable
, SWT
.NONE
);
907 done
&= setDataItem(i
, tableItem
); // false if table item not updated yet in this thread
909 if (fTable
.getItemCount() > fTableItemCount
- fTableTopEventRank
) {
910 fTable
.remove(fTableItemCount
- fTableTopEventRank
);
915 int lastRowOffset
= fTableTopEventRank
+ fTableRows
- 1;
916 if (fSelectedEventRank
< fFrozenRowCount
) {
917 fTable
.select(fSelectedEventRank
);
919 fTable
.deselectAll();
920 } else if ((fSelectedEventRank
>= fTableTopEventRank
+ fFrozenRowCount
) && (fSelectedEventRank
<= lastRowOffset
)) {
921 int selectedRow
= fSelectedEventRank
- fTableTopEventRank
;
922 fTable
.select(selectedRow
);
924 fTable
.deselectAll();
930 * Method setSelection.
931 * @param index int the item number to select in the table.
933 public void setSelection(int index
) {
934 if (fTableItemCount
> 0) {
935 int i
= Math
.min(index
, fTableItemCount
- 1);
938 fSelectedEventRank
= i
;
939 if ((i
< fTableTopEventRank
+ fFrozenRowCount
&& i
>= fFrozenRowCount
) ||
940 (i
>= fTableTopEventRank
+ fFullyVisibleRows
)) {
941 int lastPageTopEntryRank
= Math
.max(0, fTableItemCount
- fFullyVisibleRows
);
942 fTableTopEventRank
= Math
.max(0, Math
.min(lastPageTopEntryRank
, i
- fFrozenRowCount
- fFullyVisibleRows
/ 2));
944 if (fFullyVisibleRows
< fTableItemCount
) {
945 fSlider
.setSelection(fTableTopEventRank
);
954 * Method getSelectionIndex.
955 * @return int the table index of the selected event. not necessarrily the index of the event due to filtering.
957 public int getSelectionIndex() {
958 int index
= fTable
.getSelectionIndex();
960 return fSelectedEventRank
;
962 if (index
< fFrozenRowCount
) {
965 return (index
- fFrozenRowCount
) + getTopIndex();
969 * Method setFrozenRowCount.
970 * @param count int the number of rows to freeze from the top row
972 public void setFrozenRowCount(int count
) {
973 fFrozenRowCount
= count
;
978 * Method createTableEditor.
979 * @return a TableEditor of the table
981 public TableEditor
createTableEditor() {
982 return new TableEditor(fTable
);
986 * Method createTableEditorControl.
987 * @param control Class<? extends Control>
990 public Control
createTableEditorControl(Class
<?
extends Control
> control
) {
992 return control
.getConstructor(Composite
.class, int.class).newInstance(new Object
[] {fTable
, SWT
.NONE
});
993 } catch (Exception e
) {
994 Activator
.getDefault().logError("Error creating table editor control", e
); //$NON-NLS-1$
1000 * @return the tooltipProvider
1002 public TooltipProvider
getTooltipProvider() {
1003 return tooltipProvider
;
1007 * @param tooltipProvider the tooltipProvider to set
1009 public void setTooltipProvider(TooltipProvider tooltipProvider
) {
1010 this.tooltipProvider
= tooltipProvider
;
1014 * @return the doubleClickListener
1016 public IDoubleClickListener
getDoubleClickListener() {
1017 return doubleClickListener
;
1021 * @param doubleClickListener the doubleClickListener to set
1023 public void setDoubleClickListener(IDoubleClickListener doubleClickListener
) {
1024 this.doubleClickListener
= doubleClickListener
;