JavaFX Tabelle mit Daten füllen

Bitte aktiviere JavaScript!
Moin, ich arbeite momentan an einem kleinen Datenbankexplorer.
Hierzu habe ich ne Oberfläche mit JavaFX erstellt. Ein Teil dieser Oberfläche ist nun eine Tabelle. Hierzu hab ich nen TableView, die eine Tabellenspalte enthält um die Namen der Tabellen der Datenbank aufzulisten und anklickbar zu machen, erstellt..
Es soll halt erstmal da ne Auflistung von allen Datentabellen die auf der Datenbank initialisert sind stattfinden. Die sollen anklickbar sein, sodass ich wenn ich eine Tabelle anklicke die Daten der ausgewählten Datentabelle bekomme..
Ist so ne Tabelle da überhaupt die richtige Wahl oder sollte ich eine andere Wahl nehmen? Eine Choicebox wäre sicherlich einfacher, allerdings würde ich gerne die Namen der vorhandenen Tabellen der Datenbank dauerhaft angezeigt bekommen in ner Auflistung.

Für das Hinzufügen der Daten nutze ich folgende Methode:

Java:
private void setTables()
    {
        for(int i=0; i<5; i++)
        {
            ArrayList<String> tables = phoenixStudio.getTables();
            if(tables == null)
            {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
           if(tables == null)
            {
              tableNames.setCellValueFactory(new PropertyValueFactory<>("TabellenNamen"));
               for(String string : tables)
               {
                   System.out.println(string);
               }
               tbData.setItems(FXCollections.observableArrayList(tables));
               tbData.getColumns().setAll(tableNames);
               return;
            }
        }
    }
Hier einmal kurz was die Variablen genau für Objekte sind:

Code:
@FXML
private TableColumn<String, String> tableNames;

@FXML
private TableView<String> tbData;
PhoenixStudio ist mehr oder weniger das Hauptprogramm, welches die diversen DatenbankConnectors verwaltet, also die Befehlsanfragen an die Datenbank schickt.
Mein Problem ist nun allerdings, dass trotz dem Aufrufen des Einfügens der Daten keine Daten hinzugefügt werden.
Der einzige Unterschied, der sich bemerkbar macht, ist, dass, nicht mehr wie zuvor, "No Content in Table" zu lesen ist, sondern die Tabelle mit leeren Spalten/Zeilen befüllt ist. Die Arraylist die ich allerdings einfüge, beinhaltet alle korrekten Namen der Datenbanktabellen.

Hat jemand ne Idee wie ich das Problem gelöst kriege?
 
A

Anzeige




Vielleicht hilft dir unser Kurs hier weiter —> (hier klicken)
Wenn du eh nur eine Spalte hast - nimm doch lieber eine ListView. Mal grob skizziert:
Java:
public class FooController implements Initializable {
    @FXML
    private ListView<String> tableNames;
  
     @Override
     public void initialize(URL location, ResourceBundle resources) {
          tableNames.setOrientation(Orientation.HORIZONTAL); // wenn nicht schon im FXML festgelegt
          tableNames.setItems(FXCollections.observableArrayList(phoenixStudio.getTables()));
          tableNames.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
              // listview selection changed ... display some data here
          });
     }
}
 
Vielen Dank für deine Antwort. So funktioniert das tatsächlich :)
Wenn ich jetzt vom ChangeListener ausgehe: Ich klicke eine Zeile an und erhalte als String den Tabellennamen.

Die TableView erhalte ich durch folgendes, oder?
Java:
@FXML
private TableView<TableColumn<String, String>> databaseData;
Ist das so korrekt initialisiert?
Die Tabelle der Datenbank erhalte ich als zwei-dimensionales String Array:
Java:
 String[][] tableData = phoenixStudio.getWholeTable(ipTextField.getText(), databaseTextField.getText(), newValue).getData();
Da die Anzahl der Spalten bei der Tabelle einer Datenbank immer gleich sein wird kann ich auch die Spaltenanzahl ermitteln..
Doch wie befülle ich die Tabellenspalte nun mit ihrem Inhalt? Mein Code sieht dazu momentan folgender Maßen aus:
Java:
 QuerryResult querryResult = phoenixStudio.getWholeTable(ipTextField.getText(), databaseTextField.getText(), newValue);
            String[][] tableData = querryResult.getData();
            //Spalten in Tabelle erzeugen
            for(int i=0; i<querryResult.getColumnCount()- databaseData.getColumns().size(); i++)
            {
               databaseData.getColumns().add(new TableColumn<>(querryResult.getColumnNames()[i]));
            }

            //Spalten der Tabelle mit Daten füllen:
            for(int i=0; i<querryResult.getColumnCount(); i++)
            {
                databaseData.getColumns().get(i)
            }
Ist das so überhaupt der richtige Weg über die einzelnen Felder der Tabelle zu gehen?
 
