TableView füllen

wolfin96

Mitglied
Hallo miteinander! Ich möchte bei meinem Programm einen TableView einfügen, der die verfügbaren Objekte anzeigt, im weiteren Verlauf soll man dann auch Objekte hinzufügen und löschen können, das ist momentan aber erstmal noch nicht das Problem, so weit bin ich leider noch nicht. Ich habe gerade versucht den TableView zu initialisieren und zur Probe ein paar Objekte erstellt und versucht mir anzeigen zu lassen. Dies klappt allerdings noch nicht. Ich habe eine Vermutung woran es mitunter liegen könnte (wie im Text markiert). Die Tabelle wird mit Objekten gefüllt die über ein Interface definiert werden. Bei den Objekte selbst (rund, rechteckig, quadratisch) wird jeweils die Form in der Klasse vordefiniert und das Gewicht in der Klassenmethode entsprechend berechnet (siehe weiter unten).
Vielleicht kann mir ja jemand weiterhelfen und mir sagen, warum die Daten nicht in der Tabelle dargestellt werden. Vielen Dank schon mal!

Hier erstmal der Code vom Tableview:
Java:
    @FXML private TableView<ISpielstein> tableView;
    @FXML private TableColumn<ISpielstein, String> formSpalte;
    @FXML private TableColumn<ISpielstein, Double> gewichtSpalte;  


public void initialize(URL url, ResourceBundle rb) {
        formSpalte.setCellValueFactory(new PropertyValueFactory<ISpielstein, String>("form"));
        //Hier könnte unter anderem der Fehler sein; die Variable Gewicht ist ein double
        gewichtSpalte.setCellValueFactory(new PropertyValueFactory<ISpielstein, Double>("gewicht"));
       
        tableView.setItems(getHaufen());
    }

//Habe hier ein paar Objekte zum Testen erstellt
    Rund rund  = new Rund(21);
    Rechteckig rechteckig = new Rechteckig(10, 43);
    Quadratisch quadratisch = new Quadratisch(54);
   
//Und hier zur ObservableList hinzugefügt, welche den TableView füllen soll
    public ObservableList<ISpielstein> getHaufen(){
        ObservableList <ISpielstein> steine = FXCollections.observableArrayList();
       
        steine.add(rechteckig);
        steine.add(quadratisch);
        steine.add(rund);
       
        return steine;
    }

Hier der Code beispielhaft von einem der drei Objekte, da sie sich im Grunde kaum unterscheiden (Die Variable Dichte wird im entsprechenden Interface definiert):
Java:
//erstellen der Klasse Quadratisch welche die Schnittstelle ISpielstein implementiert
public class Quadratisch implements ISpielstein {

    //Variable Seitenlaenge des quadratischen Spielsteins
    private double laenge;
   
    //Variable Breite ist gleich der Laenge, da es sich um eine quadratische Grundfläche handelt
    private double breite = laenge;
   
    //Variable fuer das Gewicht des Spielsteins
    public double gewicht;
       
    //Variable fuer die Form des Spielsteins, wird vorab definiert
    public String form = "Quader (quadratisch)";

    /*Konstruktor der Klasse Quadratisch, wird in der Main Methode zum Erstellen eines Spielsteins aufgerufen
    *wird, bekommt vom dort implementierten Scanner die Laenge und die Nummer übergeben
    */
    public Quadratisch(double laenge) {
        this.laenge = laenge;
    }

    //Setter fuer die Laenge
    public void setLaenge(double laenge) {
        this.laenge = laenge;
    }
   
    //Setter fuer die Breite
    public void setBreite(double breite) {
        this.breite = breite;
    }

    //Getter fuer die Form
    @Override
    public String getForm() {
        return form;
    }

    //Getter für das Gewicht; hier wird das Spielsteingewicht berechnet und anschliessend gerundet
    @Override
    public double getGewicht() {
        gewicht = breite * laenge * HOEHE * DICHTE;
        gewicht = Math.round(100.0 * gewicht) / 100.0;
        return gewicht;
    }

    //toString Methode gibt die wichtigsten Informationen des Spielsteins als String zurueck
    @Override
    public String toString() {
        return "Form: " + form + ", Gewicht: " + getGewicht() + "g";
    }  
}
 
Du must für die Paramenter, die du in der ObservableList auflisten möchtes, eine Property-Klasse verwenden.
[CODE lang="java" title="nicht"]private double laenge;[/CODE]
[CODE lang="java" title="sondern"]private SimpleDoubleProperty laenge;[/CODE]

