Binding a hashmap to a table view (JavaFX)

I want to display the contents of a HashMap in a JavaFX Tableview . Below is the code that I used to set the contents of the HashMap to the columns of the table. The problem I am facing is that it only displays one line. The for loop iterates only 5 times: every time it picks up the first HashMap value.

If I ignore the return SimpleObjectProperty string return SimpleObjectProperty , the for loop return SimpleObjectProperty over the entire contents in the HashMap .

 final ObservableList<Map> data = FXCollections.observableArrayList(); data.addAll(HASHMAP); TableColumn<Map.Entry, String> nCol = new TableColumn<Map.Entry, String>("Name"); nCol.setEditable(true); nCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Entry, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Entry, String> p) { Set <String> set=HASHMAP.keySet(); for (String key:HASHMAP.keySet()) { String key1= key.toString(); return new SimpleObjectProperty<>(key.toString()); } return null; } }); Table.setItems(data); Table.getColumns().setAll(nCol,.........); 
+4
source share
2 answers
  • CellFactory.Callback.call() creates only one cell, not all cells in the loop
  • Using return from the loop interrupts the execution of the loop.

Take a look at the following example, especially the comments:

 public class MapTableView extends Application { @Override public void start(Stage stage) { // sample data Map<String, String> map = new HashMap<>(); map.put("one", "One"); map.put("two", "Two"); map.put("three", "Three"); // use fully detailed type for Map.Entry<String, String> TableColumn<Map.Entry<String, String>, String> column1 = new TableColumn<>("Key"); column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) { // this callback returns property for just one cell, you can't use a loop here // for first column we use key return new SimpleStringProperty(p.getValue().getKey()); } }); TableColumn<Map.Entry<String, String>, String> column2 = new TableColumn<>("Value"); column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<String, String>, String>, ObservableValue<String>>() { @Override public ObservableValue<String> call(TableColumn.CellDataFeatures<Map.Entry<String, String>, String> p) { // for second column we use value return new SimpleStringProperty(p.getValue().getValue()); } }); ObservableList<Map.Entry<String, String>> items = FXCollections.observableArrayList(map.entrySet()); final TableView<Map.Entry<String,String>> table = new TableView<>(items); table.getColumns().setAll(column1, column2); Scene scene = new Scene(table, 400, 400); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(); } } 
+9
source

Sergey Grinev; I found a solution, a general solution to this problem

 public class TableCassaController<K,V> extends TableView<Map.Entry<K,V>> implements Initializable { @FXML private TableColumn<K, V> column1; @FXML private TableColumn<K, V> column2; public TableCassaController(ObservableMap<K,V> map, String col1Name, String col2Name) { System.out.println("Costruttore table"); TableColumn<Map.Entry<K, V>, K> column1 = new TableColumn<>(col1Name); column1.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<K, V>, K>, ObservableValue<K>>() { @Override public ObservableValue<K> call(TableColumn.CellDataFeatures<Map.Entry<K, V>, K> p) { // this callback returns property for just one cell, you can't use a loop here // for first column we use key return new SimpleObjectProperty<K>(p.getValue().getKey()); } }); TableColumn<Map.Entry<K, V>, V> column2 = new TableColumn<>(col2Name); column2.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Map.Entry<K, V>, V>, ObservableValue<V>>() { @Override public ObservableValue<V> call(TableColumn.CellDataFeatures<Map.Entry<K, V>, V> p) { // for second column we use value return new SimpleObjectProperty<V>(p.getValue().getValue()); } }); ObservableList<Map.Entry<K, V>> items = FXCollections.observableArrayList(map.entrySet()); this.setItems(items); this.getColumns().setAll(column1, column2); } 

Thank you very much!!!: -)

0
source

Source: https://habr.com/ru/post/1500573/


All Articles