I've inherited some code that I'm trying to extend by changing the border color of a ComboBox based on a detected ComboBox value change. However, it seems that any changes made to the ComboBox style do not make it outside of the ChangeListener lambda.
Basically, the ComboBox border is initialized to black and I want to change to color after the user changes the value, but the color set inside the ChangeListener doesn't get applied. When I step through the code I see the style string change inside the lambda ChangeListener, but it goes back to the initial style string when I exit the lambda ChangeListener.
I've included the code I'm modifying below, with the code I'm trying to add set the ComboBox style inserted and called out. Any help would be appreciated.
public class SearchScreenController
{
@FXML
private TableView<ConfigBaselineFileArtifact> searchRecordsTable;
@FXML
private TableColumn<ConfigBaselineFileArtifact, String> categoryColumn = new TableColumn<>("File Category");
@FXML
private TableColumn<ConfigBaselineFileArtifact, ConfigBaselineFileArtifact> subcategoryColumn = new TableColumn<>("File Subcategory")
private void createSearchTable()
{
searchRecordsTable.getColumns().clear();
//File Category and Subcategory Columns
categoryColumn.setCellValueFactory(new PropertyValueFactory<>("fileCategoryName"));
subcategoryColumn.setCellValueFactory(value -> new SimpleObjectProperty(value.getValue()));
categoryColumn.setCellFactory(param -> new TableCell<ConfigBaselineFileArtifact, String>() {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
ComboBox<String> cb = new ComboBox<String>(FXCollections.observableArrayList(categoryList));
cb.setValue(item);
cb.setPrefWidth(145);
cb.setStyle("-fx-background-color: transparent; -fx-border-color: black;");
cb.getSelectionModel().selectedItemProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {
if (newValue != null) {
int index = getIndex();
// Test for case that updated combobox isn't listed with list of selected records
if (!searchRecordsTable.getSelectionModel().getSelectedIndices().contains(index)) {
searchRecordsTable.getItems().get(index).setFileCategoryName(newValue);
searchRecordsTable.getItems().get(index).setFileSubCategoryName("");
DataStore.getInstance().saveConfigBaselineFileArtifact(searchRecordsTable.getItems().get(index));
} else {
// Else if updated combobox IS within list of selected records
searchRecordsTable.getSelectionModel().getSelectedItems().forEach(record -> {
record.setFileCategoryName(newValue);
record.setFileSubCategoryName("");
DataStore.getInstance().saveConfigBaselineFileArtifact(record);
});
}
// Code I'm trying to add is below
if (newValue.equals("")) {
cb.setStyle("-fx-background-color: transparent; -fx-border-color: red;");
} else {
cb.setStyle("-fx-background-color: transparent; -fx-border-color: green;");
// Code I'm trying to add is above
searchRecordsTable.refresh();
}
});
setGraphic(cb);
}
}
});
searchRecordsTable.getColumns().addAll(checkBoxColumn, fileNameColumn, artifactNameColumn, categoryColumn, subcategoryColumn, sensorNameColumn, subsystemColumn, componentColumn, dateImportedColumn, importedByColumn, labelsColumn);
searchRecordsTable.refresh();
searchRecordsTable.setEditable(true);
searchRecordsTable.getSelectionModel().getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
}
}
I think the problem is, that the border is being reset on your searchRecordsTable.refresh();
call. It seems that the updateItem(String item, boolean empty)
function is called again. You need to make sure, that you store the state anywhere else, e.g. a HashMap. Something like this:
private Map<String, Boolean> changeMap = new HashMap<>();
//in your selectedItem listener
if (newValue.equals("")) {
changeMap.remove(item);
} else {
changeMap.put(item, true);
}
//before setGraphic(cb)
if(changeMap.contains(item)) {
cb.setStyle("-fx-background-color: transparent; -fx-border-color: green;");
}