Dynamische ListView-Größe, die bei Fenstergrößenänderung sich anpasst

Diskutiere Dynamische ListView-Größe, die bei Fenstergrößenänderung sich anpasst im AWT, Swing, JavaFX & SWT Bereich.
B

BigMemo007

Hallo liebe Comunity,

habe folgendes Projekt in JafaFX gemacht:

Java:
package gui;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.control.TextField;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class CreateGUIBooking {

    private Scene scene;
    private BorderPane layout;

    private VBox vBoxTop;
    private VBox vBoxBottom;
    private VBox vBoxLeft;
    private VBox vBoxRight;
    private VBox vBoxCenter;
    
    private Font fontLabel;
    
    private Label labelAmount;
    private TextField tfAmount;
    private Separator separator;
    private Button btn_buchen;
    private ListView<String> outgoings;
    private ListView<String> income;
    private Label labelOutgoings;
    private Label labelIncome;
    
    private String txtLabelAmount = "Betrag eingeben";
    private String txtLabelOutgoings = "Ausgaben";
    private String txtLabelIncome = "Einnahmen";
    private String txtBtn_buchen = "Buchen";
    
    public CreateGUIBooking() {
        layout = new BorderPane();
        scene = new Scene(layout, 700, 600);

        vBoxTop = new VBox();
        vBoxLeft = new VBox();
        vBoxCenter = new VBox();
        vBoxRight = new VBox();
        vBoxBottom = new VBox();
        
        fontLabel = Font.font("sans-serif", FontWeight.BOLD, 15);
        
        labelAmount = new Label();
        
        tfAmount = new TextField();
        separator = new Separator();
        btn_buchen = new Button();
        labelOutgoings = new Label();
        outgoings = new ListView<String>();
        labelIncome = new Label();
        income = new ListView<String>();
        
        setPostions();
    }

    private void setPostions() {

        // vBoxTop
        labelAmount.setFont(fontLabel);
        labelAmount.setText(txtLabelAmount);

        tfAmount.setAlignment(Pos.CENTER);
        tfAmount.setPrefSize(100, 25);
        tfAmount.setMinSize(100, 25);
        tfAmount.setMaxSize(100, 25);
        
        VBox.setMargin(labelAmount, new Insets(20, 0, 0, 0));
        VBox.setMargin(tfAmount, new Insets(5,0,0,0));
        vBoxTop.setAlignment(Pos.CENTER);
        
        vBoxTop.getChildren().addAll(labelAmount, tfAmount);
        layout.setTop(vBoxTop);

        
        
        // Separator
        separator.setOrientation(Orientation.VERTICAL);
        separator.setMinSize(10, 300);
        separator.setPrefSize(10, 300);
        separator.setMaxSize(10, 300);
        vBoxCenter.getChildren().add(separator);
        vBoxCenter.setAlignment(Pos.CENTER);
        layout.setCenter(vBoxCenter);

        //vBoxLeft
        labelIncome.setFont(fontLabel);
        labelIncome.setText(txtLabelIncome);
        
        income.setMinSize(300, 420);
        //vBoxLeft.setBackground(new Background(new BackgroundFill(Color.AQUA,
        //        CornerRadii.EMPTY, Insets.EMPTY)));
        
        vBoxLeft.setAlignment(Pos.CENTER);
        VBox.setMargin(income, new Insets(0, 0, 0, 20));

        vBoxLeft.getChildren().addAll(labelIncome, income);
        layout.setLeft(vBoxLeft);

        
        // vBoxRight
        labelOutgoings.setFont(fontLabel);
        labelOutgoings.setText(txtLabelOutgoings);
        
        outgoings.setMinSize(300, 420);
        
        vBoxRight.setAlignment(Pos.CENTER);
        VBox.setMargin(outgoings, new Insets(0, 20, 0, 0));

        vBoxRight.getChildren().addAll(labelOutgoings, outgoings);
        layout.setRight(vBoxRight);

        
        // vBoxBottom
        btn_buchen.setFont(fontLabel);
        btn_buchen.setText(txtBtn_buchen);
        btn_buchen.setAlignment(Pos.CENTER);
        btn_buchen.setMinSize(120, 25);
        
        vBoxBottom.setAlignment(Pos.CENTER);
        VBox.setMargin(btn_buchen, new Insets(0,0,20,0));

        vBoxBottom.getChildren().add(btn_buchen);
        layout.setBottom(vBoxBottom);


    }

    public Scene getScene() {
        return scene;
    }


}

Ich habe eine ListView<String> erstellt, die in eine VBox reingepackt und die wiederum in die layout.setLeft (BorderPane) reingetan. Links und Rechts jeweils eine.
Wenn ich aber von der Stage die Fenstergröße ändere, also mit der Maus größer kleiner ziehe, passt sich die größe der ListVievs leider nicht an. Ich habe verschiedene Propertys probiert, mit ChangeListeners gearbeitet, alles leider ohne Erfolg. Nur mein Kopf rauch immer mehr.

Kann man das in dieser Konstellation überhaupt realsieren und wenn ja, am Besten wie? :))
 
L

lam_tr

Vielleicht kannst du die ListView noch mit weitere settings machen.

Code:
ListView.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

VBox.setVgrow(ListView, Priority.ALWAYS);
somit sollte an sich die Listview immer an der VBox ausdehnen.
 
B

BigMemo007

Vielen Dank. Hat super funtkioniert. In der Höhe ist es jetzt schon dynamisch. Aber in der Breite geht es nicht. Weder die VBox noch die ListViw haben eine setHgrow Methode. Gibt es dafür auch eine Möglichkeit?
 
T

thecain

ich kenn javafx nicht gut würde aber mal ins Blinde raten, das es ein setVGrow gibt
 
B

BigMemo007

ich kenn javafx nicht gut würde aber mal ins Blinde raten, das es ein setVGrow gibt
Ein setVGrow gibt es aber eben kein setHGrow bei VBox. Das setHGrow gibt es bei HBox und ich verwende nunmal eine VBox. Das ist mein Problem bei der dynamischen Anpassung der Breite.

Ist es eine Idee, die VBox nochmal in eine HBox zu packen?
 
L

lam_tr

Ein setVGrow gibt es aber eben kein setHGrow bei VBox. Das setHGrow gibt es bei HBox und ich verwende nunmal eine VBox. Das ist mein Problem bei der dynamischen Anpassung der Breite.

Ist es eine Idee, die VBox nochmal in eine HBox zu packen?
Kommst du mit control.setMaxWidth(Double.MAX_VALUE) nicht zum Ziel?
 
B

BigMemo007

Kommst du mit control.setMaxWidth(Double.MAX_VALUE) nicht zum Ziel?
Leider nicht. Das Problem ist, dass beim ändern der Breite des Fensters, das borderPane.CENTER breiter oder schmaler wird, also sich anpasst.
Die LEFT und RIGHT, da sind meine ListViews jeweils drin, reagieren auf die Breitenveränderung nicht. Die reagieren auf die Höhenänderung.
Eine Möglichkeit der BorderLayout mitzuteilen, dass die Breite des CENTERs fest bleiben soll und die des LEFTs und RIGHTs dynamsich sein soll, würde das Problem lösten. Aber ich habe bis jetzt nichts gefunden.
 
L

lam_tr

