1
1
/***********************************************************************
2
- * Copyright by Michael Loesler, https://software.applied-geodesy.org *
3
- * *
4
- * This program is free software; you can redistribute it and/or modify *
5
- * it under the terms of the GNU General Public License as published by *
6
- * the Free Software Foundation; either version 3 of the License, or *
7
- * at your option any later version. *
8
- * *
9
- * This program is distributed in the hope that it will be useful, *
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
- * GNU General Public License for more details. *
13
- * *
14
- * You should have received a copy of the GNU General Public License *
15
- * along with this program; if not, see <http://www.gnu.org/licenses/> *
16
- * or write to the *
17
- * Free Software Foundation, Inc., *
18
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19
- * *
20
- ***********************************************************************/
2
+ * Copyright by Michael Loesler, https://software.applied-geodesy.org *
3
+ * *
4
+ * This program is free software; you can redistribute it and/or modify *
5
+ * it under the terms of the GNU General Public License as published by *
6
+ * the Free Software Foundation; either version 3 of the License, or *
7
+ * at your option any later version. *
8
+ * *
9
+ * This program is distributed in the hope that it will be useful, *
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
+ * GNU General Public License for more details. *
13
+ * *
14
+ * You should have received a copy of the GNU General Public License *
15
+ * along with this program; if not, see <http://www.gnu.org/licenses/> *
16
+ * or write to the *
17
+ * Free Software Foundation, Inc., *
18
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19
+ * *
20
+ ***********************************************************************/
21
21
22
22
package org .applied_geodesy .jag3d .ui .table ;
23
23
41
41
import javafx .scene .control .TableRow ;
42
42
import javafx .scene .control .TableColumn .CellDataFeatures ;
43
43
import javafx .scene .control .TableColumn .CellEditEvent ;
44
+ import javafx .scene .control .TablePosition ;
44
45
import javafx .scene .control .TableView ;
45
46
import javafx .scene .control .cell .CheckBoxTableCell ;
47
+ import javafx .scene .input .Clipboard ;
48
+ import javafx .scene .input .ClipboardContent ;
49
+ import javafx .scene .input .KeyCode ;
50
+ import javafx .scene .input .KeyCodeCombination ;
51
+ import javafx .scene .input .KeyCombination ;
52
+ import javafx .scene .input .KeyEvent ;
46
53
import javafx .scene .input .MouseButton ;
47
54
import javafx .scene .input .MouseEvent ;
48
55
import javafx .util .Callback ;
49
56
50
- public abstract class UITableBuilder <T > {
57
+ public abstract class UITableBuilder <T > {
58
+
59
+ class TableKeyEventHandler implements EventHandler <KeyEvent > {
60
+
61
+ KeyCodeCombination copyKeyCodeCompination = new KeyCodeCombination (KeyCode .C , KeyCombination .CONTROL_ANY );
62
+ public void handle (final KeyEvent keyEvent ) {
63
+
64
+ if (copyKeyCodeCompination .match (keyEvent )) {
65
+ if (keyEvent .getSource () instanceof TableView ) {
66
+ copySelectionToClipboard ( (TableView <?>) keyEvent .getSource ());
67
+ keyEvent .consume ();
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+
51
74
class TableCellChangeListener <S > implements ChangeListener <S > {
52
75
private final int columnIndex ;
53
76
private final T rowData ;
54
77
TableCellChangeListener (int columnIndex , T rowData ) {
55
78
this .columnIndex = columnIndex ;
56
79
this .rowData = rowData ;
57
80
}
58
-
81
+
59
82
@ Override
60
83
public void changed (ObservableValue <? extends S > observable , S oldValue , S newValue ) {
61
84
if (rowData != null ) {
62
85
setValue (rowData , columnIndex , -1 , oldValue , newValue );
63
86
}
64
87
}
65
88
}
66
-
89
+
67
90
class TableCellEvent <S > implements EventHandler <CellEditEvent <T , S >> {
68
91
private final int columnIndex ;
69
92
TableCellEvent (int columnIndex ) {
70
93
this .columnIndex = columnIndex ;
71
94
}
72
-
95
+
73
96
@ Override
74
97
public void handle (CellEditEvent <T , S > event ) {
75
98
if (event .getTableColumn ().isEditable ()) {
76
- // event.getTablePosition().getRow()
99
+ // event.getTablePosition().getRow()
77
100
//int column = event.getTablePosition().getColumn();
78
- //setValue(event.getRowValue(), column, event.getNewValue());
101
+ //setValue(event.getRowValue(), column, event.getNewValue());
79
102
setValue (event .getRowValue (), this .columnIndex , event .getTablePosition ().getRow (), event .getOldValue (), event .getNewValue ());
80
103
}
81
104
}
82
105
}
83
-
106
+
84
107
static FormatterOptions options = FormatterOptions .getInstance ();
85
108
static I18N i18n = I18N .getInstance ();
86
109
TableView <T > table = this .createTable ();
87
-
110
+
88
111
UITableBuilder () {}
89
-
112
+
90
113
TableView <T > createTable () {
91
114
this .table = new TableView <T >();
92
115
ObservableList <T > tableModel = FXCollections .observableArrayList ();
93
116
this .table .setItems (tableModel );
94
117
this .table .setColumnResizePolicy (TableView .UNCONSTRAINED_RESIZE_POLICY );
95
118
this .table .setTableMenuButtonVisible (false );
96
- // this.table.setPlaceholder(new Text(i18n.getString("UITableBuilder.emptytable", "No content in table.")));
119
+ // this.table.setPlaceholder(new Text(i18n.getString("UITableBuilder.emptytable", "No content in table.")));
97
120
this .table .getSelectionModel ().setSelectionMode (SelectionMode .MULTIPLE );
121
+ this .table .setOnKeyPressed (new TableKeyEventHandler ());
98
122
tableModel .add (this .getEmptyRow ());
99
123
return table ;
100
124
}
101
-
125
+
102
126
static <T > Callback <TableColumn <T ,Integer >, TableCell <T ,Integer >> getIntegerCallback () {
103
127
return new Callback <TableColumn <T , Integer >, TableCell <T , Integer >>() {
104
128
@ Override
@@ -107,9 +131,9 @@ public TableCell<T, Integer> call(TableColumn<T, Integer> cell) {
107
131
tableCell .setAlignment (Pos .CENTER_RIGHT );
108
132
return tableCell ;
109
133
}
110
- };
134
+ };
111
135
}
112
-
136
+
113
137
static <T > Callback <TableColumn <T ,Double >, TableCell <T ,Double >> getDoubleCallback (CellValueType cellValueType ) {
114
138
return new Callback <TableColumn <T , Double >, TableCell <T , Double >>() {
115
139
@ Override
@@ -118,9 +142,9 @@ public TableCell<T, Double> call(TableColumn<T, Double> cell) {
118
142
tableCell .setAlignment (Pos .CENTER_RIGHT );
119
143
return tableCell ;
120
144
}
121
- };
145
+ };
122
146
}
123
-
147
+
124
148
static <T > Callback <TableColumn <T ,Double >, TableCell <T ,Double >> getDoubleCallback (CellValueType cellValueType , boolean displayUnit ) {
125
149
return new Callback <TableColumn <T , Double >, TableCell <T , Double >>() {
126
150
@ Override
@@ -129,31 +153,31 @@ public TableCell<T, Double> call(TableColumn<T, Double> cell) {
129
153
tableCell .setAlignment (Pos .CENTER_RIGHT );
130
154
return tableCell ;
131
155
}
132
- };
156
+ };
133
157
}
134
-
158
+
135
159
static <T > Callback <TableColumn <T ,String >, TableCell <T ,String >> getStringCallback () {
136
- return new Callback <TableColumn <T ,String >, TableCell <T ,String >>() {
137
- @ Override
138
- public TableCell <T ,String > call (TableColumn <T ,String > cell ) {
139
- TableCell <T ,String > tableCell = new EditableCell <T , String >(new EditableStringCellConverter ());
140
- tableCell .setAlignment (Pos .CENTER_LEFT );
141
- return tableCell ;
142
- }
143
- };
144
- }
145
-
160
+ return new Callback <TableColumn <T ,String >, TableCell <T ,String >>() {
161
+ @ Override
162
+ public TableCell <T ,String > call (TableColumn <T ,String > cell ) {
163
+ TableCell <T ,String > tableCell = new EditableCell <T , String >(new EditableStringCellConverter ());
164
+ tableCell .setAlignment (Pos .CENTER_LEFT );
165
+ return tableCell ;
166
+ }
167
+ };
168
+ }
169
+
146
170
static <T > Callback <TableColumn <T ,Boolean >, TableCell <T ,Boolean >> getBooleanCallback () {
147
171
return new Callback <TableColumn <T , Boolean >, TableCell <T , Boolean >>() {
148
172
@ Override
149
173
public TableCell <T , Boolean > call (TableColumn <T , Boolean > column ) {
150
174
TableCell <T , Boolean > tableCell = new CheckBoxTableCell <T , Boolean >();
151
175
tableCell .setAlignment (Pos .CENTER );
152
- return tableCell ;
153
- }
154
- };
176
+ return tableCell ;
177
+ }
178
+ };
155
179
}
156
-
180
+
157
181
void addContextMenu (TableView <T > table , ContextMenu contextMenu ) {
158
182
table .setRowFactory (new Callback <TableView <T >, TableRow <T >>() {
159
183
@ Override
@@ -165,7 +189,7 @@ public TableRow<T> call(TableView<T> tableView) {
165
189
}
166
190
});
167
191
}
168
-
192
+
169
193
void addDynamicRowAdder (TableView <T > table ) {
170
194
table .setOnMouseClicked (new EventHandler <MouseEvent >() {
171
195
@ Override
@@ -186,20 +210,20 @@ else if (table.getItems() != null && table.getItems().size() == table.getSelecti
186
210
}
187
211
});
188
212
}
189
-
213
+
190
214
<S >TableColumn <T , S > getColumn (ColumnTooltipHeader header , Function <T , ObservableValue <S >> property , Callback <TableColumn <T , S >, TableCell <T , S >> callback , ColumnType type , int columnIndex , boolean editable ) {
191
215
final TableCellEvent <S > tableCellEvent = new TableCellEvent <S >(columnIndex );
192
216
TableColumn <T , S > column = new TableColumn <T , S >();
193
217
Label columnLabel = header .getLabel ();
194
- columnLabel .getStyleClass ().add ("column-header-label" );
195
- columnLabel .setMaxWidth (Double .MAX_VALUE );
196
- columnLabel .setTooltip (header .getTooltip ());
197
-
198
- column .setUserData (type );
199
- column .setEditable (editable );
200
- column .setGraphic (columnLabel );
201
- column .setMinWidth (25 );
202
- column .setPrefWidth (125 );
218
+ columnLabel .getStyleClass ().add ("column-header-label" );
219
+ columnLabel .setMaxWidth (Double .MAX_VALUE );
220
+ columnLabel .setTooltip (header .getTooltip ());
221
+
222
+ column .setUserData (type );
223
+ column .setEditable (editable );
224
+ column .setGraphic (columnLabel );
225
+ column .setMinWidth (25 );
226
+ column .setPrefWidth (125 );
203
227
column .setCellValueFactory (new Callback <CellDataFeatures <T , S >, ObservableValue <S >>() {
204
228
@ Override
205
229
public ObservableValue <S > call (CellDataFeatures <T , S > param ) {
@@ -219,8 +243,36 @@ public ObservableValue<S> call(CellDataFeatures<T, S> param) {
219
243
public TableView <T > getTable () {
220
244
return this .table ;
221
245
}
222
-
246
+
247
+ public static void copySelectionToClipboard (TableView <?> table ) {
248
+ StringBuilder clipboardString = new StringBuilder ();
249
+
250
+ for (TablePosition <?,?> position : table .getSelectionModel ().getSelectedCells ()) {
251
+ int rowIndex = position .getRow ();
252
+
253
+ if (rowIndex < 0 || rowIndex >= table .getItems ().size ())
254
+ continue ;
255
+
256
+ for (TableColumn <?, ?> column : table .getColumns ()) {
257
+ if (!column .isVisible ())
258
+ continue ;
259
+
260
+ Object cell = column .getCellData (rowIndex );
261
+
262
+ if (cell == null )
263
+ cell = " " ;
264
+
265
+ clipboardString .append (cell .toString ()).append ('\t' );
266
+ }
267
+ clipboardString .append ("\r \n " );
268
+ }
269
+
270
+ final ClipboardContent clipboardContent = new ClipboardContent ();
271
+ clipboardContent .putString (clipboardString .toString ());
272
+ Clipboard .getSystemClipboard ().setContent (clipboardContent );
273
+ }
274
+
223
275
public static Object getValueAt (TableView <?> table , int columnIndex , int rowIndex ) {
224
- return table .getColumns ().get (columnIndex ).getCellObservableValue (rowIndex ).getValue ();
276
+ return table .getColumns ().get (columnIndex ).getCellObservableValue (rowIndex ).getValue ();
225
277
}
226
- }
278
+ }
0 commit comments