/
CellSpanTableView.java
104 lines (93 loc) · 2.95 KB
/
CellSpanTableView.java
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package net.jonathangiles.hacking.tableview.cellSpan;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
/**
*
*/
public class CellSpanTableView<S> extends TableView<S> {
public CellSpanTableView() {
super();
getStyleClass().add(DEFAULT_STYLE_CLASS);
this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
registerCellListener();
}
public CellSpanTableView(ObservableList<S> items) {
super(items);
getStyleClass().add(DEFAULT_STYLE_CLASS);
this.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
registerCellListener();
}
// --- Span Model
private ObjectProperty<SpanModel> spanModel = new SimpleObjectProperty<SpanModel>(this,
"spanModel");
public final ObjectProperty<SpanModel> spanModelProperty() {
return spanModel;
}
public final void setSpanModel(SpanModel value) {
spanModelProperty().set(value);
}
public final SpanModel getSpanModel() {
return spanModel.get();
}
/***************************************************************************
* * Stylesheet Handling * *
**************************************************************************/
private static final String DEFAULT_STYLE_CLASS = "cell-span-table-view";
private boolean isFirstRun = true;
@Override
protected void layoutChildren() {
// ugly hack to enable adding the cell-span.css file to the scenegraph
// without requiring user intervention
if (isFirstRun) {
Scene scene = getScene();
if (scene != null) {
ObservableList<String> stylesheets = scene.getStylesheets();
String cssPath = CellSpanTableView.class.getResource("cell-span.css")
.toExternalForm();
if (!stylesheets.contains(cssPath)) {
stylesheets.add(cssPath);
isFirstRun = false;
}
}
}
super.layoutChildren();
}
public void registerCellListener() {
final TableView.TableViewSelectionModel<S> sm = this.getSelectionModel();
sm.getSelectedCells().addListener(new ListChangeListener<TablePosition>() {
@Override
public void onChanged(Change<? extends TablePosition> change) {
final CellSpanTableView<S> tableView = CellSpanTableView.this;
if (sm.getSelectedCells().isEmpty()) {
return;
}
final TablePosition tp = sm.getSelectedCells().get(0);
if (tp == null) {
return;
}
CellSpan cellSpan = tableView.getSpanModel().getCellSpanAt(
tp.getRow(), tp.getColumn());
if(null == cellSpan) {
return;
}
final int rowSpan = cellSpan.getRowSpan();
if(rowSpan < 2) {
return;
}
for(int row = tp.getRow(); row < tp.getRow() + rowSpan; row++) {
if(sm.isSelected(row)) {
continue;
}
tableView.getSelectionModel().select(row);
System.out.println(row);
}
}
});
}
}