Du kannst der Klasse weiterhin ein ganz einfaches double übergeben, bzw. abrufen. Entsprechend müssen aber die Getter und Setter angepasst werden.
[CODE lang="java" title="get & set"]public Double getLaenge() {
return laenge.get();
}

public void setLaenge(double laenge) {
this.laenge.set(laenge);
}
[/CODE]
 
Ach ja. Der Getter ist essentiell. Ohne den funktioniert die Liste nicht.
Und ich nehme an, ich habe es noch nicht ausprobiert, sagt mir aber die Logik, den Setter benötigst du später fürs Ändern.
MfG Missy.
 
Was heißt denn "klappt nicht"? Wird gar nichts in der Tabelle angezeigt, oder werden keine Werte in den Zellen angezeigt, oder werden nur einzelne Zellen nicht angezeigt?

Auf jeden Fall gibt es Fehler in der Quadratisch-Klasse, das was du in Zeile 8 versuchst klappt so nicht 🙂

Du must für die Paramenter, die du in der ObservableList auflisten möchtes, eine Property-Klasse verwenden.
Nein, können auch "normale" Typen sein 🙂
 
Ach ja. Der Getter ist essentiell. Ohne den funktioniert die Liste nicht.
Und ich nehme an, ich habe es noch nicht ausprobiert, sagt mir aber die Logik, den Setter benötigst du später fürs Ändern.
MfG Missy.
Danke erstmal für die Hilfe! Jetzt habe ich noch das Problem, dass ich mit den Werten von Laenge und Breite das Gewicht berechnen muss, das geht aber scheinbar nicht so einfach mit SimpleDoublePropertys wie mit normalen double Werten wenn ich das jetzt richtig gesehen habe. Gibts da eine Möglichkeit trotzdem mit SimpleDoublePropertys zu rechnen oder muss ich die erst wieder zurück zu double casten?
 
Was heißt denn "klappt nicht"? Wird gar nichts in der Tabelle angezeigt, oder werden keine Werte in den Zellen angezeigt, oder werden nur einzelne Zellen nicht angezeigt?

Auf jeden Fall gibt es Fehler in der Quadratisch-Klasse, das was du in Zeile 8 versuchst klappt so nicht 🙂


Nein, können auch "normale" Typen sein 🙂
Es werden gar keine Werte in der Tabelle angezeigt. Hast du eine Idee wo das Problem da liegen könnte?
Habe es jetzt mal probiert wie missy72 beschrieben hatte mit dem SimpleDoubleProperty, da ist jetzt aber das Problem mit dem rechnen entstanden. Hättest du da vielleicht noch eine Idee?
 
Es werden gar keine Werte in der Tabelle angezeigt. Hast du eine Idee wo das Problem da liegen könnte?
Gibt es Fehler auf der Konsole?

Hat die Tabellen keiner Spalten/keine Zeilen/leere Zeilen? Das sollte jeweils anders aussehen und Aufschluss über den Fehler geben.

Der Oben gezeigte Code ist auf jeden Fall nicht Quelle des Problems, der funktioniert grundsätzlich korrekt, solange die FXML-Datei und die etwaige module-info korrekt sind.

Habe es jetzt mal probiert wie missy72 beschrieben hatte mit dem SimpleDoubleProperty, da ist jetzt aber das Problem mit dem rechnen entstanden. Hättest du da vielleicht noch eine Idee?
Keine Propertys benutzen, wenn du diese nicht brauchst 🙂
 
Im Zweifelsfall an mrBrown halten. Ich programmiere ja auch erst seit Januar.

Mein Kenntnisstand war, dass man für die ListView eine ObservableList braucht und die Elemente aus der Property-Klasse erstellen soll/muss.

Du kannst die Berechnungen ganz normal mit dem Standard DOUBLE durchführen und den dann dem Setter der Klasse übergeben.
Ich zitiere mich mal selbst.
Du kannst der Klasse weiterhin ein ganz einfaches double übergeben, bzw. abrufen. Entsprechend müssen aber die Getter und Setter angepasst werden.
Java:
public Double getLaenge() {
return laenge.get();
}

public void setLaenge(double laenge) {
this.laenge.set(laenge);
}
 
