我有一个TableView和两个文本字段。当用户将数字写入文本字段并按下按钮时。所有桌布都应按百分比绘制。例如,30%应该是黄色,70%应该是绿色。
我试图使用查找方法来查找TableView对象。添加新的CSS类会更改表行的颜色。但是这种解决方案不是很好。查找只能找到可见的元素。
@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();
}
答案 0 :(得分:-1)
您可以将TableRow StyleClass
作为TableView数据模型中的字段
fxml视图
<VBox fx:id="root" prefHeight="300.0" prefWidth="600.0" fx:controller="sample.View"
xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" >
<stylesheets>
<URL value="@app.css" />
</stylesheets>
<ToolBar>
<Button fx:id="set" mnemonicParsing="false" onAction="#set" text="Set" />
<Button fx:id="reset" mnemonicParsing="false" onAction="#reset" text="Reset" />
</ToolBar>
<TableView fx:id="tvDevices" VBox.vgrow="ALWAYS">
<columns>
<TableColumn fx:id="colNum1" text="Num1">
<cellValueFactory>
<PropertyValueFactory property="num1" />
</cellValueFactory>
</TableColumn>
<TableColumn fx:id="colNum2" text="Num2">
<cellValueFactory>
<PropertyValueFactory property="num2" />
</cellValueFactory>
</TableColumn><TableColumn fx:id="colNum3" text="Num3">
<cellValueFactory>
<PropertyValueFactory property="num3" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
</VBox>
数据视图模型类
public class Foo {
private DoubleProperty num1;
private DoubleProperty num2;
private DoubleProperty num3;
private StringProperty styleClass;
public Foo(int num1, int num2, int num3) {
this.num1 = new SimpleDoubleProperty(num1);
this.num2 = new SimpleDoubleProperty(num2);
this.num3 = new SimpleDoubleProperty(num3);
this.styleClass = new SimpleStringProperty();
}
public double getNum1() {
return num1.get();
}
public DoubleProperty num1Property() {
return num1;
}
public void setNum1(double num1) {
this.num1.set(num1);
}
public double getNum2() {
return num2.get();
}
public DoubleProperty num2Property() {
return num2;
}
public void setNum2(double num2) {
this.num2.set(num2);
}
public double getNum3() {
return num3.get();
}
public DoubleProperty num3Property() {
return num3;
}
public void setNum3(double num3) {
this.num3.set(num3);
}
public String getStyleClass() {
return styleClass.get();
}
public StringProperty styleClassProperty() {
return styleClass;
}
public void setStyleClass(String styleClass) {
this.styleClass.set(styleClass);
}
}
视图控制器
public class View implements Initializable {
@FXML
private TableView<Foo> tvDevices;
@Override
public void initialize(URL location, ResourceBundle resources) {
tvDevices.setRowFactory(param -> {
TableRow<Foo> row = new TableRow<>();
//This listener will monitor the Change in the Modal StyleClass to keep row updated when StyleClass value chenge.
ChangeListener<String> listener = (observable, oldValue, newValue) -> {
if (newValue == null) {
//reset StyleClass to default by removing any additional class's
row.getStyleClass().remove(3,row.getStyleClass().size());
} else {
//removing any additional class's and add the new one
row.getStyleClass().remove(3,row.getStyleClass().size());
row.getStyleClass().add(newValue);
}
};
//This listener will monitor the particular Modal attached to this row.
row.itemProperty().addListener((observable, oldValue, newValue) -> {
if (oldValue != null) {
//remover the listener from the old item
oldValue.styleClassProperty().removeListener(listener);
}
if (newValue != null) {
// attach the listener to the new item
newValue.styleClassProperty().addListener(listener);
// update row StyleClass to new item StyleClass
if (newValue.styleClassProperty() == null) {
row.getStyleClass().remove(3,row.getStyleClass().size());
} else {
row.getStyleClass().remove(3,row.getStyleClass().size());
row.getStyleClass().add(newValue.getStyleClass());
}
} else {
//reset StyleClass to default because new item is null
row.getStyleClass().remove(3,row.getStyleClass().size());
}
});
return row;
});
for (int i = 0; i < 50; i++) {
tvDevices.getItems().add(new Foo(1, 2, 3));
}
}
@FXML
private void reset(ActionEvent actionEvent) {
tvDevices.getItems().forEach(foo -> foo.setStyleClass(null));
actionEvent.consume();
}
@FXML
private void set(ActionEvent actionEvent) {
tvDevices.getItems().get(10).setStyleClass("class1");
tvDevices.getItems().get(20).setStyleClass("class2");
tvDevices.getItems().get(40).setStyleClass("class3");
actionEvent.consume();
}
}