Ich habe nun die gesamte Methode des ChangeListeners überarbeitet und habe endlich rausgefunden wie ich Inhalte der Tabelle hinzufüge. Jetzt habe ich nur noch das Problem, dass ich nur die TabellenSpalten der mittleren Tabelle bekomme. Die restlichen werden nicht angezeigt. Nen weiteres Problem ist auch, dass die Spalten jedes Mal wenn der ChangeListener anschlägt hinzugefügt werden..
Mein gesamter ChangeListener sieht momentan wie folgt aus:

Java:
 private void tableListChangeListener()
    {
        tablesList.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {

            QuerryResult querryResult = phoenixStudio.getWholeTable(ipTextField.getText(), databaseTextField.getText(), newValue);
            ObservableList<ObservableList> data = FXCollections.observableArrayList();
            if(querryResult != null)
            {
                databaseData.getItems().clear();
                String[][] tableData = querryResult.getData();
               //Spalten erzeugem
                for(int i=0; i<querryResult.getColumnCount(); i++)
                {
                    TableColumn col = new TableColumn(querryResult.getColumnNames()[i]);
                    final int j = i;
                    col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){
                        public ObservableValue<String> call(TableColumn.CellDataFeatures<ObservableList, String> param) {
                            return new SimpleStringProperty(param.getValue().get(j).toString());
                        }
                    });
                    databaseData.getColumns().addAll(col);
                }

                //Tabellendaten einfügen
                for(int i=0; i<tableData.length; i++)
                {
                    ObservableList<String> row = FXCollections.observableArrayList();
                    for(int j=0; j<querryResult.getColumnCount(); j++)
                    {
                        row.add(tableData[i][j]);
                    }
                    data.add(row);
                }
                databaseData.setItems(data);
            }
        });
    }
Hat jemand ne Idee wo der Fehler sein könnte bzgl. von anderen Tabellen? Oder kann es vl damit zusammenhängen, dass kein Inhalt in der TableView angezeigt wird, wenn keine Daten in der Tabelle vorhanden sind?
 
Ehrlich gesagt würde ich das etwas anders angehen.
Nen weiteres Problem ist auch, dass die Spalten jedes Mal wenn der ChangeListener anschlägt hinzugefügt werden..
Weil du die Items der Tabelle leerst, nicht aber die Spalten. databaseData.getItems().clear(); --> databaseData.getColumns().clear();
etzt habe ich nur noch das Problem, dass ich nur die TabellenSpalten der mittleren Tabelle bekomme.
Was für eine mittlere Tabelle?

Hab das gerade selber mal gebastelt.. vielleicht kannst du ja was mit anfangen
Java:
public class DatabaseTable {
    private String name;
    private ObservableList<TableColumn> columns;
    private int rowCount;

    public DatabaseTable( String name, int rowCount ) {
        this.name = name;
        this.columns = FXCollections.observableArrayList();
        this.rowCount = rowCount;
    }

    public void addColumn(String name, ObservableList<String> values) {
        columns.add(new TableColumn(name, values));
    }

    public String getName() {
        return name;
    }

    public ObservableList<TableColumn> getColumns() {
        return columns;
    }

    public ObservableList<String> getRow(int i) {
        return columns.stream().map(e -> e.getValueAt(i)).collect(Collectors.toCollection(FXCollections::observableArrayList));
    }

    public int getRowCount() {
        return rowCount;
    }

    class TableColumn {
        private String heading;
        private ObservableList<String> values;

        public TableColumn(String heading, ObservableList<String> values) {
            this.heading = heading;
            this.values = values;
        }

        public String getHeading() {
            return heading;
        }

        public String getValueAt(int i) {
            return values.get(i);
        }
    }
}
Java:
public class Main extends Application {

    private ListView<DatabaseTable> tableNameView;
    private TableView<ObservableList<String>> tableView;


    @Override
    public void start( Stage primaryStage ) throws Exception {

        ObservableList<DatabaseTable> tables = loadDummyTables();

        tableView = new TableView<>();
        tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        tableNameView = new ListView<>(tables);
        tableNameView.setCellFactory(param -> new ListCell<>() {
            @Override
            protected void updateItem( DatabaseTable item, boolean empty ) {
                super.updateItem(item, empty);
                if(!empty) {
                    setText(item.getName());
                }
            }
        });
        tableNameView.getSelectionModel().selectedItemProperty().addListener(( observable, oldValue, newValue ) -> updateTableView(newValue));

        HBox root = new HBox();
        root.getChildren().addAll(tableNameView, tableView);

        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("ListView TableView Test");
        primaryStage.show();

    }

    private void updateTableView( DatabaseTable table ) {
        if(table != null) {
            tableView.getColumns().clear();

            var columns = table.getColumns();
            for(int i = 0; i < columns.size(); i++) {
                TableColumn<ObservableList<String>, String> column = new TableColumn<>(columns.get(i).getHeading());
                final int index = i;
                column.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().get(index)));
                tableView.getColumns().add(column);
            }

            tableView.setItems(IntStream.range(0, table.getRowCount()).boxed().map(table::getRow).collect(Collectors.toCollection(FXCollections::observableArrayList)));
        }
    }

    private ObservableList<DatabaseTable> loadDummyTables() {
        return FXCollections.observableArrayList(
                loadDummyTable("DummyTable One", new String[]{ "Col1", "Col2", "Col3" }, new String[][]{
                        { "Value1.1", "Value1.2", "Value1.3" },
                        { "Value 2.1", "Value2.2", "Value 2.3" },
                        { "Value 3.1", "Value3.2", "Value 3.3" } }),
                loadDummyTable("Dummy Table Two", new String[]{"Col1", "Col2"}, new String[][] {
                        {"Value 0.0", "Value 0.1"},
                        { "Value 1.0", "Value 1.1"}
                }),
                loadDummyTable("Emtpty table", new String[]{"Col1", "Col2", "Col3"}, new String[][]{}));
    }

    private DatabaseTable loadDummyTable( String tableName, String[] columnName, String[][] values ) {

        DatabaseTable table = new DatabaseTable(tableName, values.length);

        for ( int i = 0; i < columnName.length; i++ ) {
            ObservableList<String> columnValues = FXCollections.observableArrayList();
            for ( String[] value : values ) {
                columnValues.add(value[ i ]);
            }
            table.addColumn(columnName[ i ], columnValues);
        }

        return table;
    }
}
 
Was für eine mittlere Tabelle?
Ich habe momentan auf der Beispieldatenbank 3 Tabellen. Davon beinhaltet nur eine Tabelle auch Daten. Die anderen beiden Tabellen sind leer. Die TableView wird halt nur bei der Tabelle aktualisiert wenn ich die Tabelle anzeigen lasse, die Daten beinhaltet, ich vermute mal dass ich mit dere Anzahl der Tabellenspalten arbeite, die könnte aber evtl 0 betragen, wenn keine Daten vorhanden sind, wodurch der Code zum hinzufügen von Spalten nicht ausgeführt wird.


Java:
private ObservableList<TableColumn> columns;
Was für eine TableColumn ist das? ist das eine selbsterstellte Klasse oder verwendest du hier die TableCollumn von JavaFX?
Wenn ich die TableCollumn von JavaFX verwende, habe ich ein Problem beim hinzufügen einer Spalte:

Code:
public void addColumn(String name, ObservableList<String> values)
{
   columns.add(new TableColumn(name, values));
}
Hier bekomme ich von IntelliJ die Fehlermeldung, dass der Konstruktor String, ObserveableList<String> nicht definiert wäre...
Nehme ich eine eigene Klasse (hab die mal Tabellenspalte genannt damit man nicht so viele Namensdopplungen hat) ist die Methode
Java:
public ObservableList<String> getRow(int i)
{
   return columns.stream().map(e -> e.getValueAt(i)).collect(Collectors.toCollection(FXCollections::observableArrayList));
}
nicht verfügbar, weil die Klasse Tabellenspalte die Methode nicht beinhaltet. Die Tabellenspalte sieht derzeit wie folgt aus:

Java:
package network.databases.database;

import javafx.collections.ObservableList;

public class Tabellenspalte
{
    private String name;
    private ObservableList<String> values;

    public Tabellenspalte(String name, ObservableList<String> values)
    {
        this.name = name;
        this.values = values;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ObservableList<String> getValues() {
        return values;
    }

    public void setValues(ObservableList<String> values) {
        this.values = values;
    }
}
Frage ist halt: Welche TableCollumn hast du in deinem Beispiel verwendet?
Nehme ich die von JavaFX kann ich die getRow-Abfrage auch nicht ausführen, da er die Methode nicht kennt.
 
Hallo, vielen Dank für deine Hilfe erst einmal :)
Ich habe noch eine Frage zu deiner Methode, die die TableView updated: Du hast in einer Zeile was geschrieben wie
var columns = table.getColumns(); Hier meckert mein IntelliJ rum, es könne das symbol 'var' nicht resolven.
Folglich kennt er auch die Methoden nicht wie column.get(i) etc.
Kann ich hier einfach die ObserveableList setzen, da getCollumns() ja diese zurückgibt? Falls ich dies tue, kennt er allerdings die Abfrage getHeading nicht mehr..
Auch die leeren spitzen Klammern bei new TableCollumn<>(collumns.get(i).getHeading) bemängelt er...
 
Hier meckert mein IntelliJ rum, es könne das symbol 'var' nicht resolven.
"var" gibt es erst seit Java 10. Schreib einfach ObservableList<TableColumn> columns =...

Auch die leeren spitzen
Was für eine Java Version benutzt du denn? Die leeren spitzen Klammern nennen sich Diamond Operator und sollten seit Java 7(?) verfügbar sind. Ansonsten musst du den Typ dort einfach noch mal eintragen
 
Ich benutze aktuell Java 8.. Die Diamond operatoren wurden wohl doch erkannt, war wohl lediglich ne Folge von dem "fehlenden" var, dass mir das rot unterschlängelt angezeigt wurde..
Vielen Dank für deine Hilfe :)
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben