JavaFX 2 TableView: разные фабрики ячеек в зависимости от данных внутри ячейки

Я пытаюсь использовать табличное представление для рендеринга / редактирования "ключ = значение " пар. Таким образом, таблица должна иметь два столбца:ключ» а также "значение", Ключ - это обычная строка, а значением может быть что угодно. Моя проблема заключается в том, что тип данных значений может отличаться от строки к строке. По сути, я хотел использовать чекбоксы для логических значений и выбор для списков. Я нашел способ визуализации всего столбца таблицы с помощью флажков или вариантов, установив фабрику ячеек:

final TableColumn valueColumn = new TableColumn("Value");
valueColumn.setCellFactory(new Callback() {
    @Override
    public TableCell call(final TableColumn column) {
        // if (value instanceof Boolean)
        return new CheckBoxTableCell();
    }
});

Но мне нужно иметь возможность вставлять условие, основанное на типе элемента, который будет отображаться внутри ячейки. Другими словами, некоторые фабрики ячеек находятся на уровне ячеек, а не на уровне столбцов. И это оценивает мое состояние во время рендеринга. У меня нетЯ не нашел еще решения для этого. Может быть, у кого-то есть подходящие методы для реализации такого рода рендеринга? Может быть, какой-то сторонний датагрид?

Ответы на вопрос(1)

Решение Вопроса

Вот таблица, отображающая пары строк и объектов различных типов.

Пользовательская фабрика ячеек используется для обработки отображения различных типов объектов (путем выполнения проверки экземпляра объекта 's печатать и отображать соответствующий текст или графику).

import javafx.application.*;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.Pair;

public class PairTable extends Application {
    public static final String NAME_COLUMN_NAME  = "Name";
    public static final String VALUE_COLUMN_NAME = "Value";

    final TableView table = new TableView();

    public static void main(String[] args) throws Exception {
        launch(args);
    }

    public void start(final Stage stage) throws Exception {
        // model data
        ObservableList data = FXCollections.observableArrayList(
                pair("Song", "Bach Cello Suite 2"),
                pair("Image", new Image("http://upload.wikimedia.org/wikipedia/en/9/99/Bach_Seal.jpg")),
                pair("Rating", 4),
                pair("Classic", true),
                pair("Song Data", new byte[]{})
        );

        table.getItems().setAll(data);
        table.setPrefHeight(275);

        // table definition
        TableColumn nameColumn = new TableColumn(NAME_COLUMN_NAME);
        nameColumn.setPrefWidth(100);
        TableColumn valueColumn = new TableColumn(VALUE_COLUMN_NAME);
        valueColumn.setSortable(false);
        valueColumn.setPrefWidth(150);

        nameColumn.setCellValueFactory(new PairKeyFactory());
        valueColumn.setCellValueFactory(new PairValueFactory());

        table.getColumns().setAll(nameColumn, valueColumn);
        valueColumn.setCellFactory(new Callback() {
            @Override
            public TableCell call(TableColumn column) {
                return new PairValueCell();
            }
        });

        // layout the scene.
        final StackPane layout = new StackPane();
        layout.getChildren().setAll(table);
        Scene scene = new Scene(layout);
        stage.setScene(scene);
        stage.show();
    }

    private Pair pair(String name, Object value) {
        return new Pair(name, value);
    }
}

class PairKeyFactory implements Callback {
    @Override
    public ObservableValue call(TableColumn.CellDataFeatures data) {
        return new ReadOnlyObjectWrapper(data.getValue().getKey());
    }
}

class PairValueFactory implements Callback {
    @SuppressWarnings("unchecked")
    @Override
    public ObservableValue call(TableColumn.CellDataFeatures data) {
        Object value = data.getValue().getValue();
        return (value instanceof ObservableValue)
                ? (ObservableValue) value
                : new ReadOnlyObjectWrapper(value);
    }
}

class PairValueCell extends TableCell {
    @Override
    protected void updateItem(Object item, boolean empty) {
        super.updateItem(item, empty);

        if (item != null) {
            if (item instanceof String) {
                setText((String) item);
                setGraphic(null);
            } else if (item instanceof Integer) {
                setText(Integer.toString((Integer) item));
                setGraphic(null);
            } else if (item instanceof Boolean) {
                CheckBox checkBox = new CheckBox();
                checkBox.setSelected((boolean) item);
                setGraphic(checkBox);
            } else if (item instanceof Image) {
                setText(null);
                ImageView imageView = new ImageView((Image) item);
                imageView.setFitWidth(100);
                imageView.setPreserveRatio(true);
                imageView.setSmooth(true);
                setGraphic(imageView);
            } else {
                setText("N/A");
                setGraphic(null);
            }
        } else {
            setText(null);
            setGraphic(null);
        }
    }
}
 jewelsea18 июл. 2016 г., 02:35
Пожалуйста, задайте как новый вопрос Эдди
 Petr KOKOREV12 июн. 2013 г., 22:28
Тот'Это то, что я, наконец, решил сделать, потратив немного больше времени на эту тему. Спасибо за этот ответ! Я не был уверен, еслиupdateItem» Метод был единственным, который можно переопределить, чтобы получить хороший результат, но на вашем примере он работает нормально
 Eddy17 июл. 2016 г., 17:58
Работает, но теперь ячейки только для чтения ... Есть идеи, как сделать их редактируемыми?

Ваш ответ на вопрос