JavaFX: voneinander abhängige TextFields

SteffiBee

Mitglied
Hallo zusammen und ein frohes neues Jahr,

ich brauche Hilfe beim ChangeListener für Textfelder in JavaFX.

Folgender Sachverhalt:

Für einen Teil eines Programmes möchte ich anhand von einem Listenpreis, dem Mehrwertsteuersatz und einem Rabatt auf den Listenpreis den Verkaufspreis mit und ohne Mehrwertsteuer berechnen lassen.
Weiterhin soll die Möglichkeit gegeben sein, entweder einen Verkaufspreis mit oder ohne Mehrwertsteuer anzugeben, woraus sich dann der Rabatt zum Listenpreis errechnet.

Das Prozedere an sich ist kein Problem, die jeweiligen Berechnungen funktionieren auch ohne Weiteres.

Ich habe für die einzelnen Textfelder per addListener(new ChangeListener...)... (siehe Code unten) das EventHandling implementiert.
Funktioniert im Grunde auch, allerdings wird der Text dann so schnell gesetzt, dass nach Eingabe bereits EINER Ziffer sofort in den Dezimalbetrag umgewandelt wird, da ja das EventHandling für die weiteren Textfelder sofort umgesetzt wird. Ein Anwender kann so unmöglich einen vernünftigen Betrag eingeben.
Umgehen kann ich das mit PauseTransition, was auch funktioniert, aber ein flüssiger Programmablauf sieht anders aus. Das ist irgendwie sehr unschön gelöst.
Gibt es weitere Möglichkeiten, das irgendwie umzusetzen?

Bitte jetzt nicht unbedingt auf die Bezeichnungen achten, das Ganze ist erst einmal nur ein grober Entwurf bzw. Test.
Ich habe die erstbesten Bezeichnungen genommen, die mir in den Sinn kamen.

Vielen Dank im Voraus

Java:
[/B]
tfKalkRab1.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                Double vkmit, vkohne, rabatt, lp;

                if (tfListenpreis.getText().isEmpty() || tfKalkRab1.getText().isEmpty()) {
                    tfVKoM1.setText("");
                    return;
                } else {
                    lp = Double.valueOf(tfListenpreis.getText().replace(",", "."));
                    rabatt = Double.valueOf(tfKalkRab1.getText().replace(",", "."));
                    vkohne = lp * ((100 - rabatt) / 100);
                    vkmit = vkohne + (vkohne * Double.valueOf(tfMWST.getText().replace(",", ".")) / 100);
                    pause.setOnFinished(
                            event -> tfVKoM1.setText(String.valueOf(String.format(Locale.ENGLISH, "%1.2f", vkohne))));
                    pause.playFromStart();
                    pause1.setOnFinished(
                            event -> tfVKmM1.setText(String.valueOf(String.format(Locale.ENGLISH, "%1.2f", vkmit))));
                    pause1.playFromStart();
                }
            }
        });

        tfVKoM1.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                Double vkmit, vkohne, rabatt, lp;

                if (tfListenpreis.getText().isEmpty() || tfVKoM1.getText().isEmpty()) {
                    tfKalkRab1.setText("");
                    return;
                } else {
                    vkohne = Double.valueOf(tfVKoM1.getText().replace(",", "."));
                    lp = Double.valueOf(tfListenpreis.getText().replace(",", "."));
                    rabatt = Double.parseDouble(String.format(Locale.ENGLISH, "%1.2f", (vkohne / lp - 1) * (-1) * 100));
                    vkmit = vkohne + (vkohne * Double.valueOf(tfMWST.getText().replace(",", ".")) / 100);
                    pause2.setOnFinished(event -> tfKalkRab1.setText(String.valueOf(rabatt)));
                    pause2.playFromStart();
                    pause3.setOnFinished(
                            event -> tfVKmM1.setText(String.valueOf(String.format(Locale.ENGLISH, "%1.2f", vkmit))));
                    pause3.playFromStart();
                }
            }
        });

        tfVKmM1.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {

                Double vkmit, vkohne, rabatt, lp;

                if (tfListenpreis.getText().isEmpty() || tfVKmM1.getText().isEmpty()) {
                    tfKalkRab1.setText("");
                    return;
                } else {
                    vkmit = Double.valueOf(tfVKmM1.getText().replace(",", "."));
                    lp = Double.valueOf(tfListenpreis.getText().replace(",", "."));
                    vkohne = vkmit / (Double.valueOf(tfMWST.getText().replace(",", ".")) / 100 + 1);
                    rabatt = Double.parseDouble(String.format(Locale.ENGLISH, "%1.2f", (vkohne / lp - 1) * (-1) * 100));
                    pause4.setOnFinished(event -> tfKalkRab1.setText(String.valueOf(rabatt)));
                    pause4.playFromStart();
                    pause5.setOnFinished(
                            event -> tfVKoM1.setText(String.valueOf(String.format(Locale.ENGLISH, "%1.2f", vkohne))));
                    pause5.playFromStart();
                }
            }
        });
[B]
 
M

Mart

Gast
1. textfeld hat ein action event ( enter drücken ) und dann löst du den eventhandler aus oder irgendwie anders den handler verpacken
2. in dem CHangelistener baust du ein if ein .. ( if (betrag==langGenug ) berechne )