Leider nicht. Das Problem ist, dass beim ändern der Breite des Fensters, das borderPane.CENTER breiter oder schmaler wird, also sich anpasst.
Die LEFT und RIGHT, da sind meine ListViews jeweils drin, reagieren auf die Breitenveränderung nicht. Die reagieren auf die Höhenänderung.
Eine Möglichkeit der BorderLayout mitzuteilen, dass die Breite des CENTERs fest bleiben soll und die des LEFTs und RIGHTs dynamsich sein soll, würde das Problem lösten. Aber ich habe bis jetzt nichts gefunden.
Okay ich habe mir mal dein Code angeschaut, es ist echt ein komisches Verhalten, so habe ich das auch noch nicht gemacht. Wieso verpackst du nicht alle zwei listViews mit dem Separator in eine HBox und stellst sie in den Center von der BorderPane.

Das sollte auf jeden Fall funktionieren.
 
L

lam_tr

Ich habe jetzt nicht alles nachgebaut sondern nur auf die ListView und Separator mich beschränkt. Hier das passende Snipptet dazu basierend auf deinen Code

Code:
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class CreateGUIBooking extends Application {

    private Scene scene;

    public CreateGUIBooking() {
        BorderPane parent = new BorderPane();
        HBox hbox = new HBox(5);
        VBox vbox = createPane("Einnahmen");
        hbox.getChildren().add(vbox);

        Separator separator = new Separator();
        separator.setOrientation(Orientation.VERTICAL);
        hbox.getChildren().add(separator);
        hbox.getChildren().add(createPane("Ausgaben"));
        parent.setCenter(hbox);
        scene = new Scene(parent, 700, 600);
    }

    private VBox createPane(String name) {
        VBox vbox = new VBox(5);
        ListView<Object> listview = new ListView<>();
        VBox.setVgrow(listview, Priority.ALWAYS);
        Label label = new Label(name);
        label.setMaxWidth(Double.MAX_VALUE);
        label.setAlignment(Pos.CENTER);
        vbox.getChildren().add(label);
        vbox.getChildren().add(listview);
        HBox.setHgrow(vbox, Priority.ALWAYS);
        return vbox;
    }

    public Scene getScene() {
        return scene;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        CreateGUIBooking creator = new CreateGUIBooking();
        primaryStage.setScene(creator.getScene());
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}
 
B

BigMemo007

Vielen Dank an euch. Das mit dem dynamischen Anpassen an Fenstergröße vertikal sowie horizontal klappt jetzt super.

Nun möchte ich in den Bottom des BorderPanes 3 Buttons reinpacken. Eins soll ganz links, eins in der mitte und das dritte ganz rechts platziert werden. Ich möchte eigentlich auf Margin verzichten. Mit Position habe ich es leider nicht hinbekommen. Was mache ich falsch?

Java:
package gui;

import java.time.LocalDate;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class CreateGUIBooking {

    private Scene scene;
    private BorderPane layout;

    private VBox vBoxDate;
    private HBox hBoxTop;
    private HBox hBoxCenter;
    private VBox vBoxCenterRight;
    private VBox vBoxCenterLeft;
    private VBox vBoxCenterMiddle;
    private HBox hBoxBottom;
    
    private Font fontLabel;
    
    private DatePicker datePicker;
    private Label labelDate;
    
    private Label labelAmount;
    private MyNumTextField tfAmount;
    private Separator separator;
    private Button btnBooking;
    private Button btnAnalyseBookings;
    private Button btnEditBookings;
    private ListView<String> outgoings;
    private ListView<String> income;
    private Label labelOutgoings;
    private Label labelIncome;
    
    private String txtLabelAmount = "Betrag eingeben";
    private String txtLabelOutgoings = "Ausgaben";
    private String txtLabelIncome = "Einnahmen";
    private String txtBtn_buchen = "Buchen";
    private String txtLabelDate = "Tag der Buchung";
    
    public CreateGUIBooking() {
        layout = new BorderPane();
        scene = new Scene(layout, 700, 600);
        
        vBoxDate = new VBox();
        vBoxCenterMiddle = new VBox();
        hBoxTop = new HBox();
        hBoxCenter = new HBox();
        vBoxCenterLeft = new VBox();
        vBoxCenterRight = new VBox();
        hBoxBottom = new HBox();
        
        fontLabel = Font.font("sans-serif", FontWeight.BOLD, 15);
        labelDate = new Label();
        labelAmount = new Label();
        labelIncome = new Label();
        labelOutgoings = new Label();
        
        tfAmount = new MyNumTextField();
        datePicker = new DatePicker();
        separator = new Separator();
        
        outgoings = new ListView<String>();
        income = new ListView<String>();
        
        btnBooking = new Button();
        btnAnalyseBookings = new Button();
        btnEditBookings = new Button();
        
        setSettings();
        setPostions();
    }
    
    private void setSettings() {
        labelDate.setText(txtLabelDate);
        labelDate.setFont(fontLabel);
        labelAmount.setFont(fontLabel);
        labelAmount.setText(txtLabelAmount);
        labelIncome.setFont(fontLabel);
        labelIncome.setText(txtLabelIncome);
        labelOutgoings.setFont(fontLabel);
        labelOutgoings.setText(txtLabelOutgoings);
        
        btnBooking.setFont(fontLabel);
        btnBooking.setText(txtBtn_buchen);
        
        btnAnalyseBookings.setFont(fontLabel);
        btnAnalyseBookings.setText("Auswertung ansehen");
        btnEditBookings.setFont(fontLabel);
        btnEditBookings.setText("Buchungen editieren");
        
        datePicker.setShowWeekNumbers(true);
        datePicker.setValue(LocalDate.now());
        //datePicker.setEffect(new SepiaTone());
        
    }

    private void setPostions() {

        // setup BorderPane TOP       
        vBoxDate.setAlignment(Pos.CENTER);
        vBoxDate.getChildren().addAll(labelDate, datePicker);
        
        hBoxTop.setAlignment(Pos.CENTER);
        hBoxTop.getChildren().addAll(vBoxDate);
        layout.setTop(hBoxTop);

        
        // setup BorderPane CENTER
            // setup income
        VBox.setVgrow(income, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterLeft.setAlignment(Pos.CENTER);  //zentriert labelIncome
        VBox.setMargin(income, new Insets(0, 20, 20, 20));
        vBoxCenterLeft.getChildren().addAll(labelIncome, income);
        
            // setup outgoings
        VBox.setVgrow(outgoings, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterRight.setAlignment(Pos.CENTER);    //zentriert labelOutgoings
        VBox.setMargin(outgoings, new Insets(0, 20, 20, 20));
        vBoxCenterRight.getChildren().addAll(labelOutgoings, outgoings);
        

             //setup AmountField and Separator
        tfAmount.setMinSize(100, 25);
        tfAmount.setMaxSize(100, 25);
        tfAmount.setPadding(new Insets(5,0,0,10));
        
        separator.setOrientation(Orientation.VERTICAL);
        separator.setPadding(new Insets(30,0,50,0)); //Strich unten sieht schöner aus
        
        vBoxCenterMiddle.getChildren().addAll(labelAmount, tfAmount, separator);
        VBox.setMargin(labelAmount, new Insets(20,0,10,0));
        VBox.setVgrow(separator, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        VBox.setVgrow(vBoxCenterMiddle, Priority.ALWAYS); //und separator wird angezeigt
        vBoxCenterMiddle.setAlignment(Pos.CENTER);       
        
            // merge the nodes in CENTER
        HBox.setHgrow(vBoxCenterLeft, Priority.ALWAYS);
        HBox.setHgrow(vBoxCenterRight, Priority.ALWAYS);
        hBoxCenter.getChildren().addAll(vBoxCenterLeft, vBoxCenterMiddle, vBoxCenterRight);
        layout.setCenter(hBoxCenter);
        
        
  [B]      // setup BorderPane BOTTOM
        btnAnalyseBookings.setMinSize(150, 25);
        btnBooking.setMinSize(150, 25);
        btnEditBookings.setMinSize(150, 25);
        
        VBox vBoxEdit = new VBox();
        VBox vBoxBooking = new VBox();
        VBox vBoxAnalyse = new VBox();
        
        vBoxAnalyse.getChildren().add(btnAnalyseBookings);
        vBoxBooking.getChildren().add(btnBooking);
        vBoxEdit.getChildren().add(btnEditBookings);
        
        VBox.setMargin(btnBooking, new Insets(0, 50, 0, 50));
        BorderPane.setMargin(hBoxBottom, new Insets(0,0,20,0));
        hBoxBottom.setAlignment(Pos.CENTER);
        
        
        //btnAnalyseBookings.setMaxWidth(Double.MAX_VALUE);
        //btnBooking.setMaxWidth(Double.MAX_VALUE);
        //btnEditBookings.setMaxWidth(Double.MAX_VALUE);
        
        //BorderPane.setAlignment(vBoxEdit, Pos.CENTER_LEFT);
        //BorderPane.setAlignment(vBoxBooking, Pos.CENTER);
        //BorderPane.setAlignment(vBoxAnalyse, Pos.CENTER_RIGHT);
        
        //vBoxAnalyse.setAlignment(Pos.BASELINE_LEFT);
        //vBoxBooking.setAlignment(Pos.BASELINE_CENTER);
        //vBoxEdit.setAlignment(Pos.BASELINE_RIGHT);
        
        
        //hBoxBottom.getChildren().addAll(btnAnalyseBookings, btnBooking, btnEditBookings);
        hBoxBottom.getChildren().addAll(vBoxEdit, vBoxBooking, vBoxAnalyse);
        layout.setBottom(hBoxBottom);[/B]

    }

    public Scene getScene() {
        return scene;
    }


}
 
L

lam_tr

Kannst du die Buttons nicht in ein HBox verpacken und zwischen einzelne Buttons ein zu hbox-wachsendes, leeres Label hinzufügen:)
 
B

BigMemo007

Java:
// setup BorderPane BOTTOM
        btnAnalyseBookings.setMinSize(150, 25);
        btnBooking.setMinSize(150, 25);
        btnEditBookings.setMinSize(150, 25);
        

        BorderPane.setMargin(hBoxBottom, new Insets(20,20,20,20));

        Label l1 = new Label();
        l1.setMinWidth(20);
        l1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l1, Priority.ALWAYS);
        
        Label l2 = new Label();
        l2.setMinWidth(20);
        l2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l2, Priority.ALWAYS);
        
        hBoxBottom.getChildren().addAll(btnAnalyseBookings, l1, btnBooking, l2, btnEditBookings);
        layout.setBottom(hBoxBottom);
    

    }
