JavaFX kann man da noch was am code vereinfachen design technisch sieht nicht richtig aus...

  • Themenstarter Themenstarter Mart
  • Beginndatum Beginndatum
M

Mart

Gast
ich versuche für mein Rapidfx die erstellung von nodes und views vereinfachen

Java:
    BorderPane root = GUIFactory.getBorderPane()
        .bottom(new Button("Bottom"))
        .top(new Button("Top"))
        .centerView(this.view)
        .id("bob")
        .build();
das sieht ja schon gut aus ( ? ) es sollte das "zusammenbauen" der Views vereinfachen so sachen wie widthproperty und css sollten fürs erste extra gemacht werden

für das hab ich die klasse die stark danach aussieht dass ich da was vereinfachen könnte da es ansich 12 mal das selbe ist aber ich steh auf dem schlauch in der Hinsicht...
Java:
public class BorderPaneBuilder extends AnyFactory<BorderPane, BorderPaneBuilder> {

  public BorderPaneBuilder() {
    root = new BorderPane();
  }

  public BorderPaneBuilder top(Node node) {
    root.setTop(node);
    return this;
  }

  public BorderPaneBuilder left(Node node) {
    root.setLeft(node);
    return this;
  }

  public BorderPaneBuilder right(Node node) {
    root.setRight(node);
    return this;
  }

  public BorderPaneBuilder center(Node node) {
    root.setCenter(node);
    return this;
  }

  public BorderPaneBuilder bottom(Node node) {

    root.setBottom(node);
    return this;
  }
  public BorderPaneBuilder bottomView(RapidView<?> view) {
    bottom(view.getRootPane());
    return this;
  }
  public BorderPaneBuilder topView(RapidView<?> view) {
    top(view.getRootPane());
    return this;
  }
  public BorderPaneBuilder leftView(RapidView<?> view) {
    left(view.getRootPane());
    return this;
  }
  public BorderPaneBuilder rightView(RapidView<?> view) {
    right(view.getRootPane());
    return this;
  }
  public BorderPaneBuilder centerView(RapidView<?> view) {
    top(view.getRootPane());
    return this;
  }
  public BorderPane build() {
    return root;
  }

}
in der Any factory steht die id() methode und dass root dann dem generischen typen entspricht kann ich ja nachreichen
 
Nein, das wird nicht besser. Du hast nur eine Zeile Code pro Aufruf, und davon auch keine Komplexitaet in der Zeile, egal was du da versuchst, unter eine Zeile wirst du nicht kommen. Du koenntest anfangen mit Lambdas und aehnlichem, aber du kommst nicht unter eine Zeile.

Was mir aber auffaellt, waere das du eventuell den Builder komplett vernichten kannst. Du koenntest dich direkt von BorderPane ableiten und die Methoden ueberschreiben:

Java:
public RapidBorderPane extends BorderPane {
    public RapidBorderPane() {
        super();
    }
   
    @Override
    public RapidBorderPane setRight(Node node) {
        super.setRight(node);
       
        return this;
    }
}

Java:
BorderPane pane = new RapidBorderPane()
        .setBottom(new Button("Bottom"))
        .setTop(new Button("Top"))
        .setCenterView(this.view)
        .setId("bob")

Also quasi einfach nur eine Verbesserung der bisherigen API.
 
die set Methoden sind final 😀
genauso wie deren properties

im moment schauts so aus
Java:
public class BorderPaneBuilder extends AnyFactory<BorderPane, BorderPaneBuilder> {
  private enum Position {
    TOP, LEFT, RIGHT, CENTER,BOTTOM;
  }

  private BorderPaneBuilder set(Position position, Node node) {
    switch (position) {
    case CENTER -> root.setCenter(node);
    case LEFT -> root.setLeft(node);
    case RIGHT -> root.setRight(node);
    case TOP -> root.setTop(node);
    case BOTTOM -> root.setBottom(node);
    }
    return this;
  }

  public BorderPaneBuilder() {
    root = new BorderPane();
  }

  public BorderPaneBuilder top(Node node) {
    return set(Position.TOP, node);
  }

