OLD | NEW |
| (Empty) |
1 package autotest.tko; | |
2 | |
3 import autotest.common.ui.RightClickTable; | |
4 | |
5 import com.google.gwt.event.dom.client.ClickEvent; | |
6 import com.google.gwt.user.client.DOM; | |
7 import com.google.gwt.user.client.Element; | |
8 import com.google.gwt.user.client.Event; | |
9 import com.google.gwt.user.client.ui.HTMLTable; | |
10 | |
11 import java.util.ArrayList; | |
12 import java.util.List; | |
13 | |
14 /** | |
15 * Customized table class supporting multiple tbody elements. It is modified to
support input | |
16 * handling, getRowCount(), getCellCount(), and getCellFormatter().getElement().
getElement() | |
17 * also works. Calls to other methods aren't guaranteed to work. | |
18 */ | |
19 class FragmentedTable extends RightClickTable { | |
20 public class FragmentedCellFormatter extends HTMLTable.CellFormatter { | |
21 @Override | |
22 public Element getElement(int row, int column) { | |
23 checkCellBounds(row, column); | |
24 Element bodyElem = bodyElems.get(getFragmentIndex(row)); | |
25 return getCellElement(bodyElem, getRowWithinFragment(row), column); | |
26 } | |
27 | |
28 /** | |
29 * Native method to efficiently get a td element from a tbody. Copied fr
om GWT's | |
30 * HTMLTable.java. | |
31 */ | |
32 private native Element getCellElement(Element tbody, int row, int col) /
*-{ | |
33 return tbody.rows[row].cells[col]; | |
34 }-*/; | |
35 } | |
36 | |
37 private List<Element> bodyElems = new ArrayList<Element>(); | |
38 private int totalRowCount; | |
39 private int rowsPerFragment; | |
40 | |
41 public FragmentedTable() { | |
42 super(); | |
43 setCellFormatter(new FragmentedCellFormatter()); | |
44 } | |
45 | |
46 /** | |
47 * This method must be called after added or removing tbody elements and bef
ore using other | |
48 * functionality (accessing cell elements, input handling, etc.). | |
49 */ | |
50 public void updateBodyElems() { | |
51 totalRowCount = 0; | |
52 Element tbody = DOM.getFirstChild(getElement()); | |
53 for(; tbody != null; tbody = DOM.getNextSibling(tbody)) { | |
54 assert tbody.getTagName().equalsIgnoreCase("tbody"); | |
55 bodyElems.add(tbody); | |
56 totalRowCount += getRowCount(tbody); | |
57 } | |
58 } | |
59 | |
60 public void reset() { | |
61 bodyElems.clear(); | |
62 TkoUtils.clearDomChildren(getElement()); | |
63 } | |
64 | |
65 private int getRowWithinFragment(int row) { | |
66 return row % rowsPerFragment; | |
67 } | |
68 | |
69 private int getFragmentIndex(int row) { | |
70 return row / rowsPerFragment; | |
71 } | |
72 | |
73 @Override | |
74 public HTMLTable.Cell getCellForEvent(ClickEvent event) { | |
75 return getCellForDomEvent(event); | |
76 } | |
77 | |
78 @Override | |
79 protected RowColumn getCellPosition(Element td) { | |
80 Element tr = DOM.getParent(td); | |
81 Element body = DOM.getParent(tr); | |
82 int fragmentIndex = DOM.getChildIndex(getElement(), body); | |
83 int rowWithinFragment = DOM.getChildIndex(body, tr); | |
84 int row = fragmentIndex * rowsPerFragment + rowWithinFragment; | |
85 int column = DOM.getChildIndex(tr, td); | |
86 return new RowColumn(row, column); | |
87 } | |
88 | |
89 /** | |
90 * This is a modified version of getEventTargetCell() from HTMLTable.java. | |
91 */ | |
92 @Override | |
93 protected Element getEventTargetCell(Event event) { | |
94 Element td = DOM.eventGetTarget(event); | |
95 for (; td != null; td = DOM.getParent(td)) { | |
96 // If it's a TD, it might be the one we're looking for. | |
97 if (DOM.getElementProperty(td, "tagName").equalsIgnoreCase("td")) { | |
98 // Make sure it's directly a part of this table before returning | |
99 // it. | |
100 Element tr = DOM.getParent(td); | |
101 Element body = DOM.getParent(tr); | |
102 Element tableElem = DOM.getParent(body); | |
103 if (tableElem == getElement()) { | |
104 return td; | |
105 } | |
106 } | |
107 // If we run into this table's element, we're out of options. | |
108 if (td == getElement()) { | |
109 return null; | |
110 } | |
111 } | |
112 return null; | |
113 } | |
114 | |
115 @Override | |
116 public int getCellCount(int row) { | |
117 Element bodyElem = bodyElems.get(getFragmentIndex(row)); | |
118 return getCellCount(bodyElem, getRowWithinFragment(row)); | |
119 } | |
120 | |
121 @Override | |
122 public int getRowCount() { | |
123 return totalRowCount; | |
124 } | |
125 | |
126 private native int getRowCount(Element tbody) /*-{ | |
127 return tbody.rows.length; | |
128 }-*/; | |
129 | |
130 private native int getCellCount(Element tbody, int row) /*-{ | |
131 return tbody.rows[row].cells.length; | |
132 }-*/; | |
133 | |
134 /** | |
135 * This must be called before using other functionality (accessing cell elem
ents, input | |
136 * handling, etc.). | |
137 * @param rowsPerFragment The number of rows in each tbody. The last tbody
may have fewer | |
138 * rows. All others must have exactly this number of rows. | |
139 */ | |
140 public void setRowsPerFragment(int rowsPerFragment) { | |
141 this.rowsPerFragment = rowsPerFragment; | |
142 } | |
143 } | |
OLD | NEW |