Mit diesem Code gehts. :))

Schade, dass die BorderPane und die HBox nicht mit Positions das auch lösen können. Habe 2 Stunden meines Lebens verschwendet :(. AnchoPane war auch keine Hilfe.
 
L

lam_tr

Alternativ kannst du auch GridPane benutzen und dort die Ausrichtungen auslegen mit drei Columns.
 
B

BigMemo007

Vielen Dank schonmal für eure Hilfen. Ich habe folgenden Code zusammengestellt. Er sieht schrecklich aus, finde ich. Wie kann ich besser aufräumen? Soll ich eine Klasse erstellen, die mir die gewünschten und dort formatierten ListViews gibt? Oder wie schreibt man denn übersichtlierech Code?

Java:
package gui;

import java.time.LocalDate;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class CreateGUIBooking {

    private Scene scene;
    private BorderPane layout;

    private VBox vBoxDate;
    private HBox hBoxTop;
    private HBox hBoxCenter;
    private VBox vBoxCenterRight;
    private VBox vBoxCenterLeft;
    private VBox vBoxCenterMiddle;
    private HBox hBoxBottom;
    
    private Font font1;
    private Font font2;
    
    private Label labelOutgoings;
    private Label labelIncome;
    private Label labelDate;
    private Label labelAmount;
    
    private DatePicker datePicker;
    private MyNumTextField tfAmount;
    private Separator separator;
    private ListView<String> outgoings;
    private ListView<String> income;
    
    private Button btnBooking;
    private Button btnAnalyseBookings;
    private Button btnEditBookings;
    private Button btnAddIncome;
    private Button btnRemoveIncome;
    private Button btnAddOutgoing;
    private Button btnRemoveOutgoing;
    
    private String txtLabelAmount = "Betrag eingeben";
    private String txtLabelOutgoings = "Ausgaben";
    private String txtLabelIncome = "Einnahmen";
    private String txtBtn_buchen = "Buchen";
    private String txtLabelDate = "Tag der Buchung";
    
    public CreateGUIBooking() {
        layout = new BorderPane();
        scene = new Scene(layout, 800, 600);
        
        vBoxDate = new VBox();
        vBoxCenterMiddle = new VBox();
        hBoxTop = new HBox();
        hBoxCenter = new HBox();
        vBoxCenterLeft = new VBox();
        vBoxCenterRight = new VBox();
        hBoxBottom = new HBox();
        
        font1 = Font.font("sans-serif", FontWeight.BOLD, 15);
        font2 = Font.font("sans-serif", FontWeight.BOLD, 12);
        
        labelDate = new Label();
        labelAmount = new Label();
        labelIncome = new Label();
        labelOutgoings = new Label();
        
        tfAmount = new MyNumTextField();
        datePicker = new DatePicker();
        separator = new Separator();
        
        outgoings = new ListView<String>();
        income = new ListView<String>();
        
        btnBooking = new Button();
        btnAnalyseBookings = new Button();
        btnEditBookings = new Button();
        btnAddIncome = new Button();
        btnAddOutgoing = new Button();
        btnRemoveIncome = new Button();
        btnRemoveOutgoing = new Button();
        
        setSettings();
        setPostions();
    }
    
    private void setSettings() {
        labelDate.setText(txtLabelDate);
        labelDate.setFont(font1);
        labelAmount.setFont(font1);
        labelAmount.setText(txtLabelAmount);
        labelIncome.setFont(font1);
        labelIncome.setText(txtLabelIncome);
        labelOutgoings.setFont(font1);
        labelOutgoings.setText(txtLabelOutgoings);
        
        btnBooking.setFont(font1);
        btnBooking.setText(txtBtn_buchen);
        
        btnAddIncome.setFont(font2);
        btnAddIncome.setText("+");
        btnAddOutgoing.setFont(font2);
        btnAddOutgoing.setText("+");
        btnRemoveIncome.setFont(font2);
        btnRemoveIncome.setText("-");
        btnRemoveOutgoing.setFont(font2);
        btnRemoveOutgoing.setText("-");
        btnAnalyseBookings.setFont(font2);
        btnAnalyseBookings.setText("Auswertung ansehen");
        btnEditBookings.setFont(font2);
        btnEditBookings.setText("Buchungen editieren");
        
        datePicker.setShowWeekNumbers(true);
        datePicker.setValue(LocalDate.now());
        //datePicker.setEffect(new SepiaTone());
        
    }

    private void setPostions() {

        // setup BorderPane TOP       
        vBoxDate.setAlignment(Pos.CENTER);
        vBoxDate.getChildren().addAll(labelDate, datePicker);
        
        hBoxTop.setAlignment(Pos.CENTER);
        BorderPane.setMargin(hBoxTop, new Insets(10,0,10,0));
        hBoxTop.getChildren().addAll(vBoxDate);
        layout.setTop(hBoxTop);

        
        // setup BorderPane CENTER
            // setup income
        HBox hBoxIncome = new HBox();
        HBox.setMargin(btnRemoveIncome, new Insets(0, 20, 5, 30));
        HBox.setMargin(btnAddIncome, new Insets(0, 30, 5, 0));
        
        Label spaceLabelIncome1 = new Label();
        spaceLabelIncome1.setMinWidth(20);
        spaceLabelIncome1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelIncome1, Priority.ALWAYS);

        Label spaceLabelIncome2 = new Label();
        spaceLabelIncome2.setMinWidth(20);
        spaceLabelIncome2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelIncome2, Priority.ALWAYS);

        hBoxIncome.getChildren().addAll(btnRemoveIncome, spaceLabelIncome1, labelIncome,
                spaceLabelIncome2, btnAddIncome);
            
        VBox.setVgrow(income, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterLeft.setAlignment(Pos.CENTER);  //zentriert labelIncome
        VBox.setMargin(income, new Insets(0, 20, 0, 20));
        vBoxCenterLeft.getChildren().addAll(hBoxIncome, income);
        
            // setup outgoings
        HBox hBoxOutgoing = new HBox();
        HBox.setMargin(btnRemoveOutgoing, new Insets(0, 20, 5, 30));
        HBox.setMargin(btnAddOutgoing, new Insets(0, 30, 5, 0));
        
        Label spaceLabelOutgoing1 = new Label();
        spaceLabelOutgoing1.setMinWidth(20);
        spaceLabelOutgoing1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelOutgoing1, Priority.ALWAYS);

        Label spaceLabelOutgoing2 = new Label();
        spaceLabelOutgoing2.setMinWidth(20);
        spaceLabelOutgoing2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelOutgoing2, Priority.ALWAYS);

        hBoxOutgoing.getChildren().addAll(btnRemoveOutgoing, spaceLabelOutgoing1, labelOutgoings,
                spaceLabelOutgoing2, btnAddOutgoing);
        
        
        VBox.setVgrow(outgoings, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterRight.setAlignment(Pos.CENTER);    //zentriert labelOutgoings
        VBox.setMargin(outgoings, new Insets(0, 20, 0, 20));
        vBoxCenterRight.getChildren().addAll(hBoxOutgoing, outgoings);
        

             //setup AmountField and Separator
        tfAmount.setMinSize(100, 25);
        tfAmount.setMaxSize(100, 25);
        
        separator.setOrientation(Orientation.VERTICAL);
        separator.setPadding(new Insets(30,0,50,0)); //Strich unten sieht schöner aus
        
        vBoxCenterMiddle.getChildren().addAll(labelAmount, tfAmount, separator);
        VBox.setMargin(labelAmount, new Insets(20,0,5,0));
        VBox.setVgrow(separator, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        VBox.setVgrow(vBoxCenterMiddle, Priority.ALWAYS); //und separator wird angezeigt
        vBoxCenterMiddle.setAlignment(Pos.CENTER);       
        
            // merge the nodes in CENTER
        HBox.setHgrow(vBoxCenterLeft, Priority.ALWAYS);
        HBox.setHgrow(vBoxCenterRight, Priority.ALWAYS);
        hBoxCenter.getChildren().addAll(vBoxCenterLeft, vBoxCenterMiddle, vBoxCenterRight);
        layout.setCenter(hBoxCenter);
        
        
        // setup BorderPane BOTTOM
        btnAnalyseBookings.setMinSize(150, 25);
        btnBooking.setMinSize(150, 25);
        btnEditBookings.setMinSize(150, 25);
        

        BorderPane.setMargin(hBoxBottom, new Insets(20,20,20,20));

        Label l1 = new Label();
        l1.setMinWidth(20);
        l1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l1, Priority.ALWAYS);
        
        Label l2 = new Label();
        l2.setMinWidth(20);
        l2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l2, Priority.ALWAYS);
        
        hBoxBottom.getChildren().addAll(btnAnalyseBookings, l1, btnBooking, l2, btnEditBookings);
        layout.setBottom(hBoxBottom);
    

    }

    public Scene getScene() {
        return scene;
    }


}