  public BorderPaneBuilder left(Node node) {
    return set(Position.CENTER, node);
  }

  public BorderPaneBuilder right(Node node) {
    return set(Position.RIGHT, node);
  }

  public BorderPaneBuilder center(Node node) {
    return set(Position.CENTER, node);
  }

  public BorderPaneBuilder bottom(Node node) {
    return set(Position.BOTTOM, node);
  }

  public BorderPaneBuilder bottom(RapidView<?> view) {
    return bottom(view.getRootPane());
  }

  public BorderPaneBuilder top(RapidView<?> view) {
    return top(view.getRootPane());
  }

  public BorderPaneBuilder left(RapidView<?> view) {
    return left(view.getRootPane());
  }

  public BorderPaneBuilder right(RapidView<?> view) {
    return right(view.getRootPane());
  }

  public BorderPaneBuilder center(RapidView<?> view) {
    return top(view.getRootPane());
  }

}
 
Java:
public class BorderPaneBuilder extends AnyFactory<BorderPane, BorderPaneBuilder> {
private enum Position {
TOP, LEFT, RIGHT, CENTER,BOTTOM;
}

private BorderPaneBuilder set(Position position, Node node) {
switch (position) {
case CENTER -> root.setCenter(node);
case LEFT -> root.setLeft(node);
case RIGHT -> root.setRight(node);
case TOP -> root.setTop(node);
case BOTTOM -> root.setBottom(node);
}
return this;
}

public BorderPaneBuilder() {
root = new BorderPane();
}

public BorderPaneBuilder top(Node node) {
return set(Position.TOP, node);
}

public BorderPaneBuilder left(Node node) {
return set(Position.CENTER, node);
}

public BorderPaneBuilder right(Node node) {
return set(Position.RIGHT, node);
}

public BorderPaneBuilder center(Node node) {
return set(Position.CENTER, node);
}

public BorderPaneBuilder bottom(Node node) {
return set(Position.BOTTOM, node);
}

public BorderPaneBuilder bottom(RapidView<?> view) {
return bottom(view.getRootPane());
}

public BorderPaneBuilder top(RapidView<?> view) {
return top(view.getRootPane());
}

public BorderPaneBuilder left(RapidView<?> view) {
return left(view.getRootPane());
}

public BorderPaneBuilder right(RapidView<?> view) {
return right(view.getRootPane());
}

public BorderPaneBuilder center(RapidView<?> view) {
return top(view.getRootPane());
}

}
Aber das macht's doch nicht besser mit dem Enum...? Gewinnst du ja nichts (auszer dass du jetzt einen Enum mitschleifst).
 
Achso, du koenntest die Methoden noch anders beim ableiten benennen:

Java:
BorderPane pane = new RapidBorderPane()
        .withBottom(new Button("Bottom"))
        .withTop(new Button("Top"))
        .withCenter(this.view)
        .withId("bob")
 
von der Grundsätzlichen Idee warum sollte man den Builder eher vermeiden?

es würde ja wie gezeigt auf beide möglichkeiten gehen

dachte delegation over inheritance?
 
von der Grundsätzlichen Idee warum sollte man den Builder eher vermeiden?
Sollte nicht, nur persoenliche Praeferenz. Von der Verwendung her ergeben sich Unterschiede wie du ja schon gesehen hast. Hinzu kommt noch dass beim Builder dann "Erstellung" und "Veraenderung" unterschiedlich sind.

Java:
BorderPane pane = GUIFactory.getBorderPane()
        .bottom(new Button("Bottom"))
        .top(new Button("Top"))
        .centerView(this.view)
        .id("bob")
        .build();

// Some time later in a button event.

pane.setTop(anotherButton);
pane.setBottom(someNewLabel);

Java:
RapidBorderPane pane = new RapidBorderPane()
        .withBottom(new Button("Bottom"))
        .withTop(new Button("Top"))
        .withCenter(this.view)
        .withId("bob");

// Some time later in a button event.

pane.withTop(anotherButton)
        .withBottom(someNewLabel);