nur deine problematik ist du versuchst einen apfel mit birnen zu bauen
du sagst selber "wenn der user betrag eingegeben HAT" in java übersetzt => wenn event passiert ist => event -> kalkuliere
du willst die berechnung aber mit etwas das permanent läuft also "wenn der user betrag eingibt" aber den Fall hast du gar nicht

deswegen finde ich deine problematik nur so halb da du einerseits das eine willst und anderer seits das andere aber beides passt nicht zusammen
 

SteffiBee

Mitglied
Hey, danke für Deine Antwort.
Also zu Punkt 2: Das halte ich für nicht so geeignet, da ein Anwender evtl. nur 5 statt 5,00 eingeben könnte.
Dann würde das Event in dem Fall gar nicht ausgelöst werden.

Wie würde ich Punkt 1 umsetzen können?
Was Du meinst, ist mir klar, dass also das Event erst ausgelöst wird, wenn der Betrag eingegeben UND Enter gedrückt wird.
Mir ist gerade nur nicht ganz bewusst, ob das dann immer noch in Verbindung mit dem Listener funktioniert oder der Listener
ganz rausgenommen wird und die Berechnungen dann nur durchgeführt werden, wenn die Enter-Taste gedrückt wird?
 
M

Mart

Gast
also 1. warum du keine Listener Brauchst und ich das feststellen kann dass du keinen listener brauchst
1. du benutzt nie oldValue oder observable
2. du willst nicht dass es immer ausgeführt wird

du musst es halt dann ausführen wenn du es willst
die listener brauchst du halt dann eig gar nicht mehr ( den inhalt der Listener stoppfst du in die Handler)

deine TextFelder haben "standardMäßig" das onaction attribut auf enter gesetzt aber du hast ja auch noch deine anderen 90 events die du setzen kannst das onaction war nur ein beispiel
 
M

Mart

Gast
onkeypressed( key.ENTER ) ist beim textfeld gleich onAction ... beim button ist es onMousePRessed.. das ist halt so standardmäßig eingestellt aber es ist prinzipiell wurscht auf welchem event du es machst
 
M

Mart

Gast
außerdem solltest du deine Methoden mal umbauen da sie sich nur gering unterscheiden und jedes mal fast der selbe code da steht
 

SteffiBee

Mitglied
Ja, das habe ich auch schon überlegt.
Habe das Problem noch an anderer Stelle.
Weiß aber nicht wie, da die Methoden an wenigen Stellen eben doch nicht identisch sind.
Das Hauptproblem habe ich mit den jeweiligen Namen für die Textfelder. Wie soll ich die ansprechen, wenn sie sich in einer Methode befinden, die allgemein gültig sein soll.
 
M

Mart

Gast
Java:
public void addListener(TextField textFeld){
    textFeld.onActionProperty().set(event -> ... )
}
 
M

Mart

Gast
Das ist mal ne Idee 👍😍. Das sollte ja dann auch mit denen funktionieren, die ich zusätzlich innerhalb der Methode brauche, oder?
natürlich, ich hab meine "Bibliothek" bzw "Frontend Framework" für javafx so aufgebaut somit alles nur noch über properties geht :)
( ja das flexen musste jetzt sein :D )

würde ich es in "clean" machen also mit meinem framework ( jetzt nicht mit den annotationen weil die hast du ja nich )

hätte ich die View klasse
Java:
class View{
    TextField text = new TextField("bob");
 
    public StringProperty getTextProperty(){
        return text.textProperty();
    }
public ObjectProperty<Action> textActionProperty(){
return text.onactionProperty();
}
}
die Controller Klasse


Java:
class Controller{
    private View view = new View();
    private StringProperty textProperty = new SimpleStringProperty();
    private Objectproperty<Action> actionProperty = new SimpleObjectProperty();
    public Controller(){
        makeBindings();
        actionProperty.set(DEIN EVENT HANDLER);
    }
    private makeBindings(){
        view.getTextProperty().bind(textProperty);
        view.getActionProperty().bind(actionProperty);
    }
    
    EventHandler DEIN EVENT HANDLER (
textProperty.set("Hallo Bob");
);
}
in meinem Framework musst du die makeBIndings() mehtode nicht buaen aber ist ja wurscht.. was fällt auf?
es ist plötzlich komplett egal welcher node da ist .. der komplette View aufbau ist egal geworden .. der Controller bietet die Propertys an und die View kann sie sich nehmen wie sie gerade lustig ist es ist egal ob es eine Textarea oder Textfeld oder ein button ist .. oder ob die TextProperty und action property überhaupt die gleichen nodes sind

zusätzlich dein Controller ist unabhängig von der View zb
ich mach ne neue view nur mit nem button um den Eventhandler auszuprobieren
gut ok dann erstell ich die anderen "get" methoden und returne null immer ( bei mir würde es weg fallen .. deswegen hatte ich es auch geschrieben :D )
somit kannst du einen mini teil deines controllers testen bzw sofort die View austauschen ist komplett irrelevant da die view nach der "friss und stirb" mehtode sachen vom controller anschaut, der Controller funktioniert auch komplett ohne view witzigerweise da zb der Eventhandler die Property im Controller benutzt und nicht die von der View, dass die View sich daran bindet ist irrelevant für den Controller ( bzw den Methoden innerhalb des Controllers )

das model ist noch ne extra geschichte aber die sollte jetzt erstmal tot geschwiegen werden :D