Allein für diese Gui habe ich 2 Tage gebraucht. Ist das normal beim Programmieren? Wenn es an die Logik geht, werde ich wahrscheinlich 2 Jahre brauchen.
 
L

lam_tr

Vielen Dank schonmal für eure Hilfen. Ich habe folgenden Code zusammengestellt. Er sieht schrecklich aus, finde ich. Wie kann ich besser aufräumen? Soll ich eine Klasse erstellen, die mir die gewünschten und dort formatierten ListViews gibt? Oder wie schreibt man denn übersichtlierech Code?

Java:
package gui;

import java.time.LocalDate;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class CreateGUIBooking {

    private Scene scene;
    private BorderPane layout;

    private VBox vBoxDate;
    private HBox hBoxTop;
    private HBox hBoxCenter;
    private VBox vBoxCenterRight;
    private VBox vBoxCenterLeft;
    private VBox vBoxCenterMiddle;
    private HBox hBoxBottom;
   
    private Font font1;
    private Font font2;
   
    private Label labelOutgoings;
    private Label labelIncome;
    private Label labelDate;
    private Label labelAmount;
   
    private DatePicker datePicker;
    private MyNumTextField tfAmount;
    private Separator separator;
    private ListView<String> outgoings;
    private ListView<String> income;
   
    private Button btnBooking;
    private Button btnAnalyseBookings;
    private Button btnEditBookings;
    private Button btnAddIncome;
    private Button btnRemoveIncome;
    private Button btnAddOutgoing;
    private Button btnRemoveOutgoing;
   
    private String txtLabelAmount = "Betrag eingeben";
    private String txtLabelOutgoings = "Ausgaben";
    private String txtLabelIncome = "Einnahmen";
    private String txtBtn_buchen = "Buchen";
    private String txtLabelDate = "Tag der Buchung";
   
    public CreateGUIBooking() {
        layout = new BorderPane();
        scene = new Scene(layout, 800, 600);
       
        vBoxDate = new VBox();
        vBoxCenterMiddle = new VBox();
        hBoxTop = new HBox();
        hBoxCenter = new HBox();
        vBoxCenterLeft = new VBox();
        vBoxCenterRight = new VBox();
        hBoxBottom = new HBox();
       
        font1 = Font.font("sans-serif", FontWeight.BOLD, 15);
        font2 = Font.font("sans-serif", FontWeight.BOLD, 12);
       
        labelDate = new Label();
        labelAmount = new Label();
        labelIncome = new Label();
        labelOutgoings = new Label();
       
        tfAmount = new MyNumTextField();
        datePicker = new DatePicker();
        separator = new Separator();
       
        outgoings = new ListView<String>();
        income = new ListView<String>();
       
        btnBooking = new Button();
        btnAnalyseBookings = new Button();
        btnEditBookings = new Button();
        btnAddIncome = new Button();
        btnAddOutgoing = new Button();
        btnRemoveIncome = new Button();
        btnRemoveOutgoing = new Button();
       
        setSettings();
        setPostions();
    }
   
    private void setSettings() {
        labelDate.setText(txtLabelDate);
        labelDate.setFont(font1);
        labelAmount.setFont(font1);
        labelAmount.setText(txtLabelAmount);
        labelIncome.setFont(font1);
        labelIncome.setText(txtLabelIncome);
        labelOutgoings.setFont(font1);
        labelOutgoings.setText(txtLabelOutgoings);
       
        btnBooking.setFont(font1);
        btnBooking.setText(txtBtn_buchen);
       
        btnAddIncome.setFont(font2);
        btnAddIncome.setText("+");
        btnAddOutgoing.setFont(font2);
        btnAddOutgoing.setText("+");
        btnRemoveIncome.setFont(font2);
        btnRemoveIncome.setText("-");
        btnRemoveOutgoing.setFont(font2);
        btnRemoveOutgoing.setText("-");
        btnAnalyseBookings.setFont(font2);
        btnAnalyseBookings.setText("Auswertung ansehen");
        btnEditBookings.setFont(font2);
        btnEditBookings.setText("Buchungen editieren");
       
        datePicker.setShowWeekNumbers(true);
        datePicker.setValue(LocalDate.now());
        //datePicker.setEffect(new SepiaTone());
       
    }

    private void setPostions() {

        // setup BorderPane TOP      
        vBoxDate.setAlignment(Pos.CENTER);
        vBoxDate.getChildren().addAll(labelDate, datePicker);
       
        hBoxTop.setAlignment(Pos.CENTER);
        BorderPane.setMargin(hBoxTop, new Insets(10,0,10,0));
        hBoxTop.getChildren().addAll(vBoxDate);
        layout.setTop(hBoxTop);

       
        // setup BorderPane CENTER
            // setup income
        HBox hBoxIncome = new HBox();
        HBox.setMargin(btnRemoveIncome, new Insets(0, 20, 5, 30));
        HBox.setMargin(btnAddIncome, new Insets(0, 30, 5, 0));
       
        Label spaceLabelIncome1 = new Label();
        spaceLabelIncome1.setMinWidth(20);
        spaceLabelIncome1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelIncome1, Priority.ALWAYS);

        Label spaceLabelIncome2 = new Label();
        spaceLabelIncome2.setMinWidth(20);
        spaceLabelIncome2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelIncome2, Priority.ALWAYS);

        hBoxIncome.getChildren().addAll(btnRemoveIncome, spaceLabelIncome1, labelIncome,
                spaceLabelIncome2, btnAddIncome);
           
        VBox.setVgrow(income, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterLeft.setAlignment(Pos.CENTER);  //zentriert labelIncome
        VBox.setMargin(income, new Insets(0, 20, 0, 20));
        vBoxCenterLeft.getChildren().addAll(hBoxIncome, income);
       
            // setup outgoings
        HBox hBoxOutgoing = new HBox();
        HBox.setMargin(btnRemoveOutgoing, new Insets(0, 20, 5, 30));
        HBox.setMargin(btnAddOutgoing, new Insets(0, 30, 5, 0));
       
        Label spaceLabelOutgoing1 = new Label();
        spaceLabelOutgoing1.setMinWidth(20);
        spaceLabelOutgoing1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelOutgoing1, Priority.ALWAYS);

        Label spaceLabelOutgoing2 = new Label();
        spaceLabelOutgoing2.setMinWidth(20);
        spaceLabelOutgoing2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(spaceLabelOutgoing2, Priority.ALWAYS);

        hBoxOutgoing.getChildren().addAll(btnRemoveOutgoing, spaceLabelOutgoing1, labelOutgoings,
                spaceLabelOutgoing2, btnAddOutgoing);
       
       
        VBox.setVgrow(outgoings, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        vBoxCenterRight.setAlignment(Pos.CENTER);    //zentriert labelOutgoings
        VBox.setMargin(outgoings, new Insets(0, 20, 0, 20));
        vBoxCenterRight.getChildren().addAll(hBoxOutgoing, outgoings);
       

             //setup AmountField and Separator
        tfAmount.setMinSize(100, 25);
        tfAmount.setMaxSize(100, 25);
       
        separator.setOrientation(Orientation.VERTICAL);
        separator.setPadding(new Insets(30,0,50,0)); //Strich unten sieht schöner aus
       
        vBoxCenterMiddle.getChildren().addAll(labelAmount, tfAmount, separator);
        VBox.setMargin(labelAmount, new Insets(20,0,5,0));
        VBox.setVgrow(separator, Priority.ALWAYS); //passt vertikal an Fenstergröße an
        VBox.setVgrow(vBoxCenterMiddle, Priority.ALWAYS); //und separator wird angezeigt
        vBoxCenterMiddle.setAlignment(Pos.CENTER);      
       
            // merge the nodes in CENTER
        HBox.setHgrow(vBoxCenterLeft, Priority.ALWAYS);
        HBox.setHgrow(vBoxCenterRight, Priority.ALWAYS);
        hBoxCenter.getChildren().addAll(vBoxCenterLeft, vBoxCenterMiddle, vBoxCenterRight);
        layout.setCenter(hBoxCenter);
       
       
        // setup BorderPane BOTTOM
        btnAnalyseBookings.setMinSize(150, 25);
        btnBooking.setMinSize(150, 25);
        btnEditBookings.setMinSize(150, 25);
       

        BorderPane.setMargin(hBoxBottom, new Insets(20,20,20,20));

        Label l1 = new Label();
        l1.setMinWidth(20);
        l1.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l1, Priority.ALWAYS);
       
        Label l2 = new Label();
        l2.setMinWidth(20);
        l2.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l2, Priority.ALWAYS);
       
        hBoxBottom.getChildren().addAll(btnAnalyseBookings, l1, btnBooking, l2, btnEditBookings);
        layout.setBottom(hBoxBottom);
   

    }

    public Scene getScene() {
        return scene;
    }


}

