[英]JavaFX: How to correctly color background of the selected TableCell?
I want to change the row background color into green when to select a row. 我想在选择行时将行背景颜色更改为绿色。 However, although the selected row was changed color, the additionally wrong row was also changed color.
但是,尽管所选行已更改颜色,但另外错误的行也已更改颜色。 I can't figure out why??
我不知道为什么?
This is a JavaFX program coding in Intellij of Windows 10. 这是Windows 10 Intellij中的JavaFX程序编码。
TestFXML.java: TestFXML.java:
public class TestFXML implements Initializable {
@FXML
TableView<ItemLog> table;
@FXML
TableColumn<ItemLog,String> column1,column2,column4;
@FXML
TableColumn<ItemLog,Number> column3;
@Override
public void initialize(URL location, ResourceBundle resources) {
ObservableList<ItemLog> root=FXCollections.observableArrayList();
root.addAll(
new ItemLog("E0001","2.5㎟ XLPE", 1.2,"m"),
new ItemLog("E0002","4㎟ XLPE",1.5,"m"),
new ItemLog("E0003","6㎟ XLPE",2.0,"m"),
new ItemLog("E0004","10㎟ XLPE",4.0,"m"),
new ItemLog("E0005","16㎟ XLPE",6.2,"m"),
new ItemLog("E0006","25㎟ XLPE",9.1,"m"),
new ItemLog("E0007","35㎟ XLPE",14.5,"m"),
new ItemLog("E0008","50㎟ XLPE",20.6,"m"),
new ItemLog("E0009","70㎟ XLPE",31.2,"m"),
new ItemLog("E00010","120㎟ XLPE",40.5,"m"),
new ItemLog("E00011","150㎟ XLPE",55.3,"m"),
new ItemLog("E00012","185㎟ XLPE",78.8,"m"),
new ItemLog("E00013","240㎟ XLPE",96.0,"m"),
new ItemLog("E0101","2.5㎟ PVC", 1.2,"m"),
new ItemLog("E0102","4㎟ PVC",0.8,"m"),
new ItemLog("E0103","6㎟ PVC",1.2,"m"),
new ItemLog("E0104","10㎟ PVC",2.1,"m"),
new ItemLog("E0105","16㎟ PVC",4.3,"m"),
new ItemLog("E0106","25㎟ PVC",6.8,"m"),
new ItemLog("E0107","35㎟ PVC",9.5,"m"),
new ItemLog("E0108","50㎟ PVC",12.8,"m"),
new ItemLog("E0109","70㎟ PVC",16.9,"m"),
new ItemLog("E01010","120㎟ PVC",21.5,"m"),
new ItemLog("E01011","150㎟ PVC",27.6,"m"),
new ItemLog("E01012","185㎟ PVC",38.4,"m"),
new ItemLog("E01013","240㎟ PVC",52.9,"m")
);
table.setItems(root);
column1.setCellValueFactory(param -> param.getValue().code);
column2.setCellValueFactory(param -> param.getValue().description);
column3.setCellValueFactory(param -> param.getValue().price);
column4.setCellValueFactory(param -> param.getValue().unit);
//To change selected row color into green
table.getFocusModel().focusedCellProperty().addListener((observable, oldValue, newValue) -> {
if(newValue.getTableColumn() != null){
newValue.getTableColumn().setCellFactory(param -> new TableCell(){
@Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
}else{
setText(item.toString());
if(this.getIndex()==newValue.getRow()){
this.getTableRow().setStyle("-fx-background-color:green");
}
}
}
});
}
});
}
private class ItemLog {
StringProperty code=new SimpleStringProperty();
StringProperty description=new SimpleStringProperty();
DoubleProperty price=new SimpleDoubleProperty();
StringProperty unit=new SimpleStringProperty();
ItemLog(String code, String description, Double price, String unit) {
this.code.set(code);
this.description.set(description);
this.price.set(price);
this.unit.set(unit);
}
}
}
TestFXML.fxml: TestFXML.fxml:
<Pane prefHeight="414.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TestFXML">
<children>
<TableView fx:id="table" maxHeight="1.7976931348623157E308" prefHeight="421.0" prefWidth="602.0">
<columns>
<TableColumn fx:id="column1" editable="false" prefWidth="100.0" text="A" />
<TableColumn fx:id="column2" editable="false" prefWidth="300.0" text="B" />
<TableColumn fx:id="column3" editable="false" prefWidth="100.0" text="C" />
<TableColumn fx:id="column4" editable="false" prefWidth="100.0" text="D" />
</columns>
</TableView>
</children>
</Pane>
I expected when I select 1st row, only 1st row changes in to green color. 我希望在选择第一行时,只有第一行变为绿色。 Actual result is when I selected 1st row, 1st and 19th rows changed in to green color.
实际结果是当我选择第一行,第一行和第19行变为绿色时。
There are 3 issues with your approach: 您的方法存在3个问题:
TableView
usually does not recreate the cells, if the cellFactory
changes. cellFactory
发生更改, TableView
通常不会重新创建单元格。 Each cellFactory
chooses to highlight a cell based on the focused cell at the time the cellFactory
creating the cell was created . cellFactory
在创建创建该单元格的cellFactory
时根据突出显示的单元格选择突出显示一个单元格 。 Even if cells were recreated, you'd still see highlighted cells in other columns, since you never change back to a cellFactory
not highlighting cells. cellFactory
。 Doing those modifications is much simpler, if you use a CSS stylesheet, since TableCell
s get assigned a pseudo class when they get focused allowing you to only define the style of focused cells without the need to worry about cellFactory
s: 如果使用CSS样式表,则进行这些修改要简单得多,因为
TableCell
在获得焦点时会被分配一个伪类,从而使您只需定义焦点单元格的样式即可,而不必担心cellFactory
:
style.css style.css文件
.table-cell:selected {
-fx-background-color: green;
}
fxml FXML
<Pane stylesheets="style.css" prefHeight="414.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TestFXML">
...
</Pane>
Remove the cellFactory
assignments from your java code for the above approach to work. 从Java代码中删除
cellFactory
分配,以使上述方法起作用。
To only style specific TableView
s this way you could eg add a style class to the TableView
and select it based on the style class of the TableView
, eg 要仅风格特异
TableView
s这个方式,你可以如样式类添加到TableView
并选择它基于风格类的TableView
,如
.my-tableview .table-cell:selected {
-fx-background-color: green;
}
Also it becomes much simpler to combine different criteria, eg 合并不同的标准也变得更加简单,例如
/* style for selected and hovered cell */
.table-cell:selected:hover {
-fx-background-color: yellow;
}
I got the solution by myself. 我自己找到了解决方案。 To Modify that:
修改它:
if(this.getIndex()==newValue.getRow()){
this.getTableRow().setStyle("-fx-background-color:green");
}
into: 成:
if(this.getIndex()==newValue.getRow()){
this.getTableRow().setStyle("-fx-background-color:green");
}else{
this.getTableRow().setStyle("");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.