1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.utgenome.gwt.utgb.client.ui;
26
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Iterator;
31 import java.util.Map;
32
33 import org.utgenome.gwt.utgb.client.track.Design;
34 import org.utgenome.gwt.utgb.client.util.TableData;
35
36 import com.google.gwt.event.dom.client.ChangeEvent;
37 import com.google.gwt.event.dom.client.ChangeHandler;
38 import com.google.gwt.event.dom.client.KeyPressEvent;
39 import com.google.gwt.event.dom.client.KeyPressHandler;
40 import com.google.gwt.user.client.ui.Composite;
41 import com.google.gwt.user.client.ui.FlexTable;
42 import com.google.gwt.user.client.ui.Image;
43 import com.google.gwt.user.client.ui.TextBox;
44 import com.google.gwt.user.client.ui.Widget;
45 import com.google.gwt.widgetideas.client.event.KeyboardHandler;
46
47
48
49
50
51
52
53 public class EditableTable extends Composite {
54 private final static int LABEL_ROW_INDEX = 0;
55 private FlexTable _table = new FlexTable();
56 private boolean _enableInsertionOfNewRows = false;
57 private HashSet<Integer> _disabledColumn = new HashSet<Integer>();
58 private ArrayList<TextBox> _newRowBox = new ArrayList<TextBox>();
59
60
61 private TableData _tableData;
62 private ArrayList<TableChangeListener> _tableChangeListenerList = new ArrayList<TableChangeListener>();
63
64 class RowChangeListener implements ChangeHandler, KeyPressHandler {
65 public void onChange(ChangeEvent e) {
66 onChange((Widget) e.getSource());
67 }
68
69 private void onChange(Widget sender) {
70 EditableLabel label = (EditableLabel) sender;
71 CellReference cell = label.getCellReference();
72 Object key = cell.getKey();
73 String column = cell.getColumnName();
74
75 for (Iterator<TableChangeListener> it = _tableChangeListenerList.iterator(); it.hasNext();) {
76 TableChangeListener listener = it.next();
77 listener.onUpdateRow(key, column, label.getText());
78 }
79
80 }
81
82 public void onKeyPress(KeyPressEvent e) {
83 if (e.getCharCode() == KeyboardHandler.KEY_ENTER) {
84 onChange((Widget) e.getSource());
85 }
86 }
87 }
88
89 class NewRowListener implements KeyPressHandler {
90
91 public void onKeyPress(KeyPressEvent e) {
92 if (e.getCharCode() == KeyboardHandler.KEY_ENTER) {
93 Object[] row = new Object[_tableData.getColumnCount()];
94 int col = 0;
95 for (Iterator<TextBox> it = _newRowBox.iterator(); it.hasNext(); col++) {
96 TextBox textBox = it.next();
97 row[col] = new String(textBox.getText());
98 textBox.setText("");
99 }
100
101
102 for (Iterator<TableChangeListener> it = _tableChangeListenerList.iterator(); it.hasNext();) {
103 TableChangeListener listener = it.next();
104 listener.onInsertNewRow(row);
105 }
106
107 }
108 }
109
110 }
111
112 public EditableTable(String[] columnLabel) {
113 _tableData = new TableData(columnLabel);
114 init(columnLabel);
115 }
116
117 public EditableTable(String[] columnLabel, int keyColumn) {
118 _tableData = new TableData(columnLabel, keyColumn);
119 init(columnLabel);
120 }
121
122 private void init(String[] columnLabel) {
123 for (int i = 0; i < _tableData.getColumnCount(); i++)
124 _table.setText(0, i + 1, _tableData.getColumnLabel(i));
125
126 _table.setStyleName("editable-table");
127 _table.getRowFormatter().setStyleName(LABEL_ROW_INDEX, "table-label");
128
129 int keyColumn = _tableData.getKeyColumn();
130 disableEdit(keyColumn);
131
132 initWidget(_table);
133 }
134
135 public void disableEdit(int column) {
136 if (column > _table.getCellCount(LABEL_ROW_INDEX))
137 return;
138
139 _disabledColumn.add(new Integer(column));
140
141 for (int row = 1; row < _table.getRowCount(); row++) {
142 EditableLabel label = (EditableLabel) _table.getWidget(row, column + 1);
143 label.setEnabled(false);
144 }
145 }
146
147 private boolean isEditable(int column) {
148 return !_disabledColumn.contains(new Integer(column));
149 }
150
151 public void enableInsertionOfNewRow() {
152 if (_enableInsertionOfNewRows)
153 return;
154
155 _enableInsertionOfNewRows = true;
156 _newRowBox.clear();
157 int newRowPos = _table.getRowCount();
158 for (int i = 0; i < _tableData.getColumnCount(); i++) {
159 TextBox input = new TextBox();
160 input.setWidth("100%");
161 input.addKeyPressHandler(new NewRowListener());
162 _newRowBox.add(input);
163
164 _table.setWidget(newRowPos, i + 1, input);
165 }
166 }
167
168 public void insertRow(Object[] row, int beforeIndex) {
169 Object key = _tableData.addRow(row);
170 int rowPos = _table.insertRow(beforeIndex);
171
172 for (int col = 0; col < row.length; col++) {
173 EditableLabel text = new EditableLabel(new CellReference(key, _tableData.getColumnLabel(col)), row[col] != null ? row[col].toString() : "");
174 if (!isEditable(col))
175 text.setEnabled(false);
176 else {
177 RowChangeListener listener = new RowChangeListener();
178 text.addChangeHandler(listener);
179 text.addKeyPressHandler(listener);
180 }
181 _table.setWidget(rowPos, col + 1, text);
182 }
183
184 Image deleteButton = new Image(Design.IMAGE_DELETE_BUTTON);
185 _table.setWidget(rowPos, 0, deleteButton);
186
187 }
188
189 public void addRow(Object[] row) {
190 insertRow(row, _enableInsertionOfNewRows ? _table.getRowCount() - 1 : _table.getRowCount());
191 }
192
193 private Map<String, String> createRowDataMap(int row) {
194 Map<String, String> rowDataMap = new HashMap<String, String>();
195 for (int col = 0; col < _tableData.getColumnCount(); col++) {
196 String data = _table.getText(row + 1, col + 1);
197 rowDataMap.put(_tableData.getColumnLabel(col), data);
198 }
199 return rowDataMap;
200 }
201
202 public void removeAllRows() {
203 _tableData.clear();
204 int maxRowPos = _enableInsertionOfNewRows ? _table.getRowCount() - 2 : _table.getRowCount() - 1;
205 for (int i = maxRowPos; i >= 1; i--) {
206 _table.removeRow(i);
207 }
208 }
209
210 public void addTableChangeListener(TableChangeListener listener) {
211 _tableChangeListenerList.add(listener);
212 }
213
214 public void removeTableChangeListener(TableChangeListener listener) {
215 _tableChangeListenerList.remove(listener);
216 }
217
218 }
219
220 class CellReference {
221 private Object key;
222 private String columnName;
223
224 public CellReference(Object key, String columnName) {
225 super();
226 this.key = key;
227 this.columnName = columnName;
228 }
229
230 public String getColumnName() {
231 return columnName;
232 }
233
234 public Object getKey() {
235 return key;
236 }
237
238 }