Textfelder in einer ListView ausgeben

Bitte aktiviere JavaScript!
Hallo, ich komme aus der Sache leider seit gestern nicht raus.
Ich habe eine ListView. In dieser habe ich vier Textfelder drin und zwei Buttons mit + und -

Ich kann die UIControls in der ListView anzeigen, jedoch kann ich, wenn ich + drücke weitere Zeilen mit den UIControls nicht hinzufügen und mit - auch nicht löschen.

ich hoffe, man kann mir helfen.

Code:
package CreateSchemePackage;

import ViewAndController.ViewController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import list.RowListCell;
import model.Model;

public class CreateSchemeView extends VBox {
    Model model = new Model();
    private final Button view = new Button("View");
    
    private ObservableList<Model> rows = FXCollections.observableArrayList();
    ListView<Model> list = new ListView<>();
    StackPane root = new StackPane();
    Pane pane = new Pane();
    VBox vbox = new VBox();
    HBox hbox = new HBox();
    Button anzeigeListe = new Button("Listenanzeige");
    Button save = new Button("Speichern");
    
    

    public CreateSchemeView(final CreateSchemeController createSchemeController) {
        initCreateScheme();
      
      
        view.setOnAction(event -> {
            System.out.println("ButtonB has been pressed, switching to ViewA.");
          

            final Stage primaryStage = createSchemeController.getPrimaryStage();
            final ViewController viewController = new ViewController(primaryStage);
            final Scene scene = new Scene(viewController.getView(),250,600);
            scene.getStylesheets().add("style.css");
            primaryStage.setScene(scene);
            
        });
        
    }
    
    
    public void initCreateScheme(){
        
        view.setLayoutX(0);
        view.setLayoutY(0);
        
        vbox.setLayoutX(0);
        vbox.setLayoutY(0);
        vbox.setMaxWidth(200);
        vbox.setMaxHeight(800);

        hbox.setLayoutX(205);
        
        rows.add(model);
        
        list.setCellFactory(c -> new RowListCell());
        list.setItems(rows);
        
        vbox.getChildren().addAll(anzeigeListe, save);
        root.setLayoutX(205);
        root.setLayoutY(0);
        root.setPrefWidth(900);
        root.setPrefHeight(700);
        root.getChildren().addAll(list);

        hbox.getChildren().addAll(root);

        pane.getChildren().addAll(vbox, hbox);
        
        this.getChildren().addAll(view, pane);
        
    }

    public Button getCreateSchemeView() {
        return view;
    }
}
Code:
package list;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import model.Model;

public class RowListCell extends ListCell<Model> {
    private ObservableList<Model> rows = FXCollections.observableArrayList();
        private HBox content = new HBox();
        private TextField tf0 = new TextField();
        private TextField tf1 = new TextField();
        private TextField tf2 = new TextField();
        private TextField tf3 = new TextField();
        private Button add = new Button("+");
        private Button sub = new Button("-");
        Model model = new Model(tf0, tf1, tf2, tf3);

        public RowListCell() {

            content.getChildren().addAll(tf0, tf1, tf2, tf3, add, sub);
            content.setSpacing(10);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            setGraphic(content);
        }

        protected void updateItem(Model item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(content);
                //item.setValue(item.getTitle());
                add.setOnAction(e -> {
                Model newRow = new Model(tf0, tf1, tf2, tf3);
                    rows.add(newRow);
                });
                sub.setOnAction(e -> {
                    rows.remove(item);
                });
            }
        }
}
Code:
package model;


import javafx.scene.control.TextField;

public class Model {
    
    
        private TextField tf0;
        private TextField tf1;
        private TextField tf2;
        private TextField tf3;

        public Model(TextField tf0, TextField tf1, TextField tf2, TextField tf3) {

    
            this.tf0 = tf0;
            this.tf1 = tf1;
            this.tf2 = tf2;
            this.tf3 = tf3;

        }
        
        public Model() {}


