llenar data and javafx tableview cell factory

data - JavaFX 2 TableView: diferente fábrica de células en función de los datos dentro de la célula



tableview javafx (1)

Estoy intentando usar la vista de tabla para representar / editar los pares "clave = valor". Así que se supone que la tabla tiene dos columnas: "clave" y "valor". La clave es solo una cadena normal, y el valor puede ser cualquier cosa. Mi problema es que el tipo de datos de los valores puede ser diferente de una fila a otra. Básicamente, quería usar casillas de verificación para valores booleanos y opciones para listas. He encontrado una forma de representar toda la columna de la tabla con casillas de verificación u opciones configurando la fábrica de celdas:

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

Pero lo que necesito es poder insertar una condición según el tipo de elemento que se va a representar dentro de la celda. En otras palabras, alguna fábrica de células en el nivel de celda y no en el nivel de columna. Y eso evalúa mi condición en el tiempo de renderizado. Todavía no he encontrado ninguna solución a eso. Tal vez alguien tiene algunas técnicas adecuadas para implementar este tipo de representación? Tal vez algunos datos de terceros?


Aquí hay una tabla que muestra pares de cadenas y objetos de varios tipos.

Se utiliza una fábrica de celdas personalizada para controlar la visualización de diferentes tipos de objetos (mediante la realización de una instancia de comprobación del tipo de objeto y la representación del texto o gráfico apropiado).

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<Pair<String, Object>> table = new TableView<>(); public static void main(String[] args) throws Exception { launch(args); } public void start(final Stage stage) throws Exception { // model data ObservableList<Pair<String, Object>> 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<Pair<String, Object>, String> nameColumn = new TableColumn<>(NAME_COLUMN_NAME); nameColumn.setPrefWidth(100); TableColumn<Pair<String, Object>, Object> 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<TableColumn<Pair<String, Object>, Object>, TableCell<Pair<String, Object>, Object>>() { @Override public TableCell<Pair<String, Object>, Object> call(TableColumn<Pair<String, Object>, Object> 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<String, Object> pair(String name, Object value) { return new Pair<>(name, value); } } class PairKeyFactory implements Callback<TableColumn.CellDataFeatures<Pair<String, Object>, String>, ObservableValue<String>> { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Pair<String, Object>, String> data) { return new ReadOnlyObjectWrapper<>(data.getValue().getKey()); } } class PairValueFactory implements Callback<TableColumn.CellDataFeatures<Pair<String, Object>, Object>, ObservableValue<Object>> { @SuppressWarnings("unchecked") @Override public ObservableValue<Object> call(TableColumn.CellDataFeatures<Pair<String, Object>, Object> data) { Object value = data.getValue().getValue(); return (value instanceof ObservableValue) ? (ObservableValue) value : new ReadOnlyObjectWrapper<>(value); } } class PairValueCell extends TableCell<Pair<String, Object>, Object> { @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); } } }