Wie erhalte ich Zugriff auf ein UI-element aus einem anderen controller-Klassen in JavaFX?
Ich habe eine JavaFX - /Java-8-Anwendung geschrieben, mit NetBeans 8 (keine SceneBuilder
).
Meine Anwendung verfügt über ein Hauptfenster, das seine eigenen FXML-Datei (primären.fxml) und einen eigenen controller-Klasse (FXMLPrimaryController.java). Eines der Elemente in der FXML ist eine TextArea
. Einige der Methoden, die in FXMLPrimaryController.java sind über das Anhängen, dass TextArea
.
Diese Anwendung erscheint nun ein weiteres Fenster (eine weitere "stage") mit seiner eigenen FXML (Sekunde.fxml) und einen eigenen controller-Klasse (FXMLsecondController.java).
Innerhalb des zweiten controller-Klasse, wie kann ich eine TextArea in der Grundschule?
Hier ist ein Beispiel der relevante code:
primären.fxml:
<Button text="press me!" onAction="#openSecondWindow" />
<TextArea fx:id="myArea" />
FXMLPrimaryController.java:
public class FXMLPrimaryController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
}
@FXML private TextArea myArea;
final public void writeToTextArea() {
myArea.appendText("hi!");
}
@FXML
private void openSecondWindow(ActionEvent event) throws Exception {
Group root = new Group();
Stage stage = new Stage();
AnchorPane frame = FXMLLoader.load(getClass().getResource("second.fxml"));
root.getChildren().add(frame);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
}
Es ist nichts besonderes über die zweite.fxml. Angenommen, es gibt einen button mit onAction="#writeSomething"
.
In FXMLsecondController.java ich möchte eine Funktion, die auf die oben TextArea
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beim laden der FXML für die sekundäre controller, dies zu tun:
Dann können Sie Verweise auf den zweiten controller. Dies könnte nur der TextArea.
EDIT:
Ersetzt die
load()
nennen, in dem snippet oben und fügte hinzu, diesetLocation()
nennen. Die alte LinieAnchorPane frame = fxmlLoader.load(getClass().getResource("second.fxml"));
falsch war, wie ist es als die statischeload
- Funktion, die nutzlos ist hier.EDIT:
(Änderte den code-snippet oben, um besser mit Ihren Variablennamen.)
Das code-snippet oben ersetzt diesen Teil des Codes:
Linie, dass verwendet den FXMLLoader geladen die ansehen, und schafft auch die Instanz des Controllers, in diesem Fall
FXMLSecondaryController
. Sie können nicht jedoch die statischeFXMLLoader.load
Methode für diesen, benötigen Sie eine Instanz vonFXMLLoader
. Diese Instanz enthält eine Referenz auf den controller nach laden und Sie können abrufen, die mitgetController()
. Und Sie müssen gegossen, der zurückgegebene Wert Ihrer controller-Klasse (mit(FXMLSecondaryController)
).Primären controller hat ein Feld:
Diese enthält einen Verweis auf Ihre
TextArea
und initialisiert die fxml-loader. (Wenn Sie entfernen die@FXML
Anmerkung der loader nicht berühren.)In der Sekundär-controller in diesem Feld hinzufügen:
Beachten Sie, dass
@FXML
ist Weg (die fxml-loader ist nicht touch-Bereich) sowieprivate
(Sie wollen, um das Feld zu setzen, damit andere muss es sehen).Jetzt können Sie dieses Feld an, nachdem der controller geladen wurde. Also zurück zum laden code:
EDIT: Ersetzt die
load()
nennen, in dem snippet oben und fügte hinzu, diesetLocation()
nennen. Die alte LinieAnchorPane frame = fxmlLoader.load(getClass().getResource("second.fxml"));
falsch war, wie ist es als die statischeload
- Funktion, die nutzlos ist hier.Den
FXMLSecondaryController
hat jetzt einen Verweis auf dieTextArea
der primäre controller. In einer seiner Methoden, die Sie sollten in der Lage sein, um seinen Inhalt zugreifen:Beachten Sie, dass diese Lösung nicht die beste Lösung, aber es ist einfach und kann dienen als ein Anfang. Mit Bindung ist sicherlich empfehlenswert. Ich würde versuchen, eine Klasse zu erstellen, die über die Daten verfügt und auf die anderen Steuerungen binden. Aber wenn man den einfachen Ansatz für jetzt, sollte es ausreichend sein.
Ich hoffe ich konnte dir aussetzen, der TextField-von der FXMLPrimaryController, und haben eine TextField-Eigenschaft in der FXMLsecondController; legen Sie dann die Eigenschaft, wenn Sie montieren Sie die Teile zusammen. Wäre dies nicht ein gutes design, denn Sie würden aussetzen details der view durch den Controller.
Ich bin sicher, dass Sie nicht wollen, dass die TextArea aber die Daten der TextArea in
second.fxml
. So was würde ich vorschlagen, ist, um eine String-Eigenschaft in jedem der Controller und binden Sie zusammen.und dann in Ihre FXMLsecondController, können Sie
Dann können Sie binden diese zwei, mit so etwas
Diese nun bindet die variable
text
sowohl der Controller und man kann leicht zu verwenden, der eingegebene Wert wird in das Textfeld der der primäre controller in der Sekundär-controller !