Allein für diese Gui habe ich 2 Tage gebraucht. Ist das normal beim Programmieren? Wenn es an die Logik geht, werde ich wahrscheinlich 2 Jahre brauchen.
Ich finde komplexe UIs sollte man lieber in FXML machen, da hat man wenigsten noch eine Übersicht. Aber das ist Geschmackssache. Mit FXML bin ich in der Regel viel schnell dran als wenn ich alles programmatisch hinklatsche. Außerdem wird mir die Kontroller Klasse auch generiert was sehr praktisch ist.

Ich denke es ist normal wenn du mehr Zeit zum programmieren brauchst, wenn ich auf ein Problem stoße dann muss es zuerst gelöst werden, was wiederum Zeit braucht.
 
B

BigMemo007

Ich habe versucht meinen Code aufzuräumen und in Klassen unterteilt. Ich würde mich sehr freuen, wenn ihr Profis drüber schaut und mir Tipps gibt, wie ich es besser machen kann. FXML habe ich nicht so viel die Ahnung, aber ich will erstmal die Pike besser verstehen. Dann gehe ich in FXML über.
Würden Profis ohne FXML diese GUI auch so ähnlich schreiben, oder gibt es bessere Metholden? Über jeden Feedback und Tipp freue ich mich sehr.

Java:
package application;

import guiBooking.CreateGUIBooking;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Start extends Application {

    CreateGUIBooking guiBooking;
    Scene sceneGUIBooking;

    public Start() {
        guiBooking = new CreateGUIBooking();
        sceneGUIBooking = guiBooking.getScene();

    }

    public static void main(String[] args) {
        launch();

    }

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

        stage.setScene(sceneGUIBooking);
        stage.setTitle("Einnahmen-Ausgaben APP");
        stage.show();

    }

}
Java:
package objects;

import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

public class Var {

    public static final Font fontBig = Font.font("sans-serif", FontWeight.BOLD, 15);
    public static final Font fontSmall = Font.font("sans-serif", FontWeight.BOLD, 12);
    public static final Font fontExtraBig = Font.font("sans-serif", FontWeight.BOLD, 18);

    public static final Label mySpace() {
        Label l = new Label();
        l.setMinWidth(20);
        l.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l, Priority.ALWAYS);

        return l;

    }

}// end class
Java:
package guiBooking;

import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.DatePicker;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import objects.Var;

public class BPTop {

    private Label labelDate;
    private DatePicker datePicker;

    private String txtLabelDate = "Tag der Buchung";

    private VBox vBox;

    public BPTop() {

        labelDate = new Label(txtLabelDate);
        labelDate.setFont(Var.fontBig);
        datePicker = new DatePicker();

        vBox = new VBox();

        createVBox();
    }

    // datepicker and its labeling
    private void createVBox() {
        vBox.setAlignment(Pos.BASELINE_CENTER);
        BorderPane.setMargin(vBox, new Insets(5, 0, 25, 0));

        vBox.getChildren().addAll(labelDate, datePicker);

    }

    public VBox getvBox() {
        return vBox;
    }

}// end class
Java:
package guiBooking;

import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import objects.Var;

public class BPBottom {

    private final Button btnAnalyseBookings;
    private final Button btnBooking;
    private final Button btnEditBookings;

    private final String txtBtnAnalyseBookings = "Auswertung ansehen";
    private final String txtBtnBooking = "Buchen";
    private final String txtBtnEditBookings = "Buchungen editieren";

    HBox hbox;

    public BPBottom() {

        btnAnalyseBookings = new Button(txtBtnAnalyseBookings);
        btnBooking = new Button(txtBtnBooking);
        btnEditBookings = new Button(txtBtnEditBookings);

        btnAnalyseBookings.setFont(Var.fontSmall);
        btnBooking.setFont(Var.fontExtraBig);
        btnEditBookings.setFont(Var.fontSmall);

        btnAnalyseBookings.setMinSize(150, 25);
        btnBooking.setMinSize(150, 25);
        btnEditBookings.setMinSize(150, 25);

        hbox = new HBox();

        createHBox();

    }

    public void createHBox() {
        BorderPane.setMargin(hbox, new Insets(0, 20, 10, 20));

        hbox.getChildren().addAll(btnAnalyseBookings, Var.mySpace(), btnBooking, Var.mySpace(), btnEditBookings);
    }

    public HBox getHbox() {
        return hbox;
    }

}// end class
Java:
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

public class MyItemList {

    private String listID;
    private String labelTxt;
    private String addButtonTxt;
    private String remButtonTxt;
    private ListView<String> listView;

    // includes remButton, label and addButton
    private HBox hBox;

    // includes hBox and listView and is to return
    private VBox vBox;

    public MyItemList(String labelTxt, String addButtonTxt, String remButtonTxt) {
        super();

        this.labelTxt = labelTxt;
        this.addButtonTxt = addButtonTxt;
        this.remButtonTxt = remButtonTxt;

        listView = new ListView<String>();
        listView.setId(listID);

        createHBox();
        createVbox();

    }

    // for the Buttons to add or remove items and the label of list
    private void createHBox() {
        hBox = new HBox();
        Label label = new Label(labelTxt);
        Button addBtn = new Button(addButtonTxt);
        Button remBtn = new Button(remButtonTxt);

        label.setFont(Var.fontBig);
        addBtn.setFont(Var.fontSmall);
        remBtn.setFont(Var.fontSmall);

        hBox.getChildren().addAll(remBtn, Var.mySpace(), label, Var.mySpace(), addBtn);

    }

    // contains hBox and listview and adjusting placing
    private void createVbox() {

        vBox = new VBox();
        vBox.getChildren().addAll(hBox, listView);

        HBox.setHgrow(vBox, Priority.ALWAYS);
        VBox.setVgrow(listView, Priority.ALWAYS);

        VBox.setMargin(hBox, new Insets(0, 10, 2, 10));
        vBox.setPadding(new Insets(10));

    }

    public VBox getListViewAsVBox() {
        return vBox;
    }

}// class
Java:
package guiBooking;

import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import objects.MyNumTextField;
import objects.Var;

public class BPCenterMiddle {

    private Separator sep;
    private Label labelAmount;
    private MyNumTextField tfAmount;

    private final String txtLabelAmount = "Betrag eingeben";

    private VBox vBox;

    public BPCenterMiddle() {
        sep = new Separator();
        labelAmount = new Label(txtLabelAmount);
        tfAmount = new MyNumTextField();
        vBox = new VBox();

        createVBox();
    }

    // for amountfield and its labeling
    private void createVBox() {

        labelAmount.setFont(Var.fontExtraBig);

        tfAmount.setMinSize(110, 28);
        tfAmount.setMaxSize(110, 28);

        sep.setOrientation(Orientation.VERTICAL);
        VBox.setVgrow(sep, Priority.ALWAYS);
        sep.setPadding(new Insets(30, 0, 50, 0)); // Strich unten sieht schöner aus

        vBox.setAlignment(Pos.BASELINE_CENTER);
        VBox.setVgrow(vBox, Priority.ALWAYS);
        vBox.getChildren().addAll(labelAmount, tfAmount, sep);

    }

    public VBox getvBox() {
        return vBox;
    }

}// end class
Java:
package guiBooking;

import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import objects.MyItemList;


public class CreateGUIBooking {

    private Scene scene;
    private BorderPane layout;

    MyItemList itemListIncome; // Einnahmen-Liste
    MyItemList itemListOutgoing; // Ausgaben-Liste
    BPTop bpTop;
    BPCenterMiddle bpCenterMiddle;
    BPBottom bpBottom;

    public CreateGUIBooking() {
        layout = new BorderPane();
        scene = new Scene(layout, 800, 600);

        itemListIncome = new MyItemList("Einnahmen", "+", "-");
        itemListOutgoing = new MyItemList("Ausgaben", "+", "-");

        bpTop = new BPTop();
        bpCenterMiddle = new BPCenterMiddle();
        bpBottom = new BPBottom();

        setPostions();
    }

    private void setPostions() {

        // setup BorderPane TOP
        layout.setTop(bpTop.getvBox());

        // setup BorderPaneCenter
        VBox vBoxincome = itemListIncome.getListViewAsVBox();
        VBox vBoxOutgoing = itemListOutgoing.getListViewAsVBox();

        BPCenterMiddle borderCenter = new BPCenterMiddle();
        VBox vBoxCenter = borderCenter.getvBox();

        HBox hBoxCenter = new HBox();
        hBoxCenter.getChildren().addAll(vBoxincome, vBoxCenter, vBoxOutgoing);

        layout.setCenter(hBoxCenter);

        // setup BorderPane BOTTOM
        layout.setBottom(bpBottom.getHbox());

    }

    public Scene getScene() {
        return scene;
    }

}// end class

Wie gesagt, ich bin für alles dankbar :))
 
dzim

dzim

Würde sagen: Grundsätzlich OK.
Kompliziert wird es jetzt nur mit der GUI-Logik. So wie du es aufgebaut hast, wirst du vermutlich später (erst einmal) viel Logik in die Klassen der, was eher schlecht ist. Beschäftige dich daher als nächstes mal mit Konzepten wie MVC (ist einfacher, reicht mir aber häufig) oder MVVN (ist sauberer und besser zu testen!). Damit dir nicht erst schlechte Angewohnheiten zu eigen werden.
Ich habe am Anfang (wo ich aber schon recht gut mit Java zurecht kam und AWT/Swing und SWT/JFace kannte) erst einmal *alle* GUIs mit FXML gebaut. Ich fand es tatsächlich dort leichter alle Komponenten kennen zu lernen und die deklarative Strukturierung eines XMLs hat mir da sehr geholfen. Im Code hatte ich gerade mit den Grössen und den Positionierungen tatsächlich anfangs auch grössere Probleme. Und IntelliJ hat (jedenfalls in der Ultimate Edition) recht gute Java/JavaFX-Unterstützung für FXMLs.
Erst jetzt, wo ich fast alles mit Kotlin mache, bin ich wieder zurück auf einen Code-First-Ansatz und verwende kaum noch FXMLs.
 
B

BigMemo007

