2013-06-12 37 views
20

Ich versuche die Tabellenansicht zu verwenden, um die "key = value" -Paare zu rendern/bearbeiten. So soll die Tabelle zwei Spalten haben: "Schlüssel" und "Wert". Der Schlüssel ist nur eine normale Zeichenfolge und der Wert kann alles sein. Mein Problem ist, dass der Datentyp der Werte von Zeile zu Zeile unterschiedlich sein kann. Grundsätzlich wollte ich Checkboxen für boolesche Werte und Auswahlmöglichkeiten für Listen verwenden. Ich habe einen Weg gefunden, die gesamte Tabelle Spalte mit Kontrollkästchen oder Auswahl, indem die Zellfabrik zu machen:JavaFX 2 TableView: Unterschiedliche Zellenfabrik, abhängig von den Daten in der Zelle

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

Aber ich brauche, was ist in der Lage sein, eine Bedingung einzufügen basierend auf der Art des Elements, das gehen wird innerhalb der Zelle gerendert werden. Mit anderen Worten, einige Zellenfabriken auf Zellenebene und nicht auf Spaltenebene. Und das bewertet meinen Zustand zur Renderzeit. Ich habe noch keine Lösung gefunden. Vielleicht hat jemand einige geeignete Techniken, um diese Art von Rendering zu implementieren? Vielleicht ein Drittanbieter-Datagrid?

Antwort

33

Hier ist eine Tabelle mit Paaren von Strings und Objekten verschiedener Typen.

Eine benutzerdefinierte Zellenfactory wird verwendet, um die Anzeige verschiedener Objekttypen zu behandeln (indem eine Prüfung des Objekttyps durchgeführt und der entsprechende Text oder die entsprechende Grafik gerendert wird).

pairtable

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

Das ist, was ich, nachdem er ein wenig mehr Zeit, um das Thema zu tun, schließlich gewählt. Danke für diese Antwort! Ich war nicht sicher, ob die "updateItem" -Methode die einzige war, die überschrieben wurde, um ein gutes Ergebnis zu erhalten, aber mit Ihrem Beispiel scheint es gut zu funktionieren –

+0

Funktioniert aber jetzt sind die Zellen nur lesbar ... jede Idee, wie man sie macht editierbar? – Eddy

+0

Bitte fragen Sie als neue Frage Eddy – jewelsea

Verwandte Themen