Builder werden fuer gewoehnlich auch nur dann eingesetzt wenn das erstellte Objekt entweder nicht mehr veraendert werden kann, oder wenn es komplex ist und der Builder Einfachheit bringt. Was beides bei den JavaFX Controls nicht unmittelbar der Fall ist. Was ja da nur halt reinhakt ist dass die JavaFX Entwickler final verwenden als waere es Schokostreusel.

dachte delegation over inheritance?
Ich entgegne "Whatever gets the job done". Solchen "Saetzen der Weisheit" sollte man nicht blind folgen, wie ich ja letztens schon bei den Strings und der Datenbank erklaert habe.

Zugegeben, mein Hauptaugenmerkt bei so etwas liegt aber auch nicht auf der Implementierung selbst, sondern auf dem Code welche dann daraus resultiert. Es nuetzt nichts wenn du das beste und tollste Framework hast, wenn sich der Code in deiner Applikation dann liest wie ein Waschbetonboden und du alle naselang irgendwelche Sonderfaelle beachten musst.
 
ich habe es jetzt auch so übernommen wie du geschrieben hattest
Java:
public class RapidBorderPane extends BorderPane {

  public RapidBorderPane top(Node node) {
    this.setTop(node);
    return this;
  }

  public RapidBorderPane left(Node node) {
    this.setLeft(node);
    return this;
  }

  public RapidBorderPane right(Node node) {
    this.setRight(node);
    return this;
  }

  public RapidBorderPane center(Node node) {
    this.setCenter(node);
    return this;
  }

  public RapidBorderPane bottom(Node node) {
    this.setBottom(node);
    return this;
  }

  public RapidBorderPane bottom(RapidView<?> view) {
    return bottom(view.getRootPane());
  }

  public RapidBorderPane top(RapidView<?> view) {
    return top(view.getRootPane());
  }

  public RapidBorderPane left(RapidView<?> view) {
    return left(view.getRootPane());
  }

  public RapidBorderPane right(RapidView<?> view) {
    return right(view.getRootPane());
  }

  public RapidBorderPane center(RapidView<?> view) {
    return top(view.getRootPane());
  }

}

wahrscheinlich wirds auch nich mehr besser .. die borderpane ist wahrscheinlich vererbungs technisch eh ne katastrophe... die getChildren() methode bringt einfach mal gar nix mehr und ist total useless und jetzt auch noch das mit den finals

aber das mit der Vererbung wurde wahrschienlich in javafx übertrieben.. man kann eine SimpleReadOnlyDoubleWrapperProperty machen

und dass ich ganze 2 insane konstruktoren habe
etnweder gar nix, oder alle 5 optionen... da hätte sich wahrscheinlich der Builder angeboten ihn einzubauen weil man kann ja builder für optionale parameter benutzen aber man musste es void machen und final oben drauf


es funktioniert wengistens so dass ich incht mehr
Java:
borderpane.setTop(...)
borderpane.setLeft(...)
borderpane.setCenter(...)
schreiben muss , mein framework sollte es ja nicht neu erfinden sondern alles einfacher machen dass man halt schneller zum ziel kommt... ja der name war nicht gerade kreativ xD
 
Zuletzt bearbeitet von einem Moderator:
selbst wenn ich es überschreiben könnte ich kann ja nicht den return Typ in der Super klasse überschreiben
 
Java:
  @Override
  protected BorderPane layoutChildren() {
    // TODO Auto-generated method stub
    super.layoutChildren();
    return this;
  }
wenn ich dasd überschreiben will ( normal ist es void ) kommt der Fehler
The return type is incompatible with BorderPane.layoutChildren()
stell ich mich grad an wie der erste mensch? wie kann ich denn beim überschreiben dne Return typ ändern?
 
Nein, das war mein Fehler, das geht nicht. Ich haette schwoeren koennen dass das ging, aber es geht nicht, oder zumindest geht es nicht durch den Compiler durch (Laufzeit ist ja wieder was anderes).

Ich haette schwoeren koennen dass man das haette machen koennen, keine Ahnung wo ich da gerade falsch abgebogen bin...dann bleibt nur noch neue Methoden...
 

Zurück
Oben