# JavaFX - Array in View auslesen



## MattElg (23. Sep 2016)

Hallo,
ich habe in einer Model Class aus MySQL eine Tabelle in einResultSet ausgelesen. Dieses habe ich in einem Getter in ein Array gelesen und als return ausgegeben.
Diesen Getter, also das Array(String) möchte in der View Class auslesen und in einer Tabelle darstellen. Nun weiß ich nicht, wie ich dies mache. 
Hier der Getter der Model Klasse:


```
public String[][] getNamePwMap(String sqlstate){   
            try{
                Connection con ;
                con = DBConnect.connect();
                Statement stt1 = con.createStatement();
                stt1.execute("USE test");
                PreparedStatement prep = con.prepareStatement("Select "+ sqlstate);
                ResultSet rs = prep.executeQuery();
                rs.last();
                System.out.println("Anzahl Zeilen: "+rs.getRow() + " id "+rs.getString(1));
                int anzZeilen = rs.getRow();
                System.out.println(anzZeilen);
                rs.first();
                ResultSetMetaData rsmd = rs.getMetaData();
                tabelle = new String[anzZeilen+1][rsmd.getColumnCount()];
                System.out.println("Anzahl Sätze: "+rs.getRow());
                List<String> spaltenname = new ArrayList<String>();
                String[] spaltentyp = new String[rsmd.getColumnCount()];
                int[] spaltensize = new int[rsmd.getColumnCount()];
                for (int i = 0; i < rsmd.getColumnCount(); i++) {
                    spaltenname.add(rsmd.getColumnName(i+1));
                    tabelle[1][i] = rsmd.getColumnName(i+1);
                    spaltentyp[i] = (rsmd.getColumnTypeName(i+1));
                    spaltensize[i] = (rsmd.getColumnDisplaySize(i+1));
                }
                System.out.println("Die Spaltennamen heißen: " + spaltenname);
                int zeilen = 1;
                ObservableList<String> row = FXCollections.observableArrayList();
                String col = new String();
                while (rs.next()) {
                    for (int i = 0; i < rsmd.getColumnCount(); i++) {
                        col = rs.getString((i+1));
                        tabelle[zeilen][i] = rs.getString((i+1));
                        row.addAll(col);
                        System.out.println("Spalte "+i+" "+col);
                    }
                    System.out.println(row);
                    //row.addAll(col);
                   
                    zeilen ++;
                  }
                System.out.println(tabelle);
                stt1.close();
                con.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return tabelle;
        }
}
```

----
Ich würde es gern ohne ObservableList ausgeben. Sondern gleich über eine Schleife in ein TableView oder etwas anderes. Wenn jemand ein Beispiel hat, wie ich dies machen könnte wäre ich dankbar.


----------



## dennisbauer (24. Sep 2016)

Mal abgesehen davon, dass eine Methode möglichst wenig Code enthält, im größeren Stile gerne mal mit Kommentaren belegt sein dürfte, erkenne ich gerade nicht mal, was mit dieser Row überhaupt passiert. Da steht ein row.addAll(col); und das wars.

Wenn du Daten in eine TableView übergeben möchtest, kannst du entweder mithilfe von

```
tv.getItems().add(...)
```
einzelne Elemente übergeben oder eben mit

```
tv.setItems(FXCollections.observableList(deinArray))
```

Wenn du rein auf Array-Basis arbeiten möchtest, kannst du gleich ganze Arrays hinzufügen statt Objekte und in den  CellFactories einfach mit Zugriff auf die Arrayposition arbeiten.


----------



## MattElg (24. Sep 2016)

Danke Dir für Deine Antwort. Also wenn ich ein Table View 
Für den Controller dann: 

```
@SuppressWarnings("unchecked")
public void show(){
       sqlstate = ("id,fname from people;");
view.getTabelle().setItems(FXCollections.observableList((model.getNamePwMap(sqlstate))));
}
```

Und für den Viewer dann:

```
public String[][] getTabelle() {
        return tabelle;
    }
....
grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));
// Liste
        tabelle = new String[][];
        tabelle.toString()
grid.add(list, 0,1);
```


----------



## MattElg (24. Sep 2016)

Liege ich damit richtig richtig?
Oder bin ich da völlig falsch?


----------



## dennisbauer (24. Sep 2016)

Ausgehend davon, dass die getNamePwMap ein "Objekt" von Typ String[][] zurückgibt, mappt er mithilfe der ObservableList die Datensätze so um, dass der Typ deiner TableView String[] sein muss. Die CellFactories kannst du dann mit den jeweiligen Indizes belegen und die Werte rausziehen.

Der Ansatz sieht aber gut aus. Kleine Anmerkung habe ich aber: Wieso verwendest du für die GUI nicht den SceneBuilder, das geht viel einfacher von der Hand und zwingt einen schon nahezu zum Verwenden eines MVC-Modells. Dann ersparst du dir auch die 20 Zeilen für deine Gridpane oder Tableview


----------



## MattElg (24. Sep 2016)

Aha, dass ist das Problem, ich muss die TableView als String[][] definieren und dann diese so in einer Schleife befüllen. Muss ich probieren.
Den SceneBuilder kenne ich, der bietet aber nur XMLs an und da bin ich noch nicht so firm damit.


----------



## dennisbauer (24. Sep 2016)

Die FXMLs sind wesentlicher Bestandteil und werden über den FXMLLoader in Java geladen. Viel machen musst du da eigentlich nicht, außer die Annotations richtig zu setzen 

Die TableView musst du als String[] definieren, nicht als String[][], das wirst du aber sehen, dass es da Probleme damit gibt


----------



## MattElg (28. Sep 2016)

Ich habe die Controllerklasse so gestaltet und habe nun die Überschriften der Tabelle sichtbar gemacht. Direkt über den Array aus dem SQL Statement.
Was immer noch nicht klappt ist die Befüllung der einzelnen Zeilen der Tabelle. 
Also das mit "setCellValueFactory(new Callback<CellDataFeatures" funktioniert da nicht mehr.
Ich möchte die einzelnen Zeilen befüllen, denn es sind ja mehrere Spalten, deren Anzahl ich ja nicht kenne, da der SQL Code flexibel sein soll.

Controllerklasse:


```
package ausgabe;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TableColumn;
import model.DataBean6;
import eingabe.EingabeVC6;
import java.util.Arrays;

import ausgabe.AusgabeVC6.backBtnEventHandler;


public class Ausgabe {
    private DataBean6 dataBean;
    private AusgabeView6 view;
    private String sqlstate;
    //private ObservableList data;
    private ObservableList<String[]> data;
    private String[][] tabelle;
   
    public void AusgabeVC6(DataBean6 dataBean) {
        this.dataBean = dataBean;
        this.view = new AusgabeView6();
        // Eventhandler registrieren
        view.getBackBtn().setOnAction(new backBtnEventHandler());   
    }

    @SuppressWarnings("unchecked")
    public void show(){
       
        // View mit Daten befuellen
        //vertikal
        sqlstate = ("* from people;");
        tabelle = dataBean.getTabelle(sqlstate);       
       
    TableColumn[] tableColumns = new TableColumn[tabelle[0].length];
       
    for (int a = 0; a < tabelle[0].length; a++) {
        tableColumns[a] = new TableColumn(tabelle[0][a]);
        final int index = a ;
       
    }
    view.getTable().getColumns().addAll(tableColumns);
    System.out.println("Spaltenname: "+tableColumns[1]);
    //int zeile = 1 - da zeile 0 die Spaltennamen waren
    for (int zeile = 1; zeile < tabelle.length; zeile++) {
        for (int a = 0; a < tabelle[0].length; a++) {
            view.getTable().setCellValueFactory(new Callback<CellDataFeatures<String[], (tabelle[zeile][a])>>);
        }
    }
    i++;   
        view.show(dataBean.getPrimaryStage());
    }
   
    //+++++++++++++++++++++++++++++++++++++++++++++
    // Events
    //+++++++++++++++++++++++++++++++++++++++++++++

   
    class backBtnEventHandler implements EventHandler<ActionEvent>{

        @Override
        public void handle(ActionEvent e) {   
            // zur naechsten Seiten springen!
            EingabeVC6 eingabeVC = new EingabeVC6(dataBean);
            eingabeVC.show();  
        }
    }
}
```

Die View Klasse:

```
package ausgabe;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TableView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
* @author Matt
*
*/
public class AusgabeView6{
   
    private Scene scene;
   
    private GridPane grid;
    private Text scenetitle;
    //private ListView<String> list;   
    //private String[][] tabelle;
    //private TableView<String> list;   
    private TableView table;
   
    private Button backBtn;
    private HBox hbBtn;
   
    public AusgabeView6() {
        // Layout
        grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25, 25, 25, 25));

        // Ueberschrift
        scenetitle = new Text("Hallo");
        scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
        grid.add(scenetitle, 0, 0, 2, 1);

        // Tabelle
       table = new TableView();
        table.setEditable(true);
        table.setMinWidth(600);
        grid.add(table, 0,1);
      
       
        /*funktioniert
        list = new ListView<>();
        //list = new TableView<>();
        list.setMinWidth(200);
        grid.add(list, 0,1);
        */
        // Button
        backBtn = new Button("zurück");

        // Buttongruppe
        hbBtn = new HBox(10);
        hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
        hbBtn.getChildren().add(backBtn);
        grid.add(hbBtn, 0, 2);

        scene = new Scene(grid, 300, 300);
    }

    public void show(Stage stage) {
        stage.setTitle("AxxG - JavaFX MVC Beispiel");
        stage.setScene(scene);
        stage.show();
    }

   public TableView getTable(){
        return table;
    }

    public Button getBackBtn() {
        return backBtn;
    }
}
```


----------



## MattElg (28. Sep 2016)

Hallo, ich sehe Deine Klasse. Ähnliches habe ich auch vor. Eine MySQL Tabelle in ein Array lesen. Habe ich, wobei die Zeile 0 dieses Array die Spaltennamen sind.
Dieses dann direkt in ein TableView.
Nun habe ich die Spaltennamen definiert. Dies klappt auch. 
Aber ich muss noch der TableView Werte zuweisen, also alles ab Zeile 1 meines Arrays, den entsprechenden Spalten. 
Das klappt nicht. Also das was Du angemahnt hast, die Wert der TableView zuweisen. Dies von dem Array.
Derzeit bekomme ich nur eine Tabelle mit Überschriften und ohne Inhalt angezeigt.


----------



## dennisbauer (29. Sep 2016)

Du hast einen Datensatz der aus String[][] besteht, also einem multidimensionalem Array. Wenn du das nun in der Tabelle Abbilden möchtest, killst du ja automatisch eine Dimension weg, die für die Zeilen stehen, sprich jede Zeile besteht aus einer Dimension, ergo einem String[].

Die TableView definierst du als generischen Typ genaudeswegen auch mit einem String[] als Datentyp, da die Zeilen ja automatisch schon mit drinstecken.

Probier das einmal aus und poste dann die Fehler die sich ergeben. Eigentlich sollte es nur in deiner IDE eine Fehlermeldung geben, dass du da falsche Typen zuweist, was nicht schlimm wäre, denn die TableView hätten wir korrekt definiert und der Fehler muss irgendwo im Code liegen.

Die Werte weist du der TableView immernoch mit tv.getItems().addAll(...); zu, wobei du hier glaube auf die FXCollections.observableArraylist zugreifen musst, damit das addAll funktioniert


----------



## MattElg (29. Sep 2016)

```
for (int a = 0; a < tabelle[0].length; a++) {
                tableColumns[a] = new TableColumn(tabelle[0][a]);
                tableColumns[a].setCellValueFactory(new PropertyValueFactory<String, String>(tabelle[0][a]));
                final int index = a ; // I think, don't really understand what you're doing with indexes...
            }
view.getTable().getColumns().addAll(tableColumns);
       for (int row = 1; row < tabelle.length; row++) {
         for (int a = 0; a < tabelle[0].length; a++) {
           view.getTable().getItems().add(tabelle[row][a]);
         }
       }
```

Das klappt, meldet auch keine Fehler, aber wie Du schriebst, habe ich ja zwei Dimmensionen, eine für Spalten, eine für Zeilen in dem Array. Die angezeigte Tabelle hat also Spaltennamen, aber keinen Inhalt. 
Ich dachte, dieser TableView kann ich jedes einzelne Feld so zuweisen über das: 
view.getTable().getItems().add(tabelle[row][a]);
Fehler melder er keine. Aber die Tabelle bleibt leer. Ich habe ja keine ObservableArrayList. Diese will ich ja umgehen.


----------



## dennisbauer (29. Sep 2016)

Hey,

du hast in deinem Code die TableView mit dem generischen Datentyp "String" deklariert. Das ist natürlich falsch, da du ja mehrere Elemente in einem String-Array* pro Zeile *hinzufügen möchtest.

Als Datentyp sollte eigtl. TableView<String[]> da stehen und weiter unten solltest du nicht einen String als Item übergeben, sondern ein String-Array.

Innerhalb der CellValueFactory kannst du dann aus dem übergebenen Row-Objekt auf den Inhalt zugreifen bzw. auf eine feste Spalte in deinem Array.


----------



## MattElg (12. Okt 2016)

Ich bin noch meine Lösung schuldig. Also hier zum Nachtrag. Ich habe 7 Klassen, je 2 für Eingabe und Ausgabe, eines für die Konnektion zu MySQL, eines zur Datenbanknachfrage bzw. Speicherung neuer Eingabe in SQL und eine Starter-Klasse.
Starterklasse:

```
package main;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import eingabe.EingabeVC8;
import model.DataBean8;

/**
* @author Matthias Elger
*/
public class Start8 extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        try{
            // Sessionscope /Applikationscope Beans inizitalisieren!
            // muessen von Controllern weitergegeben werden
            DataBean8 dataBean = new DataBean8(primaryStage);
   
        // Ersten Controller aufrufen
        EingabeVC8 eingabeVC = new EingabeVC8(dataBean);
        eingabeVC.show();  
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
       
}
```

Das View für die Eingabe:

```
package eingabe;

import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * @author Matthias Elger
 */
public class EingabeView8{
   
   private Scene scene;
   
   private GridPane grid;
   private Text scenetitle;
   
   private Label vornameLB;
   private TextField vornameTF;
   
   private Label nachnameLB;
   private TextField nachnameTF;
   
   private Text meldungT;
   
   private Button okBtn;
   private Button addBtn;
   private HBox hbBtn;
   
   public EingabeView8() {
     // Layout
     grid = new GridPane();
     grid.setAlignment(Pos.CENTER);
     grid.setHgap(10);
     grid.setVgap(10);
     grid.setPadding(new Insets(25, 25, 25, 25));

     // Ueberschrift
     scenetitle = new Text("Hallo!");
     scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
     grid.add(scenetitle, 0, 0, 2, 1);

     // Vorname
     vornameLB = new Label("Vorname:");
     grid.add(vornameLB, 0, 1);

     vornameTF = new TextField();
     grid.add(vornameTF, 1, 1);
     
     // Nachname
     nachnameLB = new Label("Nachname:");
     grid.add(nachnameLB, 0, 2);

     nachnameTF = new TextField();
     grid.add(nachnameTF, 1, 2);

     // Buttons
     addBtn = new Button("eintragen");
     okBtn = new Button("Alle anzeigen");

     // Buttongruppe
     hbBtn = new HBox(10);
     hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
     hbBtn.getChildren().add(addBtn);
     hbBtn.getChildren().add(okBtn);
     grid.add(hbBtn, 1, 4);

     // Meldung
     meldungT = new Text();
     grid.add(meldungT, 1, 6);

     scene = new Scene(grid, 300, 300);
   }

   public void show(Stage stage) {
     stage.setTitle("JavaFX MVC Beispiel");
     stage.setScene(scene);
     stage.show();
   }


   // nur Getter von Elementen anlegen, die veraendert werden und/oder dynamisch sind
   public TextField getVornameTF() {
     return vornameTF;
   }


   public TextField getNachnameTF() {
     return nachnameTF;
   }


   public Text getMeldungT() {
     return meldungT;
   }

   public Button getOkBtn() {
     return okBtn;
   }


   public Button getAddBtn() {
     return addBtn;
   }


}
```
Der Controller für die Eingabe:

```
package eingabe;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import model.DataBean8;
import ausgabe.AusgabeVC8;

/**
 * Steuert alle Interaktionen der Eingabe-Maske
 * Verbindet die View mit dem Model
 *
 * @author Matthias
 */
public class EingabeVC8 {
   
   // Model
   private DataBean8 dataBean;
   
   // View
   private EingabeView8 view;
   
   
   public EingabeVC8(DataBean8 dataBean) {
     this.dataBean = dataBean;
     this.view = new EingabeView8();
     
     // Eventhandler registrieren
     view.getAddBtn().setOnAction(new addBtnEventHandler());   
     view.getOkBtn().setOnAction(new OkBtnEventHandler());   
   }
   
   // Start2
   public void show(){
     view.show(dataBean.getPrimaryStage());
   }
   
   //+++++++++++++++++++++++++++++++++++++++++++++
   // Events
   //+++++++++++++++++++++++++++++++++++++++++++++

   
   class OkBtnEventHandler implements EventHandler<ActionEvent>{

     @Override
     public void handle(ActionEvent e) {   
       // zur naechsten Seiten springen!
       AusgabeVC8 ausgabeVC = new AusgabeVC8(dataBean);
       ausgabeVC.show();   
     }
     
   }
   
   class addBtnEventHandler implements EventHandler<ActionEvent>{

     @Override
     public void handle(ActionEvent e) {   
       // Meldung reseten
       view.getMeldungT().setText("");
       
       // Daten aus den Textfeldern holen
       String vname = view.getVornameTF().getText();
      String nname = view.getNachnameTF().getText();
       
       //Textfelder zuruecksetzen
       view.getNachnameTF().setText("");
       view.getVornameTF().setText("");
       
       // Daten testen
       if(vname.isEmpty()){
         view.getMeldungT().setText("Der Vorname fehlt!");
         return;
       }
       if(nname.isEmpty()){
         view.getMeldungT().setText("Der Nachname fehlt!");
         return;
       }
       
       // Daten hinzufuegen  - setter aufgerufen aus Databean
       dataBean.setNamePwMap(vname, nname);
       
       // Meldung ausgeben
       if(vname == null && nname == null){
         view.getMeldungT().setText("Leser bereits vorhanden");
       }else{
         view.getMeldungT().setText("Folgenden Leser hinzugefügt: " + vname + " " +nname);
       }
     }
  }
}
```
Die View für die Ausgabe:

```
package ausgabe;

import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TableView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

/**
 * @author Matthias Elger
 */
public class AusgabeView8{
   
   private Scene scene;
   
   private GridPane grid;
   private Text scenetitle;
   TableView<String[]> table;
   private Button backBtn;
   private HBox hbBtn;
   
   public AusgabeView8() {
     // Layout
     grid = new GridPane();
     grid.setAlignment(Pos.CENTER);
     grid.setHgap(10);
     grid.setVgap(10);
     grid.setPadding(new Insets(25, 25, 25, 25));

     // Ueberschrift
     scenetitle = new Text("Leser Übersicht");
     scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
     grid.add(scenetitle, 0, 0, 2, 1);

     // Liste
     table = new  TableView<String[]>();
     table.setEditable(true);
     table.setMinWidth(100);
     grid.add(table,1, 0, 2, 2);
       
     /*funktioniert auch
     list = new ListView<>();
     //list = new TableView<>();
     list.setMinWidth(200);
     grid.add(list, 0,1);
     */
     // Button
     backBtn = new Button("zurück");

     // Buttongruppe
     hbBtn = new HBox(10);
     hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
     hbBtn.getChildren().add(backBtn);
     grid.add(hbBtn, 0, 2);

     scene = new Scene(grid, 300, 300);
   }

   public void show(Stage stage) {
     stage.setTitle("JavaFX MVC Beispiel");
     stage.setScene(scene);
     stage.show();
   }

   /*public ListView<String> getList() {
     return list;
   }*/
   public TableView getTable(){
     return table;
   }

   public Button getBackBtn() {
     return backBtn;
   }
}
```
Der Controller für die Ausgabe:

```
package ausgabe;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TableColumn;
import javafx.util.Callback;
import javafx.scene.control.TableColumn.CellDataFeatures;
import model.DataBean8;
import eingabe.EingabeVC8;
import java.util.Arrays;

/**
 * Steuert alle Interaktionen der Ausgabe-Maske
 * Verbindet die View mit dem Model
 * @author Matthias Elger
 */
public class AusgabeVC8 {
   
   private DataBean8 dataBean;
   private AusgabeView8 view;
   private String sqlstate;
   ObservableList<String[]> data = FXCollections.observableArrayList();
   private String[][] tabelle;
   public AusgabeVC8(DataBean8 dataBean) {
     this.dataBean = dataBean;
     this.view = new AusgabeView8();
     view.getBackBtn().setOnAction(new backBtnEventHandler());   
   }
   
   /**
    * als ein Array aus SQL Tabelle mit getTabelle holen, dabei als Parameter den SQL Code, alles außer Select übergeben,
    * also * from Tabellenname oder name, vname from table where...
    * dies dann in einem TableView aus AusgabeView darstellen, das aufgerufen wirdm inkl. Button,...
    */
   @SuppressWarnings("unchecked")
   public void show(){   
     // View mit Daten befuellen
       sqlstate = ("* from people;");
       //an Array übergeben
       tabelle = dataBean.getTabelle(sqlstate);
       int rowLength = (tabelle.length);
       System.out.println("Zeilen Ausgabe"+rowLength);
       //spalten - ich muss oben bei remove von ArrayList die letzte Zeile entfernen, nicht die erste, die fehlt nämlich
    for(int i=0 ; i<tabelle[0].length; i++) {
       TableColumn col = new TableColumn(tabelle[rowLength-3][i]);
    final int colNo = i;
    col.setCellValueFactory(new Callback<CellDataFeatures<String[], String>, ObservableValue<String>>() {
    @Override
    public ObservableValue<String> call(CellDataFeatures<String[], String> p) {
    return new SimpleStringProperty((p.getValue()[colNo]));
    }
    });
    col.setPrefWidth(90);
    view.getTable().getColumns().add(col);
    //Megadaten auf null setzen
    tabelle[rowLength-3][i] = null; //Spaltennamen aus Array löschen
    tabelle[rowLength-2][i] = null;   // Typ aus Array löschen
    tabelle[rowLength-1][i] = null;   // Spaltenlänge aus Array löschen
    }
    //http://stackoverflow.com/questions/20769723/populate-tableview-with-two-dimensional-array/20774549
       
       System.out.println(view.getTable().getColumns().toString());
       view.getTable().setMinWidth(100);
       view.getTable();
       data.addAll(Arrays.asList(tabelle));
       System.out.println(data);
       view.getTable().getItems().addAll(data);
     //Doppelklick erkennen - später wichtig:
     //http://javawiki.sowas.com/doku.php?id=javafx:tableview-doubleclick-row
     
     /**
      *  View anzeigen
      */
     view.show(dataBean.getPrimaryStage());
   }
   
   //+++++++++++++++++++++++++++++++++++++++++++++
   // Events
   //+++++++++++++++++++++++++++++++++++++++++++++

   /**
    * Button zurück zur Eingabe springen
    */
   class backBtnEventHandler implements EventHandler<ActionEvent>{

     @Override
     public void handle(ActionEvent e) {   
       // zur naechsten Seiten springen!
       EingabeVC8 eingabeVC = new EingabeVC8(dataBean);
       eingabeVC.show();   
     }
     
   }
}
```
Die SQL Model - Klasse

```
package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.ArrayList;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.stage.Stage;
import main.DBConnect;

/**
 * Daten, die innerhalb der Anwendung gebraucht werden, werden in Beans gespeichert.
 * Diese Klassen speichern nur Werte und haben keine andere Aufgabe!
 *
 * @author Matthias Elger
 */
public class DataBean8 {
   
     //private List<String> columns = new ArrayList<String>();
     private String[][] tabelle;
     private Stage primaryStage = null;
     private ObservableList<String> data;
     
   public DataBean8(Stage primaryStage)  {
     this.primaryStage = primaryStage;
     }
   /**
    * ermöglicht Eingabe von Werten
    */
   public void setNamePwMap(String vname, String nname) {   
     try{
       Connection con ;
       con = DBConnect.connect();
       Statement stt1 = con.createStatement();
       stt1.execute("USE test");
       String insert = ("INSERT INTO people (fname, lname) VALUES ('" + vname + "', '" + nname +"')");
       Statement stt2 = con.createStatement();
       stt2.execute(insert);           
     }
     catch (Exception e)
    {
    e.printStackTrace();
    }
   }
   
   /**
    * ermöglicht Ausgabe von SQL Tabelle, je nach SQL Anweisung, die übergeben wird
    * Ausggeben wird ein zweidimmensionales Array
    */
   public String[][] getTabelle(String sqlstate) {   
     try{
       Connection con ;
       con = DBConnect.connect();
       Statement stt1 = con.createStatement();
       stt1.execute("USE test");
       //String insert = ("Select * from people;");
       PreparedStatement prep = con.prepareStatement("Select "+ sqlstate);
    ResultSet rs = prep.executeQuery();
    //springt zur letzten Zeile im Resultset, gibt dann die Position aus,
    rs.last();
    int anzZeilen = rs.getRow();
    System.out.println(anzZeilen);
       ResultSetMetaData rsmd = rs.getMetaData();
       tabelle = new String[anzZeilen+3][rsmd.getColumnCount()];
       System.out.println("Anzahl Sätze: "+rs.getRow());
       int zeilen = 0;
       ObservableList<String> row = FXCollections.observableArrayList();
       String col = new String();
       rs.first();
       do {
  for (int i = 0; i < rsmd.getColumnCount(); i++) {
     col = rs.getString((i+1));
     tabelle[zeilen][i] = rs.getString((i+1));
     row.add(col);
  }
  zeilen ++;
  } while (rs.next());
       
       /**
        * hängt als vorvorletzte Zeile im Array die Spaltennamen mit
        * und als vorletzte Zeile den Typ, als letzte die Größe
        */
  for (int i = 0; i < rsmd.getColumnCount(); i++) {
         tabelle[anzZeilen][i] = rsmd.getColumnName(i+1);
         tabelle[anzZeilen+1][i] = rsmd.getColumnTypeName(i+1);
         //tabelle[anzZeilen+2][i]    = (rsmd.getCatalogName(i+1));
         int spaltensize = rsmd.getColumnDisplaySize(i+1);
         tabelle[anzZeilen+2][i] = toString().valueOf(spaltensize);
       }
       stt1.close();
    con.close();
     }
     catch (Exception e)
    {
    e.printStackTrace();
    }
     return tabelle;
   }
   
   public Stage getPrimaryStage() {
     return primaryStage;
   }
}
```
Der SQL Connectionklasse:

```
package main;

import java.sql.Connection;

   import java.sql.DriverManager;
   import java.sql.SQLException;

   /**
    * @author Matthias
    */

   public class DBConnect {

    private static Connection conn;
    /**
  * 3306 is the default port for MySQL in XAMPP. Note both the
  * MySQL server and Apache must be running.
  */
    private static String url = "jdbc:mysql://localhost:3306/";
     
    /**
  * The MySQL user.
  */
    private static String user = "root";
     
    /**
  * Password for the above MySQL user. If no password has been
  * set (as is the default for the root user in XAMPP's MySQL),
  * an empty string can be used.
  */
    private static String pass = "";

    public static Connection connect() throws SQLException{
    try{
       Class.forName("com.mysql.jdbc.Driver").newInstance();
    }catch(ClassNotFoundException cnfe){
    System.err.println("Error: "+cnfe.getMessage());
    }catch(InstantiationException ie){
    System.err.println("Error: "+ie.getMessage());
    }catch(IllegalAccessException iae){
    System.err.println("Error: "+iae.getMessage());
    }

    conn = DriverManager.getConnection(url,user,pass);
    return conn;

    }

    public static Connection getConnection() throws SQLException, ClassNotFoundException{

    if(conn !=null && !conn.isClosed())

    return conn;
    connect();
    return conn;
    }
   }
```


----------