du kannst aber auch mit fxml anfangen ( was ich persönlich hasse aus vielen gründen .. ) aber da bin ich der falsche ansprechpartner ich bin eher für javafx in purem code
EDIT: deine berechnung würden ins Model kommen
PS: egal was du nimmst.. somit verhinderst du ganz einfach solche spaghetti code katastrophen listener ;)
 
Zuletzt bearbeitet von einem Moderator:

SteffiBee

Mitglied
So in der Art, hatte ich es gedacht, um alles etwas unabhängiger und übersichtlicher zu halten. Hab es aber bisher nicht hinbekommen. Tausend Dank. Werde es mit dem Ansatz nochmal versuchen.
Fxml fand ich jetzt auch nicht so verkehrt. Es ist ähnlich zu Android-Entwicklungen, und da hab ich schon das ein oder andere gemacht. Aber eben nur ähnlich.
Habe noch nicht die richtige Motivation gefunden, dass hier umzusetzen. Als Anfänger bin ich froh, dass überhaupt schon etwas funktioniert 😪
 
M

Mart

Gast
Mein Ansatz benutzt halt die PRopertys bis zum maximum
bei fxml hat mich schon mal eine Sache gestört
es ist aber unwichtig dass es ein label ist und warum solls den controller interessieren worauf der eventhandler oder die TextProperty gelegt wird .. eig gar nicht
 
M

Mart

Gast
wenn du die grafik , das verhalten der grafik und die berechnungen trennst ist es immer übersichtlich

Mein ansatz "eliminiert" die abhängigkeit davon was Für ein Node es ist weil ich es trenne das ist halt ein vorteil von meinem aber irgendeinen tod stirbst du immer beim programmieren
 
M

Mart

Gast
models( beinhalten Geschäftslogik also Berechnungen ) sind übrigens Komplett unabhängig von allem es sind "allgemein" gesehen records dh nach einer berechnung oder methode ist das model im gleichen zustand wie davor
 
M

Mart

Gast
ich musste da auch durch bis ich soweit war dass ich mein eignes system bauen konnte und das hab ich dann sogar auch umgesetzt

es ist halt katastrophal dass es fast keine Tutorials gibt wie man in javafx ohne fxml ein mvc pattern bzw irgendein pattern umsetzen kann
 
M

Mart

Gast
um dir mal ein beispiel wie ich mvc umsetze zu zeigen : ( du hast halt die klassen net was blöd ist )

[CODE lang="java" title="View hat nur Nodes und gibt propertys her"]public class LoginView extends RapidSimpleView<BorderPane>
{
private Button loginButton = new Button("Login");
private Label user = new Label("UserName"), password = new Label("Password");
private TextField userLogin = new TextField(),userPassword = new TextField();
private RMessage<Account> message;
private HBox userBox = new HBox(user,userLogin);
private HBox passwordBox = new HBox(password,userPassword);
private VBox logBox = new VBox(userBox,passwordBox,loginButton);
private StringProperty userNameProperty = userLogin.textProperty() , passwordProperty = userPassword.textProperty();
@RapidFXcontroller
private ObjectProperty<EventHandler<javafx.event.ActionEvent>> loginRequestHandler = loginButton.onActionProperty();
public LoginView() {
message = new RMessage<>();
message.addContent(Account.NAME, userNameProperty);
message.addContent(Account.PASSWORD, passwordProperty);
root = new BorderPane();
root.setCenter(logBox);
}
public RMessage<Account> getLoginMessage() {
return message;
}
}[/CODE]

[CODE lang="java" title="im model wird dann halt server zeug / berechnung durchgeführt"]public class LoginModel extends RapidSimpleModel
{
private final RMessage<Account> message;
public LoginModel(RMessage<Account> message) {
this.message = message;
}
public boolean login() {
System.out.println(message.getContent(Account.NAME));
System.out.println(message.getContent(Account.PASSWORD));
return true;
}
}[/CODE]

[CODE lang="java" title="verbindet den Ganzen kram und bietet handler / properties an für die view"]public class Login extends RapidSimpleController<LoginView,LoginModel>
{
public Login() {
view = RapidFX.create(LoginView::new);
model = new LoginModel(view.getLoginMessage());
rapidFXMe();
}
private EventHandler<?> loginRequestHandler = event ->
{
model.login();
};
}[/CODE]
wo @RController steht heißt das wird mit dem Controller verbunden

die aufteilung sollte halt dargestellt werden da bei dir die extends sachen und annotationen nicht funktionieren

um die View unabhängigkeit und controller unabhängigkeit zu gewährleisten könnte dine Controller einfach die Handler und propertys an die View übergeben ob die View damit was macht ist egal

der eventhandler funktioniert auf alles und jeden egal mit was ;)
 
Zuletzt bearbeitet von einem Moderator:

SteffiBee

Mitglied
Auf den ersten Blick für mich noch etwas undurchsichtig 🤣.
Versuche, das mal in nem Mini Projekt.
In der Praxis wird mir das meistens schneller klar.
 
M

Mart

Gast
du hast ja die ganzen klassen nicht die ich habe , ich wollte dir nur eine Grobe unterteilung zeigen wie man so ein mvc aufteilen KANN ... es gibt mvp mvvm mvc und was weis ich noch alles wie man das noch aufbauen kann
 

SteffiBee

Mitglied
Hallo,

das mit der Auslagerung der Methoden funktioniert super.
Danke dafür. Der Code ist erheblich geschrumpft :).
Jetzt stehe ich vor dem nächsten Problem, vielleicht hast Du dafür auch eine Lösung, wäre super.

Ich erzeuge beim Programmstart eine ArrayList mit ChoiceBoxen (ArrayList Name: alCB).
Diese ChoiceBoxen enthalten jeweils alle aus der Datenbank gezogenen Lieferanten
(per toString Methode wird nur der Kurzname des Lieferanten angezeigt).
Das funktioniert auch alles.

Die erste ChoiceBox aus der ArrayList wird beim Programmstart in das GridPane eingefügt.
Die weiteren können per Buttonklick auf Wunsch zugefügt werden (maximal 10).
Die jeweilige ChoiceBox hole ich mir jeweils mit alCB.get(counter). Beginnend bei 0 für die erste ChoiceBox. Der Counter wird nach jeder Erzeugung
hochgezählt. Auch nach der ersten Erzeugung beim Programmstart.

Wählt man jetzt einen Artikel aus, soll der erste zugehörige Lieferant (es gibt mehrere, die auch jeweils in eine ArrayList gepackt werden, geholt werden diese ebenfalls aus der DB), in die erste ChoiceBox gepackt werden.
alCB.get(0).setValue(arrayLF.get(0));

Alles funktioniert, ich habe mir jeweilige Werte auf der Konsole ausgeben lassen.
System.out.println(alCB.get(0).getValue()) gibt mir den gewünschten Lieferanten.

alCB.get(0) ist auch die ChoiceBox, die beim Programmstart in das GridPane gepackt werden.

Das einzige Problem:
Die ChoiceBox zeigt den Wert nicht an.
Angeblich lässt sich so aber auf ChoiceBoxen, die dynamisch während der Laufzeit aus einer ArrayList erzeugt werden, zugreifen.
Aber irgendwie funktoniert das nicht.

Die zugehörigen Methoden sind wie folgt:

Erzeugung des/der ArrayLists (die anderen sind erstmal unerheblich):

Java:
[/B]
public void generateLFArrays() {
         alCB = new ArrayList<ChoiceBox<Lieferant>>();
         tfLLP = new ArrayList<TextField>();
         tfLEK = new ArrayList<TextField>();
         tfLRab = new ArrayList<TextField>();
         tfLaktuell = new ArrayList<TextField>();
         btnLakt = new ArrayList<Button>();
         
         for (int i=0; i<=9; i++) {
             alCB.add(new ChoiceBox<Lieferant>());
             tfLLP.add(new TextField());
             tfLEK.add(new TextField());
             tfLRab.add(new TextField());
             tfLaktuell.add(new TextField());
             btnLakt.add(new Button("aktualisieren"));
         }
     }
[B]

Lieferanten zufügen:

Java:
[/B]
public void addLieferant() {
     
     gpPreise.add(alCB.get(lfCounter), 0, rowLF);
     gpPreise.add(tfLLP.get(lfCounter), 1, rowLF); 
     gpPreise.add(tfLEK.get(lfCounter), 2, rowLF);
     gpPreise.add(tfLRab.get(lfCounter), 3, rowLF);
     gpPreise.add(btnLakt.get(lfCounter), 4, rowLF);
     gpPreise.add(tfLaktuell.get(lfCounter), 5, rowLF);
     alCB.get(lfCounter).setPrefWidth(150);
     alCB.get(lfCounter).setMaxWidth(150);
     alCB.get(lfCounter).getItems().addAll(fillLieferanten());
     lfCounter++;
     rowLF++;
     }
[B]

Ausschnitt aus dem Programmablauf:

Java:
[/B]
addLieferant();
// ....
arrayKON = db.getKonditionen(tfArtikelnummer.getText());
                        
                        if (!arrayKON.isEmpty()) {
                            
                            arrayLF.addAll(fillLieferanten());
                            
                            System.out.println(arrayLF.get(0).getKurzname());      // -----> gibt den erwarteten Lieferanten aus
                            System.out.println(arrayKON.get(0).getLieferant());   // -----> gibt den erwarteten Lieferanten aus
                            
                            alCB.get(0).setValue(arrayLF.get(0));        // ----> der gesetzte Wert wird in der ChoiceBox im GridPane nicht angezeigt
                            System.out.println(alCB.get(0).getValue());            // -----> gibt den erwarteten Lieferanten aus
                        }
[B]

Woran kann das liegen?

Alles funktioniert wie gewünscht, nur die Methode setValue() auf die gewünschte ChoiceBox nicht.

Danke schonmal im Voraus.
 
M

Mart

Gast
um ehrlich zu sein versteh ich deinen Code hinten und vorne nicht
Java:
public void generateLFArrays() {
         alCB = new ArrayList<ChoiceBox<Lieferant>>();
         tfLLP = new ArrayList<TextField>();
         tfLEK = new ArrayList<TextField>();
         tfLRab = new ArrayList<TextField>();
         tfLaktuell = new ArrayList<TextField>();
         btnLakt = new ArrayList<Button>();
      
         for (int i=0; i<=9; i++) {
             alCB.add(new ChoiceBox<Lieferant>());
             tfLLP.add(new TextField());
             tfLEK.add(new TextField());
             tfLRab.add(new TextField());
             tfLaktuell.add(new TextField());
             btnLakt.add(new Button("aktualisieren"));
         }
     }
das schaut sehr nahc einer eigenen klasse aus... wo die attribute die 6 arraylists sind und in der for schleife erzeugst du einfach 10 von den Objekten
das wäre sinnvolleer und einfacher zu lesen ... wesentlich einfacher
Java:
public void addLieferant() {
  
     gpPreise.add(alCB.get(lfCounter), 0, rowLF);
     gpPreise.add(tfLLP.get(lfCounter), 1, rowLF);
     gpPreise.add(tfLEK.get(lfCounter), 2, rowLF);
     gpPreise.add(tfLRab.get(lfCounter), 3, rowLF);
     gpPreise.add(btnLakt.get(lfCounter), 4, rowLF);
     gpPreise.add(tfLaktuell.get(lfCounter), 5, rowLF);
     alCB.get(lfCounter).setPrefWidth(150);
     alCB.get(lfCounter).setMaxWidth(150);
     alCB.get(lfCounter).getItems().addAll(fillLieferanten());
     lfCounter++;
     rowLF++;
     }
die abkürzungen machen es unlesbar und du hast GUI und logik gemischt ich weis nicht was du machst...

mach vllt erstmal aufräumen

im model vllt mal diese methode , diese Liefert dir lieferanten objekte ... und wenn im Lieferant nur der Name drin steht also Klasse mit nur 1em String... das ist egal weils lesbar und erweiterbar ist
Java:
Lieferant[] getLieferanten(){
    db.query ....
    return lieferantenArray;
}
Java:
public class Lieferant{
    String name;
    public Lieferant( String name )
    {
        this.name = name;
    }
    getter noch
}
hier sollte kein setter sein weils eig ein record ist

in der view hast du deine VBox wo deine 100 arrays gefühlt rein kommen nur das ist so verwirrend dass man sich nicht auskennt...
Java:
view{
    VBox angebotBox = new VBox();
  
    ObservableList<Node> getBoxChildren(){
        return angebottBox.getChildren();
    }
}
in der Liste willst du ja deine Lieferanten hinzufügen mit ?Textfeldern?

dann kannst du ja in deinem Controller das aufrufen
Java:
makeOfferEntry(){
    ObservableList<Node> childrenList = view.getBoxChildren()
        for( Lieferant lieferant : model.getLieferanten()){
            childrenList.add(new LieferantenEintrag(lieferant.getName().getPane());
        }
}
der LieferantenEintrag wäre wieder eine Klasse der entspricht dann einer ?Reihe? ist ansich das was du in der schleife versuchst zu fabrizieren

getPane sollte dir die HBox der elemente liefern dass du nicht von der Box erbst da LieferantenEintrag nicht in die Vererbung rien passt deswegen delegation bevorzugen


wenn du das hast wird dein Controller nicht mehr überschwemmt werden... du hast jetzt gefühlt 10 klassen in eine Gepackt und da kenn ich mich nicht mehr aus.. ich habe 0 plan was überhaupt das setValue machen sollte ... oder was es setten sollte

ins blinde reingeraten vllt https://stackoverflow.com/questions...-choicebox-value-when-using-a-list-of-objects ??



ich würde wetten dass du die lösung selber findest wenn du eine Struktur hättest weil an dieser die Meisten beginner scheitern aber glücksspiel kann süchtig machen :D
 
Zuletzt bearbeitet von einem Moderator:

SteffiBee

Mitglied
Ja, sorry, hab halt nur die Code-Schnipsel reingepackt, von denen ich dachte, dass sie wichtig sind.

Zum einen habe ich eine eigene Klasse bzw Paket für das Datenbank-Management.
Da sind auch auch die Abfragen drin, wie getLieferanten(), getKonditionen() etc.

Ein weiteres Pakte enthält das Fachkonzept, mit Klassen wie
Lieferant, Kondition, Artikel, Kunde etc.

Ein drittes Paket enthält sämtliche Views, also die GUI komplett.
Allerdings habe ich halt noch einiges, was wahrscheinlich ins Fachkonzept gehört.
Versuche gerade noch aufzuräumen... also sorry dafür.

Vielleicht kurz zum Sachverhalt.
Ich kann in der ArtikelView einen Artikel suchen, dieser wird in der Datenbank abgefragt und in der View angezeigt.
Für einen Artikel gibt es mehrere Lieferanten bzw Konditionen. Die Anzahl ist je Artikel unterschiedlich.
Jeder Lieferant hat für jeden Artikel unterschiedliche Konditionen.
Eine Kondition setzt sich zusammen aus einem Lieferanten, einem Listenpreis, einen Einkaufspreis und dem daraus errechneten Rabatt, zusätzlich gehört zu einer Kondition noch ein Datum, wann es das letzte Mal aktualisiert wurde.

In der Datenbank gibt es dafür eigene Tabellen.
Eine für Artikel, eine für Lieferanten, eine für Konditionen....

In der GUI sieht das so aus (für jeweils einen Artikel).

1. Lieferant Listenpreis Einkaufspreis Rabatt aktualisieren Datum aktualisiert
(ChoiceBox) (TextField) (TextField) (TextField) (Button) (TextField)

2. Lieferant usw.....

Zusätzlich gibt es einen Button, mit dem man eine zusätzliche "Zeile" für eine Kondition(Lieferanten) zufügen kann.

Damit diese Zeile bei Button Klick zugefügt wird, habe ich eben zunächst ArrayLists mit jeweils 10 Objekten erstellt.
Ich habe vor dem Kram mit den Arrays diese 10 Zeilen statisch schon beim Programmstart erstellen lassen.
Da hat auch bei Aufruf eines Artikels die Befüllung der gesamten Zeilen für die Konditionen funktioniert.
Ich finde das aber überflüssig, da ein Artikel manchmal nur eine Kondition(Lieferanten) hat.
Dann sind die weiteren 9 Zeilen einfach zu viel.
Daher sollen diese nur erstellt werden, wenn sie benötigt werden.
Ich mache das auch gerne auf eine andere Art als mit ArrayLists. Mir fällt aber keine ein.
 
M

Mart

Gast
Ich mache das auch gerne auf eine andere Art als mit ArrayLists. Mir fällt aber keine ein.
ok also um es mal so zu sagen du hast eine Datenbank anbindung die funktioniert das ist schon mal gut :D

jetzt hast du das Problem das was von der DB kommt passt dir nicht

du solltest erstmal FESTLEGEN was kommen soll von der DB .. erst wenn du daten hast kannst du sie anzeigen ( zuerst logik dann ansicht )

schreib mal die Lieferanten klasse also den Record , deine db anbindung liefert dir dann eine Arrayliste mit den Lieferanten

wenn du das hast kannst du in deinem controller for ( Lieferant : model.getLieferanten() ) also eine foreach shcleife dir die Reihen erstellen lassen auf basis der anzahl der Lieferanten = keine überlfüssigen zeilen aber das grundprinzip hab ich oben schon geschrieben... ich hab seit fast 1 jahr in meiner gui keine for int i = 0... schleife mehr geschrieben , in der View und im controller reicht ( normalerweise die foreach schleife)
 

SteffiBee

Mitglied
Er holt mir das aus der Datenbank, was ich brauche, das habe ich vorher schon mit den beim Programmstart erstellen ChoiceBoxen und TextFeldern ausprobiert.

Es seit ich versuche, die dynamisch erstellten ChoiceBoxen und TextFelder zu füllen, funktioniert es nicht.

Java:
public ArrayList<Kondition> getKonditionen(String nummer) {
        ArrayList<Kondition> konditionen = new ArrayList<Kondition>();
        String abfrage = "SELECT * FROM konditionen WHERE a_nummer="+nummer+";";
        Statement stm;
        ResultSet rs;
        try {
            stm = conn.createStatement();
            rs = stm.executeQuery(abfrage);
            
            while (rs.next()) {
                konditionen.add(new Kondition(rs.getInt(2), rs.getString(3), rs.getInt(4), rs.getDouble(5), 
                        rs.getDouble(6), rs.getDouble(7), rs.getDate(8).toLocalDate()));
            }
            
        } catch (SQLException e) {
            System.out.print("Konditionen konnten nicht gelesen werden ");
            e.printStackTrace();
        }
        return konditionen;
    }


Das funktioniert, habe mir das Ergebnis auf der Konsole ausgeben lassen.
 
M

Mart

Gast
Java:
public ArrayList<Kondition> getKonditionen(String nummer) {
        ArrayList<Kondition> konditionen = new ArrayList<Kondition>();
        String abfrage = "SELECT * FROM konditionen WHERE a_nummer="+nummer+";";
        Statement stm;
        ResultSet rs;
        try {
            stm = conn.createStatement();
            rs = stm.executeQuery(abfrage);
           
            while (rs.next()) {
                konditionen.add(new Kondition(rs.getInt(2), rs.getString(3), rs.getInt(4), rs.getDouble(5),
                        rs.getDouble(6), rs.getDouble(7), rs.getDate(8).toLocalDate()));
            }
           
        } catch (SQLException e) {
            System.out.print("Konditionen konnten nicht gelesen werden ");
            e.printStackTrace();
        }
        return konditionen;
    }
1. System.err.print ... wäre besser und noch besser eine runtimeException zu werfen
2. du hast deine Kondition klasse wo die daten drinstehen pro reihe dh im controller hast du diese Methode
Java:
void createConditionEntry(){
    for ( var kondition : model.getKondiditionen ( irgendwo.getNummer() ){
        view.getChildren.add(new KonditionsEintrag(kondition).getRootPane());
    }
}
der Konditions Eintrag ist halt für die Eine reihe verantwortlich das richtig zusammen zu bauen... ist halt dann ein neues mvc paket.. heißt ja nicht dass du alles in ein mvc paket packen musst
 
M

Mart

Gast
hast du discord, ich denke da wäre es leichter umzusetzen, wenn du willst kannst du mir deinen Discord acc über eine Private nachricht schicken
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Columns unabhängig voneinander mit Daten füllen JavaFx AWT, Swing, JavaFX & SWT 1
Juelin Javafx hängt sich auf AWT, Swing, JavaFX & SWT 31
Juelin StringGrid in SceneBuilder und javaFX AWT, Swing, JavaFX & SWT 2
Juelin starten maven javafx programm ohne netbeans AWT, Swing, JavaFX & SWT 38
Juelin javax.swing in javafx AWT, Swing, JavaFX & SWT 1
MiMa JUnit5 im JavaFX Projekt AWT, Swing, JavaFX & SWT 2
Juelin in javafx Event auslösen AWT, Swing, JavaFX & SWT 4
MiMa Fonts, Icons, Bilder in JavaFX Anwendung AWT, Swing, JavaFX & SWT 5
MiMa SwingFXUtils in JavaFX 20 AWT, Swing, JavaFX & SWT 6
MiMa JavaFX Fenstertitel zu klein. AWT, Swing, JavaFX & SWT 1
MiMa JavaFX JAR unter Windows ausführen schlägt fehl? AWT, Swing, JavaFX & SWT 5
I JavaFX JavaFx-Anwendung für die Erstellung einer Windows-Anwendung? AWT, Swing, JavaFX & SWT 6
Hatsi09 Javafx MediaPlayer spielt nicht immer AWT, Swing, JavaFX & SWT 3
Hatsi09 Javafx Neuladen von ImageView und MediaView AWT, Swing, JavaFX & SWT 3
Maxim6394 JavaFX Umlaute in JavaFX GUI AWT, Swing, JavaFX & SWT 12
Maxim6394 JavaFX Scene Builder - Crash bei eigener Komponente AWT, Swing, JavaFX & SWT 2
Ernesto95 JavaFX JavaFX GUI mit sehr vielen Update requests AWT, Swing, JavaFX & SWT 4
Telisti Javafx Image wird nicht richtig integiert AWT, Swing, JavaFX & SWT 8
J Netbeans die JavaFX-Anwendung wird nicht ausgeführt AWT, Swing, JavaFX & SWT 16
MartinNeuerlich Kann mir jemand, der einen Mac mit einem m1 oder m2-Chip hat, eine POM geben mit der Javafx-Fullscreen beim Mac mit m-Chip funktioniert? AWT, Swing, JavaFX & SWT 1
tommybalbor JavaFx Anwendung klappt nicht für macOs Nutzern, wenn ich zwei dependecies bei maven hinzufüge AWT, Swing, JavaFX & SWT 6
JavaSchmecktLecker JavaFX JavaFX Ordner automatisch verlinken AWT, Swing, JavaFX & SWT 2
melaniemueller Taschenrechner JavaFX AWT, Swing, JavaFX & SWT 4
R auto. Importanweisungen für javafx funktioniert in Eclipse nicht mehr AWT, Swing, JavaFX & SWT 4
thor_norsk JavaFX Anwendung stürzt ab AWT, Swing, JavaFX & SWT 4
berserkerdq2 Skalieren sich javafx objekte automatisch auf die Bildschirmgröße AWT, Swing, JavaFX & SWT 6
berserkerdq2 Wie füge ich ein Bild in javafx mit dem Scenebuilder ein, das automatisch mitgezogen wird, wenn das Fenster vergrößert wird oder Vollbildmodus AWT, Swing, JavaFX & SWT 6
B Java Projekt mit JavaFX und jfoenix ausführbar machen AWT, Swing, JavaFX & SWT 46
H JavaFX wie JavaFX Projekt aufsetzen? AWT, Swing, JavaFX & SWT 10
thor_norsk JavaFX - Grafikkarte AWT, Swing, JavaFX & SWT 7
MiHimbert Rückmeldung an den aufrufenden JAVAFX-Dialog AWT, Swing, JavaFX & SWT 1
MiMa JavaFX Runtime components are Missing??? AWT, Swing, JavaFX & SWT 3
J JavaFx PDF in einem Element in einem Fenster anzeigen. AWT, Swing, JavaFX & SWT 11
B JavaFX Sprachumschaltung mit Button auf der HMI AWT, Swing, JavaFX & SWT 6
H JavaFX Fehlende JavaFX Package AWT, Swing, JavaFX & SWT 10
K JavaFX unterschiedliche (mehrere Fenster) in seperater Main Methode AWT, Swing, JavaFX & SWT 26
_user_q Kann man ein 2. JavaFX-Fenster auch beenden (exit) statt schließen (close) lassen? AWT, Swing, JavaFX & SWT 8
G JavaFX Line Chart mit Farbverlauf/Gradient in Linie AWT, Swing, JavaFX & SWT 1
thor_norsk JavaFX, FXML und SceneBuilder AWT, Swing, JavaFX & SWT 6
_user_q Über installDist exportiertes Programm wirft "Unsupported JavaFX configuration" AWT, Swing, JavaFX & SWT 0
CodingBerlin JavaFX Programm läuft nur unter Eclipse AWT, Swing, JavaFX & SWT 1
H Fehler: Zum Ausführen dieser Anwendung benötigte JavaFX-Runtime-Komponenten fehlen AWT, Swing, JavaFX & SWT 44
temi JavaFX "Frames" in JavaFx - passende Komponente? AWT, Swing, JavaFX & SWT 13
G JavaFX Steuerung bzw. Test von externer JavaFX Anwendung (liegt nur als jar vor) AWT, Swing, JavaFX & SWT 9
_user_q [JavaFX] Spinner so einstellen, dass er nicht leer bleiben darf? AWT, Swing, JavaFX & SWT 6
S Javafx getResource-Pfad wird nicht erkannt AWT, Swing, JavaFX & SWT 7
A JavaFX exportierte Jar ohne beim starten die Libs hinzufügen? AWT, Swing, JavaFX & SWT 2
J JavaFX Schiffe versenken mit JavaFX und Scene builder AWT, Swing, JavaFX & SWT 3
Encera ArrayList mit eigenen Objekten in JavaFX sortieren und ausgeben AWT, Swing, JavaFX & SWT 50
L JavaFx Textformatierung mittels Datenbank und Funktion anpassen AWT, Swing, JavaFX & SWT 5
sserio Wie funktioniert ein Controller bei JavaFx? AWT, Swing, JavaFX & SWT 1
sserio Kann man bei JavaFx ein Fenster aufkommen lassen? AWT, Swing, JavaFX & SWT 1
Jose05 JavaFx Fxml: GUI aus einer anderen Klasse starten AWT, Swing, JavaFX & SWT 1
Tassos JavaFX/Problem mit der Maussteuerung in Stackpane AWT, Swing, JavaFX & SWT 7
S Ich bringe Code mit JavaFX unter Apache NetBeans IDE 12.6 nicht zum laufen. AWT, Swing, JavaFX & SWT 14
K Bekomme (u.a) javafx.fxml.LoadException trotz "korrektem" Code AWT, Swing, JavaFX & SWT 8
M Gluon will JavaFX in den Browser stecken AWT, Swing, JavaFX & SWT 0
H javafx application does not exist AWT, Swing, JavaFX & SWT 16
A JavaFX Controller Problem AWT, Swing, JavaFX & SWT 1
izoards JavaFX TableView mit Array Inhalt füllen AWT, Swing, JavaFX & SWT 1
M Javafx versuch Bibliothek zu erstellen AWT, Swing, JavaFX & SWT 0
N JavaFX Javafx intelij Projekt zu ausführbaren jar Datei Machen AWT, Swing, JavaFX & SWT 1
K JavaFx, Sound Aufnahme und Thread AWT, Swing, JavaFX & SWT 0
izoards JavaFX TextFlow - Sonderzeichen AWT, Swing, JavaFX & SWT 1
maximstein JavaFX WebView - java.lang.NoSuchMethodError: 'boolean com.sun.prism.ResourceFactory.isDisposed()' AWT, Swing, JavaFX & SWT 4
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
MiHimbert javaFX openfx (17) datepicker AWT, Swing, JavaFX & SWT 3
A Mit JavaFX einzelne Zeilen in TableView farbig markieren AWT, Swing, JavaFX & SWT 5
melaniemueller JavaFX Taschenrechner mit SceneBuilder AWT, Swing, JavaFX & SWT 12
Jose05 Javafx Label Höhe=Breite AWT, Swing, JavaFX & SWT 1
Jose05 JavaFX: eigene FXML-Datei für einen Button AWT, Swing, JavaFX & SWT 3
izoards JavaFX editierbare Tabelle AWT, Swing, JavaFX & SWT 4
N javafx Position der Bustaben finden label AWT, Swing, JavaFX & SWT 1
D Verschieden Scenen ansprechen mit dem Scene Builder und JavaFX (Eclipse) AWT, Swing, JavaFX & SWT 16
izoards JavaFX Background Task warten auf Knopfdruck AWT, Swing, JavaFX & SWT 4
M Zufallsgenerator bei JavaFx AWT, Swing, JavaFX & SWT 1
N Label Schriftart Ändern javafx AWT, Swing, JavaFX & SWT 2
L JavaFX JavaFX, MVVM und SceneBuilder AWT, Swing, JavaFX & SWT 4
S JavaFx Album AWT, Swing, JavaFX & SWT 137
I JavaFX - Pane wechseln über 2. Controller AWT, Swing, JavaFX & SWT 5
melaniemueller JavaFX Beispiel kann nicht ausgeführt werden AWT, Swing, JavaFX & SWT 4
T FXML Datei in Java Code einbinden: javafx.fxml.LoadException AWT, Swing, JavaFX & SWT 2
J JavaFX - Included FXML - Entfernen feststellen AWT, Swing, JavaFX & SWT 2
J JavaFX JavaFX/ Taskmenu / UML Klassendiagramm AWT, Swing, JavaFX & SWT 2
Davee JavaFX JavaFX Jar ausführbar jedoch nicht alle Stages AWT, Swing, JavaFX & SWT 3
2 JavaFX die ChoiceBox leitet den String nicht weiter oder es komm zu einem NullPointer AWT, Swing, JavaFX & SWT 8
C MouseEvent JavaFX AWT, Swing, JavaFX & SWT 4
L JavaFX javafx.fxml.LoadException bei einem Taschenrechner AWT, Swing, JavaFX & SWT 5
M4cM4rco0707 JavaFX Custom-Komponente mit Custom-Controller AWT, Swing, JavaFX & SWT 3
M Error occurred during initialization of boot layer java.lang.module.FindException: Module javafx.controls not found AWT, Swing, JavaFX & SWT 14
G javafx build.fxbuild in eclipse und ANT AWT, Swing, JavaFX & SWT 9
M Kollisionensbehandlung mit JavaFX AWT, Swing, JavaFX & SWT 1
N JavaFX - Toolkit not initialized AWT, Swing, JavaFX & SWT 6
G JavaFX , Duplicate erzeugt aber ich weis nicht wo AWT, Swing, JavaFX & SWT 4
K Javafx Plugin (javafx:jlink) mit moditect Plugin nutzen ... AWT, Swing, JavaFX & SWT 5
J Saubere Trennung Model, View, Controller Javafx AWT, Swing, JavaFX & SWT 10
G JavaFX BarChart während der Runtime aktualisieren AWT, Swing, JavaFX & SWT 4
Z JavaFX JavaFX Spinner AWT, Swing, JavaFX & SWT 1
N JavaFX Tableview nach Löschen von Element falscher Index AWT, Swing, JavaFX & SWT 4
G Exception javafx Thread -> caused by removing children while in EventHandler AWT, Swing, JavaFX & SWT 28

Ähnliche Java Themen

Neue Themen


Oben