Измените стиль ComboBox, если ChangeListener обнаружит изменение

Я унаследовал некоторый код, который я пытаюсь расширить, изменив цвет границы ComboBox на основе обнаруженного изменения значения ComboBox. Однако кажется, что любые изменения, внесенные в стиль ComboBox, не выходят за пределы лямбды ChangeListener.

По сути, граница ComboBox инициализируется черным цветом, и я хочу изменить цвет после того, как пользователь изменит значение, но цвет, установленный внутри ChangeListener, не применяется. Когда я просматриваю код, я вижу изменение строки стиля внутри лямбда-прослушивателя ChangeListener, но она возвращается к исходной строке стиля, когда я выхожу из лямбда-прослушивателя ChangeListener.

Я включил код, который я изменяю ниже, с кодом, который я пытаюсь добавить, чтобы установить стиль ComboBox, вставленный и вызванный. Любая помощь будет оценена по достоинству.

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);
    }
}

person Curtis    schedule 06.07.2018    source источник
comment
Кроме того, границу трудно увидеть, если вы не увеличиваете размер, так как ComboBox не использует ее по умолчанию, поэтому результирующая граница имеет ширину всего 1 пиксель...   -  person fabian    schedule 06.07.2018
comment
Также это не восстановит внешний вид, когда элемент перемещается в другую ячейку. Кроме того, пустые ячейки сохранят ComboBox как graphic. Также вы воссоздаете ComboBox каждый раз, когда элемент заменяется...   -  person fabian    schedule 06.07.2018
comment
@fabian Извините, я не понимаю, какое отношение вопрос о сравнении связанных строк имеет к настройке стиля ComboBox внутри файла . Возможно, вы имели в виду, как я использовал newValue == "" вместо newValue.equals("")?   -  person Curtis    schedule 06.07.2018


Ответы (1)


Я думаю, проблема в том, что граница сбрасывается при вашем searchRecordsTable.refresh(); звонке. Кажется, снова вызывается функция updateItem(String item, boolean empty). Вам нужно убедиться, что вы храните состояние в другом месте, например. хэш-карта. Что-то вроде этого:

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;");
}
person Halko Karr-Sajtarevic    schedule 07.07.2018