Zuletzt bearbeitet:
Ok. Es ist so. es geht auch ohne die Property-Klasse.
Ich habe gerade mal eine Variable aus meinem aktuellen Programm umgeschrieben und funktioniert trozdem.
Dann muss ich noch mal gucken für was die Proberties eigentlich gut sind.
 
Ist zwar nicht mein Beitrag, aber ich finde das gehört hier zu.
@mrBrown. Ist es korrekt, dass die Property-Klassen benötigt werden, wenn ich über die TableView Änderungen vornehmen möchte, damit mein Objekt eine Rückmeldung bekommt? Wenn ja, dann sollte Wolfin96 schon in weiser Voraussicht, zumindest die Variablen, die später über die TableView geändert werden sollen, aus der Property-Klasse verwenden.

Ich glaube ich muss ins Bett. Ich wünsche eine gute Nacht.
 
Gibt es Fehler auf der Konsole?
(Wenn ich das Programm starte, werde ich darauf hingewiesen, dass Fehler im Projekt existieren. Wenn ich mir aber die einzelnen Controller und Klassen anschaue, werden dort keine angezeigt.
In der Konsole selbst werden beim Starten selbst Fehler angezeigt, die aber verschwunden sind, sobald das Programm geöffnet ist. Kann sie deswegen auch nicht hier zeigen...)
Muss hier nochmal korrigieren, nachdem ich Eclipse jetzt nochmal neu gestartet habe öffnet sich das Programm ohne jeglichen Hinweis auf Fehler und es wird auch nichts ungewöhnliches auf der Konsole angezeigt.

Hat die Tabellen keiner Spalten/keine Zeilen/leere Zeilen? Das sollte jeweils anders aussehen und Aufschluss über den Fehler geben.
Die Tabelle sieht nach dem Starten aus, wie auf dem Bild unten. Die Spalten habe ich jeweils mit formSpalte und gewichtSpalte im Scenebuilder bei fx:id verbunden genauso wie die Tabelle selbst mit dem tableView.
Screenshot 2021-03-19 102756.jpg
Der Oben gezeigte Code ist auf jeden Fall nicht Quelle des Problems, der funktioniert grundsätzlich korrekt, solange die FXML-Datei und die etwaige module-info korrekt sind.


Keine Propertys benutzen, wenn du diese nicht brauchst 🙂
Was meinst du mit module-info?
 
Zuletzt bearbeitet:
Ich sollte mit meinem Halbwissen jetzt ein bisschen vorsichter sein, aber Folgendes kann mrBrown mit module-info meinen.

Die FXML-Datei braucht eine Info mit welcher Klasse sie interagieren soll.
Das kann man direkt in die FXML schrieben, oder im SceneBuilder auswählen.


1616148448640.png


1616148315094.png
 
Zuletzt bearbeitet:
Um die Tabelle erstmal zum Laufen zu bringen, würde ich Fehlerquelle wie z.B. die Berechnungen weglassen und
den Variablen beim Deklarieren gleich einen Wert zuweisen. (hier ohne Property)
[CODE lang="java" title="Beispiel"]this.breite = 12.5;
this.laenge = 12.5;[/CODE]
 
Zuletzt bearbeitet:
Auf Youtube gibt es was dazu. Folge 57 und 58.
Die beiden Folgen habe ich mir nicht angeguckt, aber die Videos aus der Reihe sind recht verständlich.
 
@mrBrown. Ist es korrekt, dass die Property-Klassen benötigt werden, wenn ich über die TableView Änderungen vornehmen möchte, damit mein Objekt eine Rückmeldung bekommt? Wenn ja, dann sollte Wolfin96 schon in weiser Voraussicht, zumindest die Variablen, die später über die TableView geändert werden sollen, aus der Property-Klasse verwenden.
Jein – wenn es Propertys sind, bekommt die Tabelle Änderungen der Werte direkt mit. Das kann man zB nutzen, wenn man Werte über die Tabelle selbst editieren will, man muss aber noch ein bisschen mehr machen, als nur das.

Der Nachteil ist aber eben, dass man dann alles als Properties umsetzen muss – in den meisten Fällen will man als Model aber ein "einfaches" Java-Objekt und nicht ein extra für die View angepasstes. Wenn man also Properties nutzt, sollte man direkt ein Architekturmuster wie MVVM nutzen, mit welchem man sowohl ein einfaches Model als auch Properties nutzt.
 

Neue Themen


Zurück
Oben