        public TextField getTF0() {
            return tf0;
        }

        public void setTF0(TextField tf0) {
            this.tf0 = tf0;
        }

        public TextField getTF1() {
            return tf1;
        }

        public void setTF1(TextField tf1) {
            this.tf1 = tf1;
        }

        public TextField getTF2() {
            return tf2;
        }

        public void setTF2(TextField tf2) {
            this.tf2 = tf2;
        }

        public TextField getTF3() {
            return tf3;
        }

        public void setTF3(TextField tf3) {
            this.tf3 = tf3;
        }

    }
 

Anhänge

A

Anzeige


Vielleicht hilft dir dieser Kurs hier weiter: (hier klicken)
Hallo, ich komme aus der Sache leider seit gestern nicht raus.
Ich habe eine ListView. In dieser habe ich vier Textfelder drin und zwei Buttons mit + und -

Ich kann die UIControls in der ListView anzeigen, jedoch kann ich, wenn ich + drücke weitere Zeilen mit den UIControls nicht hinzufügen und mit - auch nicht löschen.

ich hoffe, man kann mir helfen.

Code:
package CreateSchemePackage;

import ViewAndController.ViewController;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import list.RowListCell;
import model.Model;

public class CreateSchemeView extends VBox {
    Model model = new Model();
    private final Button view = new Button("View");
   
    private ObservableList<Model> rows = FXCollections.observableArrayList();
    ListView<Model> list = new ListView<>();
    StackPane root = new StackPane();
    Pane pane = new Pane();
    VBox vbox = new VBox();
    HBox hbox = new HBox();
    Button anzeigeListe = new Button("Listenanzeige");
    Button save = new Button("Speichern");
   
   

    public CreateSchemeView(final CreateSchemeController createSchemeController) {
        initCreateScheme();
     
     
        view.setOnAction(event -> {
            System.out.println("ButtonB has been pressed, switching to ViewA.");
         

            final Stage primaryStage = createSchemeController.getPrimaryStage();
            final ViewController viewController = new ViewController(primaryStage);
            final Scene scene = new Scene(viewController.getView(),250,600);
            scene.getStylesheets().add("style.css");
            primaryStage.setScene(scene);
           
        });
       
    }
   
   
    public void initCreateScheme(){
       
        view.setLayoutX(0);
        view.setLayoutY(0);
       
        vbox.setLayoutX(0);
        vbox.setLayoutY(0);
        vbox.setMaxWidth(200);
        vbox.setMaxHeight(800);

        hbox.setLayoutX(205);
       
        rows.add(model);
       
        list.setCellFactory(c -> new RowListCell());
        list.setItems(rows);
       
        vbox.getChildren().addAll(anzeigeListe, save);
        root.setLayoutX(205);
        root.setLayoutY(0);
        root.setPrefWidth(900);
        root.setPrefHeight(700);
        root.getChildren().addAll(list);

        hbox.getChildren().addAll(root);

        pane.getChildren().addAll(vbox, hbox);
       
        this.getChildren().addAll(view, pane);
       
    }

    public Button getCreateSchemeView() {
        return view;
    }
}
Code:
package list;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import model.Model;

public class RowListCell extends ListCell<Model> {
    private ObservableList<Model> rows = FXCollections.observableArrayList();
        private HBox content = new HBox();
        private TextField tf0 = new TextField();
        private TextField tf1 = new TextField();
        private TextField tf2 = new TextField();
        private TextField tf3 = new TextField();
        private Button add = new Button("+");
        private Button sub = new Button("-");
        Model model = new Model(tf0, tf1, tf2, tf3);

        public RowListCell() {

            content.getChildren().addAll(tf0, tf1, tf2, tf3, add, sub);
            content.setSpacing(10);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            setGraphic(content);
        }

        protected void updateItem(Model item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(content);
                //item.setValue(item.getTitle());
                add.setOnAction(e -> {
                Model newRow = new Model(tf0, tf1, tf2, tf3);
                    rows.add(newRow);
                });
                sub.setOnAction(e -> {
                    rows.remove(item);
                });
            }
        }
}
Code:
package model;


import javafx.scene.control.TextField;

public class Model {
   
   
        private TextField tf0;
        private TextField tf1;
        private TextField tf2;
        private TextField tf3;

        public Model(TextField tf0, TextField tf1, TextField tf2, TextField tf3) {

   
            this.tf0 = tf0;
            this.tf1 = tf1;
            this.tf2 = tf2;
            this.tf3 = tf3;

        }
       
        public Model() {}


        public TextField getTF0() {
            return tf0;
        }

        public void setTF0(TextField tf0) {
            this.tf0 = tf0;
        }

        public TextField getTF1() {
            return tf1;
        }

        public void setTF1(TextField tf1) {
            this.tf1 = tf1;
        }

        public TextField getTF2() {
            return tf2;
        }

        public void setTF2(TextField tf2) {
            this.tf2 = tf2;
        }

        public TextField getTF3() {
            return tf3;
        }

        public void setTF3(TextField tf3) {
            this.tf3 = tf3;
        }

    }
Hi,

ich vermute mal in der RowListCell fügst du immer eine neue Row in die lokale Liste, du solltest das doch eher in die List der ListView hinzufügen. Beim Löschen genauso.

Grüße
lam
 
Hi,

ich vermute mal in der RowListCell fügst du immer eine neue Row in die lokale Liste, du solltest das doch eher in die List der ListView hinzufügen. Beim Löschen genauso.

Grüße
lam

Hi, danke für die Antwort.
Hmm, was genau soll ich im Code ändern? Ich glaube ich blicke da nicht durch :(

Grüße
Büsra
 
Bevor ich weiter antworte:
Möchtest du am Ende alle 4 Werte in der ListView darstellen? Falls ja: Wäre eine TableView vielleicht besser?
 
Bevor ich weiter antworte:
Möchtest du am Ende alle 4 Werte in der ListView darstellen? Falls ja: Wäre eine TableView vielleicht besser?
Ja genau. Alle vier Werte sollen darstellbar sein. Ja eine tableview macht mehr Sinn, aber do will das der prof nicht.
Ich würde lieber eigentlich das ganze in eine Arraylist reinschmeißen und so das ganze mit dem Plus Button immer weitere Zeilen einfügen. Jedoch habe ich dazu kein Beispiel gesehen.
 
Ja eine tableview macht mehr Sinn, aber do will das der prof nicht.
Hmm dann ist das wohl so.

Ich würde lieber eigentlich das ganze in eine Arraylist reinschmeißen
ArrayList willst du bei JavaFX so gut wie nie :)

Vielleicht hier mal ein Beispiel, wie man es machen könnte. Ist noch nicht wirklich die schönste Variante. Vielleicht setz ich mich morgen noch mal dran.
Java:
public class Main extends Application {

    private ListView<Model> listview;
    private ObservableList<Model> data;

    @Override
    public void start( Stage primaryStage ) throws Exception {
        data = FXCollections.observableArrayList(Model.EMPTY);

        listview = new ListView<>(data);
        listview.setCellFactory(getCellFactoryForModelList());

        Scene scene = new Scene(listview, 300, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Callback<ListView<Model>, ListCell<Model>> getCellFactoryForModelList() {
        return param -> new ListCell<>() {
            HBox addNewItemRow = new HBox();

            {
                TextField firstInput = new TextField();
                Model.EMPTY.firstProperty().bindBidirectional(firstInput.textProperty());

                TextField secondInput = new TextField();
                Model.EMPTY.secondProperty().bindBidirectional(secondInput.textProperty());

                TextField thirdInput = new TextField();
                Model.EMPTY.thirdProperty().bindBidirectional(thirdInput.textProperty());

                Button add = new Button("+");
                add.setOnAction(e -> data.add(data.size() - 1, Model.EMPTY.copyAndClear()));

                addNewItemRow.getChildren().addAll(firstInput, secondInput, thirdInput, add);
            }

            @Override
            protected void updateItem( Model item, boolean empty ) {
                super.updateItem(item, empty);

                if ( item == Model.EMPTY ) {
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                    setText(null);
                    setGraphic(addNewItemRow);
                } else if ( item == null || empty ) {
                    setGraphic(null);
                    setText(null);
                } else {
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                    setText(item.toString());
                    setGraphic(null);
                }
            }
        };
    }
}
Java:
public class Model {

    public static final Model EMPTY = new Model();

    private StringProperty first;
    private StringProperty second;
    private StringProperty third;

    private Model( String first, String second, String third ) {
        this.first = new SimpleStringProperty(first);
        this.second = new SimpleStringProperty(second);
        this.third = new SimpleStringProperty(third);
    }

    public Model() {
        this("", "", "");
    }

    public Model copyAndClear() {
        final Model model = new Model(getFirst(), getSecond(), getThird());
        first.set("");
        second.set("");
        third.set("");

        return model;
    }

     /* Getter andProperty Methods */

    @Override
    public String toString() {
        return getFirst() + " " + getSecond() + " " + getThird() ;
    }
}
 
Hmm dann ist das wohl so.


ArrayList willst du bei JavaFX so gut wie nie :)

Vielleicht hier mal ein Beispiel, wie man es machen könnte. Ist noch nicht wirklich die schönste Variante. Vielleicht setz ich mich morgen noch mal dran.
Java:
public class Main extends Application {

    private ListView<Model> listview;
    private ObservableList<Model> data;

    @Override
    public void start( Stage primaryStage ) throws Exception {
        data = FXCollections.observableArrayList(Model.EMPTY);

        listview = new ListView<>(data);
        listview.setCellFactory(getCellFactoryForModelList());

        Scene scene = new Scene(listview, 300, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Callback<ListView<Model>, ListCell<Model>> getCellFactoryForModelList() {
        return param -> new ListCell<>() {
            HBox addNewItemRow = new HBox();

            {
                TextField firstInput = new TextField();
                Model.EMPTY.firstProperty().bindBidirectional(firstInput.textProperty());

                TextField secondInput = new TextField();
                Model.EMPTY.secondProperty().bindBidirectional(secondInput.textProperty());

                TextField thirdInput = new TextField();
                Model.EMPTY.thirdProperty().bindBidirectional(thirdInput.textProperty());

                Button add = new Button("+");
                add.setOnAction(e -> data.add(data.size() - 1, Model.EMPTY.copyAndClear()));

                addNewItemRow.getChildren().addAll(firstInput, secondInput, thirdInput, add);
            }

            @Override
            protected void updateItem( Model item, boolean empty ) {
                super.updateItem(item, empty);

                if ( item == Model.EMPTY ) {
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                    setText(null);
                    setGraphic(addNewItemRow);
                } else if ( item == null || empty ) {
                    setGraphic(null);
                    setText(null);
                } else {
                    setContentDisplay(ContentDisplay.TEXT_ONLY);
                    setText(item.toString());
                    setGraphic(null);
                }
            }
        };
    }
}
Java:
public class Model {

    public static final Model EMPTY = new Model();

    private StringProperty first;
    private StringProperty second;
    private StringProperty third;

    private Model( String first, String second, String third ) {
        this.first = new SimpleStringProperty(first);
        this.second = new SimpleStringProperty(second);
        this.third = new SimpleStringProperty(third);
    }

    public Model() {
        this("", "", "");
    }

    public Model copyAndClear() {
        final Model model = new Model(getFirst(), getSecond(), getThird());
        first.set("");
        second.set("");
        third.set("");

        return model;
    }

     /* Getter andProperty Methods */

    @Override
    public String toString() {
        return getFirst() + " " + getSecond() + " " + getThird() ;
    }
}


hey, danke für die Hilfe. Ich glaube aber, da gab's ein Missverständnis. Mit diesem Code verschiebst du die erste Zeile jeweils in die nächste Zeile.
Durch den Button klick + , möchte ich beliebig viele Zeilen mit den Textfeldern und dem + Button haben/hinzufügen.
Hoffe ich konnte mich diesmal klarer ausdrücken :)
 
genau, mit den buttons zusammen. das ganze soll sich also in der listview "vermehren".
ich glaube in meinem code, muss nur was verändert werden. ich weiß aber nicht wo der fehler ist.
bekomme auch keine fehleranzeige oder exceptions.
 
Naja dein Code hat momentan noch ein paar Probleme. Zum einen sollte dein Model keine UI-Elemente enthalten. Zum anderen - und das ist das größere Problem - hast du in der Klasse RowListCell und in der Klasse CreateSchemeView eine Liste.
 
Ich habe jetzt die TextFelder in der Model Klasse durch Strings ersetzt und in der RowListCell die ObservableList gelöscht.
 
Ich habe jetzt die TextFelder in der Model Klasse durch Strings ersetzt
Nimm lieber Properties (falls ihr sowas schon hattet und nutzen dürft). Damit kannst du ein Binding zwischen dem Model und den UI Komponenten erstellen und somit sicherstellen, dass die Werte im Model immer den Werten in den UI Textfelder entsprechen (und andersherum).
und in der RowListCell die ObservableList gelöscht.
Dann sollte es eigentlich auch funktionieren.
Java:
public class CreateSchemeView extends VBox {

    private ListView<Model> listview;
    private ObservableList<Model> data;

    public CreateSchemeView() {
        this.data = FXCollections.observableArrayList(new Model());
        initCreateScheme();
    }

    private void initCreateScheme() {
        listview = new ListView<>(data);
        listview.setCellFactory(new RowListCellFactory());
        getChildren().add(listview);
    }
}
Java:
public class RowListCellFactory implements Callback<ListView<Model>, ListCell<Model>> {
    @Override
    public ListCell<Model> call(ListView<Model> param) {
        return new ListCell<Model>(){
            @Override
            protected void updateItem(Model item, boolean empty) {
                super.updateItem(item, empty);

                setText(null);
                setGraphic(null);

                if(item != null && !empty) {
                    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

                    HBox content = new HBox();

                    TextField firstInput = new TextField(item.getFirst());
                    item.firstProperty().bindBidirectional(firstInput.textProperty());

                    TextField secondInput = new TextField(item.getSecond());
                    item.secondProperty().bindBidirectional(secondInput.textProperty());

                    TextField thirdInput = new TextField(item.getThird());
                    item.thirdProperty().bindBidirectional(thirdInput.textProperty());

                    TextField fourthInput = new TextField(item.getFourth());
                    item.fourthProperty().bindBidirectional(fourthInput.textProperty());

                    Button addButton = new Button("+");
                    addButton.setOnAction(e -> {
                        ObservableList<Model> data = param.getItems();
                        // add new Entry under the current row
                        data.add(data.indexOf(item) + 1, new Model());
                    });

                    Button removeButton = new Button("-");
                    removeButton.setOnAction(e -> param.getItems().remove(item));

                    content.getChildren().addAll(firstInput, secondInput, thirdInput, fourthInput, addButton, removeButton);
                    setGraphic(content);
                }
            }
        };
    }
}
Solltet ihr Bindings nicht benutzen dürfen, kannst du diese ja einfach entfernen und normal mit Strings arbeiten. Dann muss aber sichergestellt werden, dass sobald sich ein Text im Textfield ändert, sich auch das Model ändert
 
@Robat
Ich hab deine Nachricht jetzt erst gesehen. Hab irgendwie keine Benachrichtigung bekommen.
Vielen Dank für die Hilfe. Es funktioniert jetzt :D
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben