我有一个带有TableView的JavaFX桌面应用程序。我使用名为Orders的POJO填充数据,这些订单最终来自Firebird SQL数据库。 Image of what I have now
我要做的是更改第一列中每个单元格的背景填充颜色'状态'取决于文本值。因此,如果文本值是“准备好”,那么绿色,开始'将是黄色的' DONE'将是灰色的。 Image of what I would like
以下是我用来填充TableView的代码部分:
`
@FXML private TableView<Orders> tblOrders;
@FXML private TableColumn<Orders, Integer> clmStatus;
@FXML private TableColumn<Orders, String> clmStartDateTime;
@FXML private TableColumn<Orders, String> clmShopOrder;
@FXML private TableColumn<Orders, String> clmRotation;
@FXML private TableColumn<Orders, String> clmGMIECode;
@FXML private TableColumn<Orders, String> clmSAPCode;
@FXML private TableColumn<Orders, Integer> clmLineName;
@FXML private TableColumn<Orders, Integer> clmOrderProductionNr;
private ObservableList<Orders> list;
public void initialize(URL location, ResourceBundle resources) {
populateTable();
}
private void populateTable() {
log.appLog("Populating table\r\n");
clmStatus.setCellValueFactory(new PropertyValueFactory<>("status"));
clmStartDateTime.setCellValueFactory(new PropertyValueFactory<>
("startDateTime"));
clmShopOrder.setCellValueFactory(new PropertyValueFactory<>("extra1"));
clmRotation.setCellValueFactory(new
PropertyValueFactory<("batchLotNr"));
clmGMIECode.setCellValueFactory(new PropertyValueFactory<>("wareNr"));
clmSAPCode.setCellValueFactory(new PropertyValueFactory<>
("serviceDescription"));
clmLineName.setCellValueFactory(new PropertyValueFactory<>
("productionLineNr"));
clmOrderProductionNr.setCellValueFactory(new PropertyValueFactory<>
("orderProductionNr"));
tblOrders.setItems(list);
}
`
我的订单POJO的代码示例:
`
public class Orders {
private final SimpleStringProperty status;
private final SimpleStringProperty startDateTime;
private final SimpleStringProperty extra1;
private final SimpleStringProperty batchLotNr;
private final SimpleStringProperty wareNr;
private final SimpleStringProperty serviceDescription;
private final SimpleStringProperty productionLineNr;
private final SimpleIntegerProperty orderProductionNr;
Orders(String status, String startDateTime, String extra1, String batchLotNr, String wareNr, String serviceDescription, String productionLineNr, int orderProductionNr) {
this.status = new SimpleStringProperty(status);
this.startDateTime = new SimpleStringProperty(startDateTime);
this.extra1 = new SimpleStringProperty(extra1);
this.batchLotNr = new SimpleStringProperty(batchLotNr);
this.wareNr = new SimpleStringProperty(wareNr);
this.serviceDescription = new SimpleStringProperty(serviceDescription);
this.productionLineNr = new SimpleStringProperty(productionLineNr);
this.orderProductionNr = new SimpleIntegerProperty((orderProductionNr));
}
public String getStatus() {
return status.get();
}
public String getStartDateTime() {return startDateTime.get(); }
public String getExtra1() {
return extra1.get();
}
public String getBatchLotNr() {
return batchLotNr.get();
}
public String getWareNr() {
return wareNr.get();
}
public String getServiceDescription() {
return serviceDescription.get();
}
public String getProductionLineNr() {
return productionLineNr.get();
}
int getOrderProductionNr() {return orderProductionNr.get();}
}
`
我尝试过使用回调但我以前从未使用过回调,也没有正确理解我如何能够满足回调需求。任何帮助对我的学习都很重要。谢谢你。
答案 0 :(得分:2)
我终于找到了解决方案而无需使用任何额外的类,只需在我的控制器类中通过此SO链接进行回调: StackOverFlow Link
`
private void populateTable() {
log.appLog("Populating table\r\n");
//clmStatus.setCellValueFactory(new PropertyValueFactory<>("status"));
clmStatus.setCellFactory(new Callback<TableColumn<Orders, String>,
TableCell<Orders, String>>()
{
@Override
public TableCell<Orders, String> call(
TableColumn<Orders, String> param) {
return new TableCell<Orders, String>() {
@Override
protected void updateItem(String item, boolean empty) {
if (!empty) {
int currentIndex = indexProperty()
.getValue() < 0 ? 0
: indexProperty().getValue();
String clmStatus = param
.getTableView().getItems()
.get(currentIndex).getStatus();
if (clmStatus.equals("READY")) {
setTextFill(Color.WHITE);
setStyle("-fx-font-weight: bold");
setStyle("-fx-background-color: green");
setText(clmStatus);
} else if (clmStatus.equals("STARTED")){
setTextFill(Color.BLACK);
setStyle("-fx-font-weight: bold");
setStyle("-fx-background-color: yellow");
setText(clmStatus);
} else if (clmStatus.equals("DONE")){
setTextFill(Color.BLACK);
setStyle("-fx-font-weight: bold");
setStyle("-fx-background-color: gray");
setText(clmStatus);
} else {
setTextFill(Color.WHITE);
setStyle("-fx-font-weight: bold");
setStyle("-fx-background-color: red");
setText(clmStatus);
}
}
}
};
}
});
clmStartDateTime.setCellValueFactory(new PropertyValueFactory<>("startDateTime"));
clmShopOrder.setCellValueFactory(new PropertyValueFactory<>("extra1"));
clmRotation.setCellValueFactory(new PropertyValueFactory<>("batchLotNr"));
clmGMIECode.setCellValueFactory(new PropertyValueFactory<>("wareNr"));
clmSAPCode.setCellValueFactory(new PropertyValueFactory<>("serviceDescription"));
clmLineName.setCellValueFactory(new PropertyValueFactory<>("productionLineNr"));
clmOrderProductionNr.setCellValueFactory(new PropertyValueFactory<>("orderProductionNr"));
tblOrders.setItems(list);
}
`
答案 1 :(得分:0)
您必须为状态列定义自定义TableCell
,如下所示:
public class ColoredStatusTableCell extends TableCell<TableRow, Status> {
@Override
protected void updateItem(Status item, boolean empty) {
super.updateItem(item, empty);
if (empty || getTableRow() == null) {
setText(null);
setGraphic(null);
} else {
TableRow row = (TableRow) getTableRow().getItem();
setText(item.toString());
setStyle("-fx-background-color: " + row.getColorAsString());
// If the statis is changing dynamic you have to add the following:
row.statusProperty()
.addListener((observable, oldValue, newValue) ->
setStyle("-fx-background-color: " + row.getColorAsString()));
}
}
}
TableRow
:
public class TableRow {
private ObjectProperty<Status> status;
private Map<Status, Color> statusColor;
public TableRow(Status status, Map<Status, Color> statusColor) {
this.status = new SimpleObjectProperty<>(status);
this.statusColor = statusColor;
}
public Status getStatus() {
return status.get();
}
public ObjectProperty<Status> statusProperty() {
return status;
}
public Color getStatusColor() {
return statusColor.get(status.get());
}
public String getColorAsString() {
return String.format("#%02X%02X%02X",
(int) (getStatusColor().getRed() * 255),
(int) (getStatusColor().getGreen() * 255),
(int) (getStatusColor().getBlue() * 255));
}
}
状态:
public enum Status {
READY, STARTED, DONE
}
和控制器:
public class TestController {
@FXML
private TableView<TableRow> table;
@FXML
private TableColumn<TableRow, Status> column;
private ObservableList<TableRow> data = FXCollections.observableArrayList();
@FXML
public void initialize() {
column.setCellValueFactory(data -> data.getValue().statusProperty());
column.setCellFactory(factory -> new ColoredStatusTableCell());
Map<Status, Color> statusColor = new HashMap<>();
statusColor.put(Status.READY, Color.GREEN);
statusColor.put(Status.STARTED, Color.YELLOW);
statusColor.put(Status.DONE, Color.GRAY);
TableRow ready = new TableRow(Status.READY, statusColor);
TableRow started = new TableRow(Status.STARTED, statusColor);
TableRow done = new TableRow(Status.DONE, statusColor);
data.addAll(ready, started, done);
table.setItems(data);
}
}
我选择将状态设置为enum
,因为它更容易处理,
然后我使用了一个地图到每个状态 - 颜色组合,然后在单元格中,您可以将其背景颜色设置为状态的匹配颜色。
如果你想要而不是Color.YELLOW
等,你可以使用自定义Color.rgb(red,green,blue)