Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hallo,
die JavaFX-App besteht aus 2 Fenstern, erstellt mit dem SceneBuilder (FXML).
1) StartFenster mit: - Label
- Button: um zusätzliches Fenster aufzumachen
2) Fenster 2 mit: - TextField: für User-Eingabe
- Button: User-Input wird im Label des Startfenster angezeigt.
Ich habe das Problem statisch gelöst. Wie wird es richtig gemacht?
Hier mein Code. Vielen Dank vorab!
Ich finde die Art, eine Stage zu überschreiben, etwas antiquirt, aber Grundsätzlich spricht nichts gegen deinen Ansatz.
Ich würde es nur vielleicht über ein zentrales Modell lösen (kann ja "zur Not" auch statisch geholt werden (Model#getInstance() oder so). Dort enthalten eine StringProperty.
Im Fenster 1 das Label#textProperty() an diese StringProperty binden. In Fenster 2 ein Binding StringProperty zum TextField#textProperty().
Du Fragst wie das richtig gemacht wird, aus meiner Sicht ist die eigentlich richtige Art das zu machen einen Callback (auch Listener genannt) zu erstellen. Ob die richtige Art einfacher ist lass ich mal dahingestellt, aber du bist auf alle fälle flexibler und Kannst dein Window1 auch ohne Änderungen in anderen Projekten verwenden. Dazu musst du allerdings dein Projekt ein wenig umbauen.
Als erstes musst du dir ein Interface für deinen Callback erstellen.
Java:
public interface MyCallback {
void transferText(String text);
}
Dieses Interface musst du nun in deine Controller Klassen implementieren.
In der Window1Controller Klasse benötigst du eine Variable mit Setter für dein Callback Interface. In deiner onAction Methode musst du dann die Methode transferText von deinem Callback Interface aufrufen.
Java:
private MyCallback myCallback;
public void setMyCallback(MyCallback myCallback) {
this.myCallback = myCallback;
}
public void handleBtnAction(ActionEvent actionEvent) {
if (myCallback != null) myCallback.transferText(inputF.getText());
}
In deine WindowStartController Klasse musst du das Callback Interface und die Methode transferText implementieren und dann in der implementierten Methode deinen Text setzen. Außerdem musst du in dem Window1Controller den Callback setzen.
Java:
public class WindowStartController implements Initializable, MyCallback {
@Override
public void transferText(String text) {
tlbl.setText(text);
}
private void handleBtnAction(ActionEvent actionEvent) {
Window1 window1 = new Window1();
window1.getController().setMyCallback(this);
}
}
Damit du den Callback setzen kannst must du die Window1 Klasse noch ein wenig anpassen. Du must eine Variable mit deinem Controller erzeugen und diese initialisieren. An deinen Controller kommst du über den FXMLoader ran. Aus diesem Grund kannst du den Loader nicht mehr statisch verwenden. Dann benötigst du noch einen Getter für deinen Controller ... und eigentlich sollte es dann so funktionieren wie du das gerne hättest.
Java:
public class Window1 extends Stage {
private Window1Controller controller;
public Window1() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("window1.fxml"));
Parent root = loader.load();
controller = loader.getController();
setScene(new Scene(root, 600, 350));
setTitle("Window 1");
show();
} catch (IOException e) {
e.printStackTrace();
}
}
public Window1Controller getController() {
return controller;
}
}
Oder du nutzt einfach, wie ich es beschrieben habe, Data-Binding. Damit ist der Code auch noch viel entkoppelter und du musst nicht die eine Stage der anderen Übergeben (egal, wie viele Interfaces du da ran klatschst, es bleibt die komplette Stage).