【发布时间】:2019-01-28 08:35:01
【问题描述】:
我有一个 TableView 和两个文本字段。当用户将数字写入文本字段并按下按钮时。所有的 tablerows 都应该按百分比绘制。例如,30% 应该是黄色,70% 应该是绿色。
我尝试使用查找方法来查找 TableView 对象。添加新的 css 类改变了 tablerows 的颜色。但是这个解决方案并不好。 Lookup 只能找到可见元素。
@FXML
void confirmPercentage(ActionEvent event) {
clearSelectionsOfTestingTbaleView();
TableRow[] tableRows = selectTrainingDataTableView.lookupAll(".table-row-cell").toArray(new TableRow[0]);
double percent = Double.parseDouble(this.trainingSetPercentageTextField.getText());
percent = percent > 1 ? percent / 100 : percent;
int trainIndexes = (int) (Math.round(tableRows.length * percent));
for (int i = 0 ; i < trainIndexes; i++){
tableRows[i].getStyleClass().add("selected-as-train");
}
}
那么绘制所有表格行的方法是什么?
解决方案
我终于看到了!
所以我创建了两组来保留选定的索引。而且,我只是根据这个索引设置 PseudoClass...
void init()
Set<Integer> testSetIndexes = new HashSet<>();
Set<Integer> trainSetIndexes = new HashSet<>();
tableView.setRowFactory( tableView2 -> {
PseudoClass train = PseudoClass.getPseudoClass("train");
PseudoClass test = PseudoClass.getPseudoClass("test");
PseudoClass trainAndTest = PseudoClass.getPseudoClass("train-and-test");
/*Percentage selection with button*/
final TableRow<List<Double>> row = new TableRow<List<Double>>(){
@Override
public void updateItem(List<Double> item, boolean empty){
if (item != null) {
int index = dataInsideTableView.indexOf(item);
this.pseudoClassStateChanged(train, trainSetIndexes.contains(index));
this.pseudoClassStateChanged(test, testSetIndexes.contains(index));
this.pseudoClassStateChanged(trainAndTest, trainSetIndexes.contains(index) && testSetIndexes.contains(index));
} else {
this.pseudoClassStateChanged(train, false);
this.pseudoClassStateChanged(test, false);
this.pseudoClassStateChanged(trainAndTest, false);
}
}
};
/*Mouse selection*/
row.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if (manualSelectionCheckBox.isSelected()) {
if (event.isPrimaryButtonDown()) {
int index = dataInsideTableView.indexOf(row.getTableView().getItems().get(row.getIndex()));
if(trainSetIndexes.contains(index)){
trainSetIndexes.remove(index);
} else {
trainSetIndexes.add(index);
}
selectTrainingDataTableView.refresh(); //call update
} else if (event.isSecondaryButtonDown()) {
int index = dataInsideTableView.indexOf(row.getTableView().getItems().get(row.getIndex()));
if(testSetIndexes.contains(index)){
testSetIndexes.remove(index);
} else {
testSetIndexes.add(index);
}
tableView.refresh();
}
}
}
});
return row;
});
我点击“刷新”按钮,confirmPercentage 方法只是重新计算索引并刷新表格。
@FXML
void confirmPercentage(ActionEvent event) {
trainSetIndexes.clean();
testSetIndexes.clean();
double percent = Double.parseDouble(this.trainingSetPercentageTextField.getText());
percent = percent > 1 ? percent / 100 : percent;
trainSize = (int) (Math.floor(usedData.size() * percent));
percent = Double.parseDouble(this.testingSetPercentageTextField .getText());
percent = percent > 1 ? percent / 100 : percent;
testSize = (int) (Math.floor(usedData.size() * percent));
//put indexes
for (int i = 0 ; i < trainSize; i++){
trainSetIndexes.add(i);
}
for (int i = usedData.size()-1 ; i >= usedData.size()-1-testSize; i--){
testSetIndexes.add(i);
}
this.tableView.refresh();
}
【问题讨论】:
-
完全错误的方法:永远不要考虑场景图中的 tableRow,而是使用自定义 cellFactory 来根据模型中的状态配置自身的行(并且不要忘记 模型那个状态)
-
@JanS。它不是重复的,因为 UpdateItem 适用于可见行。我尝试了 RowFactory - 它也适用于可见行。当他们因为滚动 RowFactory 不与他们一起工作而隐藏时
-
没有不可见的行,它们不存在 ;) 请阅读单元格的重用机制
-
请不要删除您的问题只是为了再次提出相同的问题 - 所有输入都将丢失,这对所有相关人员来说都是浪费时间
-
@kleopatra 但我不认为这个问题是重复的。另一个主题中提出的解决方案让我添加了一个新列以某种方式解决问题。我认为这是我的任务的拐杖,它在某种程度上破坏了数据。