@dzim
danke für deine Antwort. Ich habe meinen Code meiner Meinung nach verbessert. Sieh unten. Werde aber mir MVC und MVVN näher anschauen.

Main-Klasse
Java:
public class RunEinnAusgApp extends Application {
    
    Scene sceneGUIBooking;
    GUIBooking guiBooking;
    
    String titleApp = "Einnahmen-Ausgaben APP";
    
    public RunEinnAusgApp() {
        guiBooking = new GUIBooking();
        sceneGUIBooking = guiBooking.getSceneGUIBooking();
    }
    
    
    @Override
    public void start(Stage primaryStage) {
        try {
            
            sceneGUIBooking.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(sceneGUIBooking);
            primaryStage.setTitle(titleApp);
            primaryStage.show();
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}
Meine Objekte werden hier kreiert:
Java:
public class MyObjects {

    private MyActionHandler myActionHandler;
    
    private DatePicker datePicker;
    private MyNumTextField amountField;
    
    private ListView<String> incomeListView;
    private ListView<String> outgoingsListView;
    
    private Separator separator;
    
    private Label lblDatePicker;
    private Label lblAmountField;
    private Label lblIncome;
    private Label lblOutgoings;
    
    private Button btnRemItemIncome;
    private Button btnAddItemIncome;
    private Button btnRemItemOutgoings;
    private Button btnAddItemOutgoings;
    
    private Button btnAnalyse;
    private Button btnBooking;
    private Button btnEdit;
    
    private int btnWidth;
    private int btnHeight;
    
    private String txtLabDatePicker = "Tag der Buchung";
    private String txtLabAmountField = "Betrag eingeben";
    private String txtLabIncome = "Einnahmen";
    private String txtLabOutgoings = "Ausgaben";
    
    private String txtBtnRemItemIncome = "-";
    private String txtBtnAddItemIncome = "+";
    private String txtBtnRemItemOutgoings = "-";
    private String txtBtnAddItemOutgoings = "+";
    
    private String txtBtnAnalyse = "Auswertung ansehen";
    private String txtBtnBooking = "Buchen";
    private String txtBtnEdit = "Buchungen editiren";
    

    public MyObjects() {
        myActionHandler = new MyActionHandler();
        
        datePicker = new DatePicker();
        amountField = new MyNumTextField();
        
        incomeListView = new ListView<String>();
        outgoingsListView = new ListView<String>();
        
        separator = new Separator();
        
        btnWidth = 100;
        btnHeight = 25;
        
        lblDatePicker = new Label(txtLabDatePicker);
        lblAmountField = new Label(txtLabAmountField);
        lblIncome = new Label(txtLabIncome);
        lblOutgoings = new Label(txtLabOutgoings);
        
        btnRemItemIncome = new Button(txtBtnRemItemIncome);
        btnAddItemIncome = new Button(txtBtnAddItemIncome);
        btnRemItemOutgoings = new Button(txtBtnRemItemOutgoings);
        btnAddItemOutgoings = new Button(txtBtnAddItemOutgoings);
        
        btnAnalyse = new Button(txtBtnAnalyse);
        btnBooking = new Button(txtBtnBooking);
        btnEdit = new Button(txtBtnEdit);
        
        
        setSettings();
        
    }//end construktor

    
    private void setSettings() {
        //datePicker-Settings
        
        
        //amountField-Settings
        amountField.setMinSize(50, 28);
        amountField.setPrefSize(128, 28);
        amountField.setMaxSize(128, 28);
        amountField.setAlignment(Pos.CENTER); //zentriert Cursor
        amountField.setFont(Var.fontBig);
        
        //LiswView-Settings
        VBox.setVgrow(incomeListView, Priority.ALWAYS);     //lässt income VERTIKAL wachsen
        VBox.setVgrow(outgoingsListView, Priority.ALWAYS);  //lässt outgoing VERTIKAL wachsen
        
        //Separator-Settings
        VBox.setMargin(separator,new Insets(30, 0, 50, 0)); //verkleinert Separator
        separator.setOrientation(Orientation.VERTICAL); //setzt Strich Vertikal
        VBox.setVgrow(separator, Priority.ALWAYS);      //Separator wächst VERTIKAL mit
        
    
        //Label-Settings (Fonts)
        lblDatePicker.setFont(Var.fontBig);
        lblAmountField.setFont(Var.fontExtraBig);
        lblIncome.setFont(Var.fontBig);
        lblOutgoings.setFont(Var.fontBig);
        
        //Button-Settings (Fonts, addActionListener)
        HBox.setMargin(btnRemItemIncome, new Insets(0, 30, 0, 0)); //Abstand zum Label lblIncome links
        btnRemItemIncome.setFont(Var.fontSmall);
        btnRemItemIncome.setOnAction(myActionHandler);
        HBox.setMargin(btnAddItemIncome, new Insets(0, 0, 0, 30)); //Abstand zum Label lblIncome rechts
        btnAddItemIncome.setFont(Var.fontSmall);
        btnAddItemIncome.setOnAction(myActionHandler);
        
        HBox.setMargin(btnRemItemOutgoings, new Insets(0, 30, 0, 0)); //Abstand zum Lable lblOutgoings links
        btnRemItemOutgoings.setFont(Var.fontSmall);
        btnRemItemOutgoings.setOnAction(myActionHandler);
        HBox.setMargin(btnAddItemOutgoings, new Insets(0, 0, 0, 30)); //Abstand zum Lable lblOutgoings rechts
        btnAddItemOutgoings.setFont(Var.fontSmall);
        btnAddItemOutgoings.setOnAction(myActionHandler);
        
        btnAnalyse.setMinSize(btnWidth, btnHeight);
        btnAnalyse.setFont(Var.fontSmall);
        btnAnalyse.setOnAction(myActionHandler);
        btnBooking.setMinSize(btnWidth, btnHeight);
        btnBooking.setFont(Var.fontExtraBig);
        btnBooking.setOnAction(myActionHandler);
        btnEdit.setMinSize(btnWidth, btnHeight);
        btnEdit.setFont(Var.fontSmall);
        btnEdit.setOnAction(myActionHandler);
        
    }
    

    public ListView<String> getIncomeListView() {
        return incomeListView;
    }



    public void setIncomeListView(ListView<String> incomeLV) {
        this.incomeListView = incomeLV;
    }



    public ListView<String> getOutgoingsListView() {
        return outgoingsListView;
    }



    public void setOutgoingsListView(ListView<String> outgoingsLV) {
        this.outgoingsListView = outgoingsLV;
    }



    public DatePicker getDatePicker() {
        return datePicker;
    }



    public MyNumTextField getAmountField() {
        return amountField;
    }



    public Label getLblDatePicker() {
        return lblDatePicker;
    }


    public Label getLblAmountField() {
        return lblAmountField;
    }
    

    public Label getLblIncome() {
        return lblIncome;
    }



    public Label getLblOutgoings() {
        return lblOutgoings;
    }



    public Button getBtnRemItemIncome() {
        return btnRemItemIncome;
    }



    public Button getBtnAddItemIncome() {
        return btnAddItemIncome;
    }



    public Button getBtnRemItemOutgoings() {
        return btnRemItemOutgoings;
    }



    public Button getBtnAddItemOutgoings() {
        return btnAddItemOutgoings;
    }



    public Button getBtnAnalyse() {
        return btnAnalyse;
    }



    public Button getBtnBooking() {
        return btnBooking;
    }



    public Button getBtnEdit() {
        return btnEdit;
    }


    public Separator getSeparator() {
        return separator;
    }

}//end class

Die Gui für Bookings wird hier gemacht
Java:
public class GUIBooking {
    
    private BorderPane layout;
    private Scene sceneGUIBooking;
    
    private static MyObjects myObjects;
    
    private VBox vBoxTop;
    private HBox hBoxCenLeftTop;
    private VBox vBoxCenterLeft;
    private HBox hBoxCenRightTop;
    private VBox vBoxCenterRight;
    private VBox vBoxCenterMiddle;
    private HBox hBoxCenter;
    private HBox hBoxBottom;
    
    
    public GUIBooking() {
        layout = new BorderPane();
        sceneGUIBooking = new Scene(layout, 800, 600);
        myObjects = new MyObjects();
        
        vBoxTop = new VBox(0);
        hBoxCenLeftTop = new HBox();
        vBoxCenterLeft = new VBox();
        hBoxCenRightTop = new HBox();
        vBoxCenterRight = new VBox();
        vBoxCenterMiddle = new VBox();
        hBoxCenter = new HBox();
        hBoxBottom = new HBox();
        
        createBoxes();
        setSettings();
        setPositions();
    }
    
    
    public void createBoxes() {
        //for BorderPane-TOP
        vBoxTop.getChildren().addAll(myObjects.getLblDatePicker(), myObjects.getDatePicker());
        
        //for BorderPane-CENTER_LEFT_TOP
        hBoxCenLeftTop.getChildren().addAll(myObjects.getBtnRemItemIncome(),
                myObjects.getLblIncome(),  myObjects.getBtnAddItemIncome());
    
        //for BorderPane-CENTER_LEFT
        vBoxCenterLeft.getChildren().addAll(hBoxCenLeftTop, myObjects.getIncomeListView());
        
        //for BorderPane-CENTER_RIGHT_TOP
        hBoxCenRightTop.getChildren().addAll(myObjects.getBtnRemItemOutgoings(),
                myObjects.getLblOutgoings(), myObjects.getBtnAddItemOutgoings());
        
        //for BorderPane-CENTER_RIGHT
        vBoxCenterRight.getChildren().addAll(hBoxCenRightTop, myObjects.getOutgoingsListView());
        
        //for BorderPane-CENTER_Middle
        vBoxCenterMiddle.getChildren().addAll(myObjects.getLblAmountField(),
                myObjects.getAmountField(), myObjects.getSeparator());

        //for BorderPane-CENTER - merging privious Boxes
        hBoxCenter.getChildren().addAll(vBoxCenterLeft, vBoxCenterMiddle, vBoxCenterRight);       
                
        //for BorderPane-BOTTOM
        hBoxBottom.getChildren().addAll(myObjects.getBtnAnalyse(), Var.mySpace(),
                myObjects.getBtnBooking(), Var.mySpace(), myObjects.getBtnEdit());
                
        
    }//end createBoxes

    private void setSettings() {
        //BorderPane-TOP Content
        BorderPane.setMargin(vBoxTop, new Insets(5, 0, 0, 0)); //setzt Top etwas tiefer
        vBoxTop.setAlignment(Pos.CENTER);
        
        //BorderPane-CENTER Content
        hBoxCenLeftTop.setAlignment(Pos.CENTER);
        hBoxCenRightTop.setAlignment(Pos.CENTER);
        vBoxCenterMiddle.setAlignment(Pos.CENTER);
        
        BorderPane.setMargin(vBoxCenterMiddle, new Insets(0, 10, 0, 10)); //Abstand amountField nach rechts und links
        BorderPane.setMargin(hBoxCenter, new Insets(10)); //Abstand Center zu den Rändern
        
        HBox.setHgrow(vBoxCenterLeft, Priority.ALWAYS);  //lässt income HORIZONTAL mitwachsen
        HBox.setHgrow(vBoxCenterRight, Priority.ALWAYS); //lässt outgoings HORIZONTAL mitwachsen
        
        //BorderPane-BOTTOM Content
        BorderPane.setMargin(hBoxBottom, new Insets(0, 20, 10, 20));
        
    }
    
    
    public void setPositions() {
        //Top
        layout.setTop(vBoxTop);
        
        //Center
        layout.setCenter(hBoxCenter);
        
        //Bottom
        layout.setBottom(hBoxBottom);
    }
    
    
    public Scene getSceneGUIBooking() {
        return sceneGUIBooking;
    }

    
    //consign (übergeben, aushändigen) in static way myObjects to MyActionHandler. Solve problem
    //with identifying the buttons as same objects (now event.getSourche() returns same JVM-adress)
    public static MyObjects getMyObjects() {
        return myObjects;
    }

}//end outer class

Variablen und Konstanten
Java:
public class Var {

    public static final Font fontBig = Font.font("sans-serif", FontWeight.BOLD, 15);
    public static final Font fontSmall = Font.font("sans-serif", FontWeight.BOLD, 12);
    public static final Font fontExtraBig = Font.font("sans-serif", FontWeight.BOLD, 18);

    public static final Label mySpace() {
        Label l = new Label();
        l.setMinWidth(20);
        l.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(l, Priority.ALWAYS);

        return l;

    }

}// end class

Mein ActionEvent
Java:
public class MyActionHandler implements EventHandler<ActionEvent>{
    
    
    @Override
    public void handle(ActionEvent event) {
    
        Object o = event.getSource();
        MyObjects myObjects = GUIBooking.getMyObjects();
        
        if (o == myObjects.getBtnRemItemIncome()) {
            System.out.println("Einnahmen-Eintrag löschen");
            
        } else if (o == myObjects.getBtnAddItemIncome()) {
            System.out.println("Einnahmen-Eintrag hinzufügen");
        
        } else if (o == myObjects.getBtnRemItemOutgoings()) {
            System.out.println("Ausgaben-Eintrag löschen");
            
        } else if (o == myObjects.getBtnAddItemOutgoings()) {
            System.out.println("Ausgaben-Eintrag hinzufügen");
        }
        
        //Buttons im BorderPane.Bottom
        else if (o == myObjects.getBtnAnalyse()) {
            System.out.println("Daten werden analysiert...");
        
        } else if (o == myObjects.getBtnBooking()) {
            System.out.println("Buchung wird vorgenommen...");
            
        } else if (o == myObjects.getBtnEdit()) {
            System.out.println("Buchung editieren.");
        }
        
    
    
    }


}//end class

Mein TextField damit es nur Zahlen und Zahlen mit Komma annimmt
Java:
public class MyNumTextField extends TextField {

     @Override
     public void replaceText(int start, int end, String text) {
         if (text.matches("[0-9]") || text.matches(",") || text == "") {
             super.replaceText(start, end, text);
         }
     }
  
     @Override
     public void replaceSelection(String text) {
         if (text.matches("[0-9]") || text.matches(",") || text == "") {
             super.replaceSelection(text);
         }
     }
    
}
Ist dies schon ein besser lesbarer und verwendbarer Code? Geht dies schon in Richtung MVC?
 
dzim

dzim

Also lesbar ist er schon. Vor allem, da du dir schon mal Mühe gegeben hast, es zu kapseln.

Es geht auch schon in Richtung MVC, nur das statische MyObjects-Konstrukt finde persönlich ich noch etwas unschön.
Besser wäre hier ein echtes Model anzulegen, in dem du den Zustand deiner Anwendung vorhältst. Dieser Zustand muss dann halt als Dependency immer mit überreicht werden (und ja, zur Not könnte es Anfangs auch statisch sein, aber das ist eine Unart, die man leider später schwer los wird – ist mir auch passiert) und der Controller macht updates daran und das UI bindet sich daran.

Les dich erst mal in Ruhe in die Themen MVC/MVVM und Dependency Injection ein. Das sollte dich dann schon etwas voran bringen.
 
Thema: 

Dynamische ListView-Größe, die bei Fenstergrößenänderung sich anpasst

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben