Вопрос по javafx-2 – Отключить TableRow на основе данных

2

Я сталкиваюсь с проблемой с TableView в JavaFX 2.1. Я хочу отключить TableRow на основе данных.

Например:

public class RowData() {
private String name;
private boolean used;

public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isUsed(){
return this.used;
}
public void setUsed(boolean used) {
this.used = used;
}

}

В программе:

    public class ViewController implements Initializable {
    @FXML
        private TableView<RowData> tableAttribute;
    public void initialize(URL location, ResourceBundle resources) {
    List<RowData> data = new ArrayList<RowData>();
            // datatype col
            TableColumn<DataRow, String> attNameCol = new TableColumn<DataRow, DataRow>(
            "Name");
            attNameCol 
            .setCellValueFactory(new PropertyValueFactory<DataRow, String>(
                    "name"));
            attNameCol .setMinWidth(110.0);
            tableComponent.getColumns().addAll(attNameCol );
    loadData(data);

    tableAttribute.setItems(FXCollections.observableList(data));

    //I want to disable row which used = true, enable otherwise

    }
}

Как я могу сделать, чтобы достичь этого?

Поможет ли щедрость? Thinhbk

Ваш Ответ

1   ответ
6

Use a rowFactory which renders the row content as disabled as needed. After the table has been shown, lookupAll the TableRows and render them as disabled as appropriate.

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

Ключевой логикой в примере является следующий кодafter the table has been shown on an active stage, который включает и отключает строки по мере необходимости (а также применяет классы стилей к каждой строке, чтобы их можно было стилизовать отдельно, если это необходимо). Обратите внимание, что для этого подхода, если строки в таблице изменяются или переупорядочиваются, то после повторного рендеринга таблицы необходимо повторно выполнить поиск и включение / отключение кода над таблицей, чтобы таблица была правильно оформлена. и имеет правильные отключенные свойства для строк.

// highlight the table rows depending upon whether we expect to get paid.
int i = 0;
for (Node n: table.lookupAll("TableRow")) {
  if (n instanceof TableRow) {
    TableRow row = (TableRow) n;
    if (table.getItems().get(i).getWillPay()) {
      row.getStyleClass().add("willPayRow");
      row.setDisable(false);
    } else {
      row.getStyleClass().add("wontPayRow");
      row.setDisable(true);
    }
    i++;
    if (i == table.getItems().size())
      break;
  }
}

When using a fxml controller the lookupAll return 0 "TableRow" nodes. It seems that after table.setItems(data) when doing lookup rows are populated why ?

Прежде чем ответить на это, я отмечу, что использование rowFactory действительно является предпочтительным решением этого вопроса, а не поиском. Некоторые из причин, почему это станет очевидным в остальной части этого ответа. Для примера подхода rowFactory, пожалуйста, обратитесь к этомусвязанный пример кода от james-d.

Поиск - это операция CSS, которая требует, чтобы css был применен к просматриваемым узлам. Чтобы явно применить CSS, позвонитеapplyCss после того, как узел был размещен в сцене.

Трудность с контроллером заключается в том, что при вызове инициализации узел еще не может быть в сцене. Чтобы обойти эту проблему, вы можете применить следующий шаблон:

Pane parent = (Pane) table.getParent();
parent.getChildren().remove(table);
Scene applyCssScene = new Scene(table);
table.applyCss();
table.layout();
applyCssScene.setRoot(null);
if (parent != null) {
    // Assumes that the original order in the parent does not matter.
    // If it did, you would also need to keep track of the child list position.
    parent.getChildren().add(table);
}
. . .
// perform css based lookup operation on the table.

Это создает сцену фиктивного держателя с таблицей в ней, применяет CSS (после чего сработают операции поиска на основе CSS), а затем удаляет таблицу со сцены, чтобы вы могли добавить ее в реальную сцену позже, а затем размещает обратно в исходный родительский элемент. Как вы могли заметить, это немного сбивает с толку. Обратите внимание, что я на самом деле не пытался выполнить процесс приложения CSS, описанный выше, в примере приложения с контроллером FXML, однако я считаю, что он будет работать.

В приведенном мной примере приложения, в котором используется поиск, описанная выше сложность не требуется, поскольку поиск выполненafter Этап, содержащий таблицу, был первоначально показан. Вызов stage.show () неявно запускает макет и приложение css передает отображаемую сцену (это необходимо сделать, чтобы определить начальный размер сцены на основе вычисленного размера начальной сцены и, возможно, по другим причинам).

К сожалению, строки не были отключены, как ожидалось. Я использовал 1-й подход (установить cellFactory). Я постараюсь использовать второй подход и дам вам знать позже. Thinhbk
Хассам, трудно ответить на твой вопрос отладки, не видя твой код. Я также не являюсь экспертом в подходе, основанном на фабрике рядов. Возможно, задайте новый вопрос и включитеmcve and stacktrace в этом, и вы сможете получить больше помощи.
На самом деле, вы правы, подход, основанный на контроллере FXML, будет немного более сложным, чем исходный пример. Я добавил некоторые пояснения относительно того, почему и как адаптировать решение для выполнения в контроллере FXML.
Я полагаю, что ваше решение должно работать в обычном случае, но в моем случае оно не работает, потому что у меня в ячейке таблицы 2 Combobox и 1 флажок. Я пытался установить с помощью обоих подходов, но не удалось. Я что-то пропустил? Thinhbk
Был ли пример приложения, на которое я ссылался, отключить строки, как вы ожидали? Если это так, я считаю, что подход должен быть адаптирован к вашему коду, потому что содержимое ячеек не имеет значения для подхода, основанного на поиске. Для подхода rowFactory вам просто нужно позаботиться о том, чтобы вы правильно отображали строки с помощью фабрики строк.

Похожие вопросы