JAVAFX: поведение при выборе строки таблицы - PullRequest
0 голосов
/ 26 июня 2018

У меня есть следующий фрагмент кода для установки цвета фона TableRow,

column.setCellFactory((TableColumn<Model, Integer> p) -> {
           ComboBoxTableCell cell = new ComboBoxTableCell(FXCollections.observableArrayList(0, 1)) {
               @Override
               public void updateItem(Object item, boolean empty) {
                   super.updateItem(item, empty);
                   if (!empty && item != null) {
                       if(Integer.valueOf(item.toString()) == 1){
                           getTableRow().setStyle("-fx-background-color: khaki;");
                       }else if(Integer.valueOf(item.toString()) == 0){
                           getTableRow().setStyle(null);
                       }
                   }
               }
           };
           return cell;
        });

Проблема в том, что когда я выбираю строку с фоном, установленным на какой-либо цвет, синий цвет по умолчанию, который указывает, что выбор идет позади. (как показано ниже)

enter image description here

Как сохранить цвет выбора по умолчанию?

1 Ответ

0 голосов
/ 26 июня 2018

Встроенный стиль имеет более высокий приоритет, чем таблицы стилей CSS. Поэтому фон для выбранных строк также переопределяется. Способ создания фона требует, чтобы вы указали -fx-control-inner-background-alt и -fx-control-inner-background.

[...].setStyle("-fx-control-inner-background: khaki; -fx-control-inner-background-alt: khaki;")

Однако есть проблема, которая намного хуже:

Вы устанавливаете стиль из TableCell s. Поскольку TableView отвечает за присвоение элементов ячейкам, порядок, в котором это делается, является подробностью реализации, приводящей к произвольным результатам, если вы используете тип ячейки в разных столбцах. Даже если вы используете эти ячейки только в одном столбце, вы никогда не обработаете случай, когда ячейки станут пустыми, поэтому даже пустые ячейки могут все еще содержать новый цвет.

Стиль строки относится к строкам таблицы.

Также вы получаете максимальную гибкость, если используете PseudoClass и таблицу стилей CSS.

1019 * Е.Г. *

final PseudoClass one = PseudoClass.getPseudoClass("one");
tableView.setRowFactory(t -> new TableRow<Model>() {

    private ChangeListener<Integer> listener = (o, oldValue, newValue) -> {
        pseudoClassStateChanged(one, newValue == 1);
    };

    @Override
    protected void updateItem(Model model, boolean empty) {
        if (getItem() != null) {
            getItem().myValueProperty().removeListener(listener);
        }

        super(model, empty);

        if (empty || model == null) {
            listener.changed(null, 0, -1);
        } else {
            model.myValueProperty().addListener(listener);
            listener.changed(null, 0, model.getMyValue());
        }
    }


});

Таблица стилей CSS

.table-row-cell:one {
    -fx-control-inner-background: khaki;
    -fx-control-inner-background-alt: khaki;
}

Кроме того, вы должны использовать параметры типа, чтобы избежать преобразования в ваш элемент из Integer в String и обратно в Integer (который следует заменить на приведение, если это необходимо сделать таким образом. В этом случае лучше не использовать необработанные типы.).

final ObservableList<Integer> values = FXCollections.observableArrayList(0, 1);

column.setCellFactory((TableColumn<Model, Integer> p) -> {
    ComboBoxTableCell<Model, Integer> cell = new ComboBoxTableCell<Model, Integer>(values) {
        @Override
        protected void updateItem(Integer item, boolean empty) {
            ...
        }
    };
    return cell;
});
...