JavaFX Label in Controller-Klasse in einer anderen Controller-Klasse ändern

wainmaster

Mitglied
Hallo zusammen,

Ich habe folgendes Problem: Ich habe mit Hilfe des Scene Builders mehrere Fenster erstellt, die ich alle mit Hilfe von Controller-Klassen bearbeite. Am Anfang des Programms wird ein Login-Fenster aufgerufen, welches ein Hilfe-Fenster bei einem fehlgeschlagenen Login öffnet. Das klappt alles auch soweit. Nun wollte ich das Hilfe-Fenster so gestalten, dass der darin enthaltende Text universell anpassbar ist, da im Laufe des Programms die Möglichkeit besteht mehrere solcher Fenster öffnen zu lassen.
Mein Problem ist nun, dass ich es nicht hinbekomme den Text des Labels durch die Controller-Klasse des Login-Fensters zu verändern. Ich habe bereits versucht diese Änderung durch eine Setter-Methode in der InfoMessageController-Klasse zu realisieren aber irgendwie hat das nicht funktioniert..

Die beiden Controller-Klassen hänge ich mal mit ran:

LoginController: Ist die Controller-Klasse für das Login-Fenster

Java:
package com.thwildau.pachisiG2.controller;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class LoginController implements Initializable{

	@Override
	public void initialize(URL location, ResourceBundle resources) {		
	}
	
	@FXML
	private Label lblUsername;
	
	@FXML
	private Label lblPassword;
	
	@FXML
	private TextField txtUsername;
	
	@FXML
	private PasswordField pwPassword;
	
	@FXML
	private Button btnLogin;
	
	@FXML
	private Button btnRegister;
	
	@FXML
	private void switchToPassword(ActionEvent event) {
		pwPassword.requestFocus();
	}
	
	@FXML
	private void sendInformation(ActionEvent event) {
		if(txtUsername.getText().equalsIgnoreCase("Test") && pwPassword.getText().equals("1234")) {
			System.out.println("User " + txtUsername.getText() + " logged in");
			try{
				Node node = (Node) event.getSource();
				Stage stage = (Stage) node.getScene().getWindow();
				Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/GameSetup.fxml"));/* Exception */
				Scene scene = new Scene(root);
				stage.setScene(scene);
				stage.show();
				} catch(Exception e) {
					e.printStackTrace();
				}
		}
		else {
			try {
				Stage stage = new Stage();			
				Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
				Scene scene = new Scene(root);
				stage.setScene(scene);
				stage.initModality(Modality.APPLICATION_MODAL);
				stage.show();
				} catch(Exception e) {
					e.printStackTrace();
				}
		}
	}
	
	public void login(ActionEvent event) {
		if(txtUsername.getText().equalsIgnoreCase("Test") && pwPassword.getText().equals("1234")) {
			System.out.println("User " + txtUsername.getText() + " logged in");
			try{
				Node node = (Node) event.getSource();
				Stage stage = (Stage) node.getScene().getWindow();
				Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/GameSetup.fxml"));/* Exception */
				Scene scene = new Scene(root);
				stage.setScene(scene);
				stage.show();
				} catch(Exception e) {
					e.printStackTrace();
				}
		}
		else {
			//Hier sollte der Text (Label) der InfoMessageController-Klasse geändert werden
			try {
			Stage stage = new Stage();	
		    Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
			Scene scene = new Scene(root);
			stage.setScene(scene);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.show();
			} catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	public void runRegistration(ActionEvent event) {
		try{
			Node node = (Node) event.getSource();
			Stage stage = (Stage) node.getScene().getWindow();
			Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/Registration.fxml"));/* Exception */
			Scene scene = new Scene(root);
			stage.setScene(scene);
			stage.show();
			} catch(Exception e2) {
				e2.printStackTrace();
			}
	}

}

InfoMessageController: Controller-Klasse für die universell anpassbare InfoMessage

Java:
package com.thwildau.pachisiG2.controller;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.stage.Stage;

public class InfoMessageController implements Initializable{
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
	}
	
	@FXML
	private Label lblInfoMessage;
	
	@FXML
	private Button btnOk;

	public void closeWindow(ActionEvent event) {
		try{
			Node node = (Node) event.getSource();
			Stage stage = (Stage) node.getScene().getWindow();
			stage.close();
			} catch(Exception e) {
				e.printStackTrace();
			}
		
	}

}

Hat vielleicht jemand eine Idee, wie ich mein Vorhaben realisieren kann? Wäre wirklich sehr dankbar!!
 

dzim

Top Contributor
Gibt ein paar Wege:

Hole dir den Controller, nachdem du mit dem FXMLLoader die UI geladen hast (dazu musst du aber eine Instanz des FXMLLoader anlegen, anstelle von der Nutzung der statischen #load-Methode), dann kannst du mit einem Setter arbeiten (nach dem du das Objekt, das du bekommst, auf deine Controller-Klasse gecastet hast). Eine Variation wäre, den Controller nicht im FXML anzugeben, sondern selbst eine Instanz anzulegen und dem FXMLLoader zu übergeben (oder man kann noch irgendwie anders sich in den Prozess einklinken - mit der dem Callback-Interface, das man im FXMLLoader per #setControllerFactory angeben kann).
Java:
        else { // Zeile 94 bei dir
            //Hier sollte der Text (Label) der InfoMessageController-Klasse geändert werden
            try {
            Stage stage = new Stage();  
            FXMLLoader fxmlLoader = new FXMLLoader();
            Parent root = fxmlLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
            LoginController lc = (LoginController) fxmlLoader.getController();
            ls.updateInfoLabel("Supertolle Hilfe!");
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

Alternativ kannst du auch Events verwenden. Ist nicht das sauberste, man gerät vielleicht auch in Gefahr den Überblick zu verlieren, aber das ist mein favorisierter Weg.
Ich habe dazu immer einen (statischen) "Event Dispatcher", bei dem man einen Listener (also ein zu implementierendes Interface) registriert, welcher nur auf bestimmte Events hört (kann man ja per Strings, wie PropertyChangeEvents oder per Integers, festlegen). In dem Controller hörst du dann auf das Event und passt daraufhin den Inhalt des Labels an.
In deinem Code würde das vielleicht so etwas wie:
Java:
        else { // Zeile 94 bei dir
            //Hier sollte der Text (Label) der InfoMessageController-Klasse geändert werden
            try {
            Stage stage = new Stage();  
            Parent root = FXMLLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.show();
            // vielleicht auch vor dem stage.show(); möglich
            EventDispatcher.getInstance().fireEvent("updateText.infoLabel", "Supertolle Hilfe!");
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

Irgendwie so :-D
 

wainmaster

Mitglied
Java:
        else { // Zeile 94 bei dir
            //Hier sollte der Text (Label) der InfoMessageController-Klasse geändert werden
            try {
            Stage stage = new Stage();  
            FXMLLoader fxmlLoader = new FXMLLoader();
            Parent root = fxmlLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
            LoginController lc = (LoginController) fxmlLoader.getController();
            ls.updateInfoLabel("Supertolle Hilfe!");
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
Das gefällt mir persönlich eigentlich ganz gut. Ich muss doch aber in der Zeile

Java:
 "LoginController lc = (LoginController) fxmlLoader.getController();
eigentlich meinen InfoMessageController nehmen oder irre ich mich da? Wenn ich das dann mache bekomme ich aber leider eine NullPointerException :cry:
 

dzim

Top Contributor
Hey - ich kenn deine Controller nicht, hab einfach den erstbesten genommen der mir über den Weg lief - also ja: Wird wohl der sein, den du meinst.
Und die Methode musst du natürlich noch in dem entsprechendem Controller implementieren - die hat er ja nicht per se...
 

wainmaster

Mitglied
Die setter-Methode habe ich ja auch schon in der InfoMessageController-Klasse eingefügt aber trotzdem bekomme ich nur die NullPointerException.. :(

So sieht bei mir die Setter-Methode in der InfoMessageController-Klasse aus:

Java:
public void setInfo(String message) {
  //Ändere den Labeltext
  lblInfoMessage.setText(message);
}

und den Code in der anderen Controller-Klasse habe ich für mich angepasst:

Java:
                                Stage stage = new Stage();
				FXMLLoader fxmlLoader = new FXMLLoader();
				Parent root = fxmlLoader.load(getClass().getResource("/com/thwildau/pachisiG2/layout/InfoMessage.fxml"));
				InfoMessageController ic = (InfoMessageController) fxmlLoader.getController();
				ic.setInfo("Testmeldung");
				Scene scene = new Scene(root);
				stage.setScene(scene);
				stage.show();

Oder blicke ich grade einfach nicht was du meinst?^^
 

wainmaster

Mitglied
Die Exception ist in der LoginController-Klasse und hat anscheinend was mit
Java:
ic.setInfo("Testmeldung");
zu tun.
 

dzim

Top Contributor
Ich habe irgendwie das Gefühl, das entweder dein Cast auf InfoMessageController falsch ist (wenn z.B. im FXML ein anderer Controller steht), oder du im FXML überhaupt keinen Controller verlinkt hast.

Sorry, aber ich verwende diese Methode ein FXML zu laden in OSGi um einen IEclispeContext in den Controller zu injecten und das klappt immer.

Mach mal einfach folgendes [c]System.err.println(fxmlLoader.getController());[/c] und sag uns mal, was da für ein Ergebnis kommt. Ist es null, dann hast du keinen Controller im FXML verlinkt. Ist es was anderes, musst du hier mal schauen, welcher Controller es wirklich ist!





BTW: Nutzt du in deinem FXML ResourceBundles (also internationalisierte Zeichenketten)?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H JavaFX Label.Text mit bind an DoubleProperty binden AWT, Swing, JavaFX & SWT 3
izoards Ausdruck auf Label Drucker AWT, Swing, JavaFX & SWT 1
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
H RPG Programmieren, label.setLocation funktioniert nicht AWT, Swing, JavaFX & SWT 7
Jose05 Javafx Label Höhe=Breite AWT, Swing, JavaFX & SWT 1
N javafx Position der Bustaben finden label AWT, Swing, JavaFX & SWT 1
N Label Schriftart Ändern javafx AWT, Swing, JavaFX & SWT 2
D JavaFX Label flackert beim aktualisieren AWT, Swing, JavaFX & SWT 12
J JavaFX Label aktualisieren AWT, Swing, JavaFX & SWT 18
M JavaFX javaFX Label-Text wird nicht gesetzt AWT, Swing, JavaFX & SWT 3
T Anderen Java Code durch Code kompilieren und Fehler in Label ausgeben AWT, Swing, JavaFX & SWT 5
I BoxLayout zentriert Label nicht AWT, Swing, JavaFX & SWT 7
B Ausgaben einer Umrechnung vom Textfeld in ein Label AWT, Swing, JavaFX & SWT 2
R JavaFX Label oder Imageview anzeigen mit Buttonklick AWT, Swing, JavaFX & SWT 4
L Label im JavaFX Thread Updaten AWT, Swing, JavaFX & SWT 3
A Inhalt wechseln bei Klick auf Label AWT, Swing, JavaFX & SWT 8
ralfb1105 JavaFX Label lässt sich innerhalb service Task nicht updaten? AWT, Swing, JavaFX & SWT 22
Trèfle JavaFX Formattierung im Label AWT, Swing, JavaFX & SWT 3
ralfb1105 JavaFX Wie Text Label in neuem Window von Main Stage setzen? AWT, Swing, JavaFX & SWT 6
F Countdown in Label anzeigen AWT, Swing, JavaFX & SWT 14
H JavaFX - Label aktualisieren AWT, Swing, JavaFX & SWT 1
J Dateiname im Label einblenden AWT, Swing, JavaFX & SWT 4
C SWT autosize bei gc.drawString() auf einem Label AWT, Swing, JavaFX & SWT 7
xYurisha Aus einer Gui Buttons, Label und ProgessBars entfernen AWT, Swing, JavaFX & SWT 4
T Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
zhermann FX Label text wird nicht richtig angezeigt AWT, Swing, JavaFX & SWT 12
zhermann NullPointerException bei Label.setText() AWT, Swing, JavaFX & SWT 5
T JavaFX Label mit mehreren Images AWT, Swing, JavaFX & SWT 11
Kanda Sorata Inhalt einer .txt Datei einlesen und in ein Label einfügen (JavaFX) AWT, Swing, JavaFX & SWT 2
L JavaFX ContextMenu bei Label mit Linksklick AWT, Swing, JavaFX & SWT 4
J JavaFX - Felder (Label) in einer ForSchleife bearbeiten AWT, Swing, JavaFX & SWT 4
N Anordnung der Label AWT, Swing, JavaFX & SWT 3
N Swing Label auf Panel legen.. AWT, Swing, JavaFX & SWT 2
D JavaFX Label lässt sich nicht mehrmals färben AWT, Swing, JavaFX & SWT 7
R Swing JLabel berührung an einem anderen Label prüfen AWT, Swing, JavaFX & SWT 3
U Java FX Zusätzliches Label per Knopfdruck während der Laufzeit auf Panel einfügen. AWT, Swing, JavaFX & SWT 2
M Text in einem Label fett setzen AWT, Swing, JavaFX & SWT 4
D Swing JFreeChart Crosshair Label - setPreferredSize oder ähnliches, aber wo ? AWT, Swing, JavaFX & SWT 1
T CSS Rechtsbüdniges Label mit Zwei Zeilen AWT, Swing, JavaFX & SWT 7
J JavaFX Translation Text/Label AWT, Swing, JavaFX & SWT 2
Tom299 JavaFX Text oder Label benutzen AWT, Swing, JavaFX & SWT 4
C Textfeld und Label werden nicht angezeigt (Ubuntu) AWT, Swing, JavaFX & SWT 2
C SWT Treeview mit Bilder im Label verändert Expanded Icon AWT, Swing, JavaFX & SWT 1
Augenblau JavaFX Wechselnde Werte in Label darstellen AWT, Swing, JavaFX & SWT 7
V Swing Brauche Hilfe mit Label AWT, Swing, JavaFX & SWT 3
S JButton-Label vergrößern AWT, Swing, JavaFX & SWT 2
D Java Swing, Label lässt sich nicht mit Checkboxen/Knopf verändern AWT, Swing, JavaFX & SWT 2
M label mit icon verschieben. AWT, Swing, JavaFX & SWT 1
B Swing JXMapKit Mausemove in Label anzeigen AWT, Swing, JavaFX & SWT 0
K Bild in Label wird nicht angezeigt AWT, Swing, JavaFX & SWT 5
S JButton u. Label auf paint-Methode AWT, Swing, JavaFX & SWT 1
G Label wird nicht erstellt AWT, Swing, JavaFX & SWT 0
7 AWT problem: KeyListener/ test im Label umändern AWT, Swing, JavaFX & SWT 4
D Swing [Frage] ComboBox + Label AWT, Swing, JavaFX & SWT 3
G Label erstellen AWT, Swing, JavaFX & SWT 6
U Label zeigt nicht überall HTML Zeichen AWT, Swing, JavaFX & SWT 3
F JavaFX label.getWidth() AWT, Swing, JavaFX & SWT 2
T Swing Label aus anderer Methode bearbeiten AWT, Swing, JavaFX & SWT 2
N Input/Output Stream werte in Label anzeigen. AWT, Swing, JavaFX & SWT 6
R JavaFX Label ändern in aufgerufener AnchorPane AWT, Swing, JavaFX & SWT 3
B Swing label.setText() macht probleme AWT, Swing, JavaFX & SWT 5
G JavaFX CSS: Label in GridPane rechts ausrichten AWT, Swing, JavaFX & SWT 9
T Swing Aktuelle Größe eines Textes in einem Label darstellen AWT, Swing, JavaFX & SWT 3
KrokoDiehl Swing Buchstaben im Label anders färben AWT, Swing, JavaFX & SWT 4
K Zugriff auf Label und Ereignisbehandlung durch zwei Handlerklassen AWT, Swing, JavaFX & SWT 3
P Label rotieren mit Timer AWT, Swing, JavaFX & SWT 5
C Label wird nicht an der richtigen Position angezeigt.. AWT, Swing, JavaFX & SWT 7
H Label mit Icon positionieren AWT, Swing, JavaFX & SWT 14
E Netbeans: Buttons mit Label bzw. Rahmen unterlegen AWT, Swing, JavaFX & SWT 8
J resize - Label bleibt erst schwarz AWT, Swing, JavaFX & SWT 4
T label überschriebt seine werte-SWT AWT, Swing, JavaFX & SWT 3
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
D Label über JScrollPane AWT, Swing, JavaFX & SWT 3
N Label auf Hauptfenster manipulieren AWT, Swing, JavaFX & SWT 2
S VAADIN: Problem mit Label AWT, Swing, JavaFX & SWT 18
P Ausgabe Label AWT, Swing, JavaFX & SWT 6
GUI-Programmer Informations-Panel an Label AWT, Swing, JavaFX & SWT 2
S ImageIcon von Label entfernen AWT, Swing, JavaFX & SWT 9
B Label breite ermitteln vor dem rendern? AWT, Swing, JavaFX & SWT 7
A Bekomme das Label nicht in die Mitte von Reihe AWT, Swing, JavaFX & SWT 7
H SWT Markierbares Label AWT, Swing, JavaFX & SWT 8
A Swing Box Label ausrichten AWT, Swing, JavaFX & SWT 3
R Label in den Vordergrund einblenden AWT, Swing, JavaFX & SWT 5
J Hintergrund Label-Frame AWT, Swing, JavaFX & SWT 3
O Swing Label(bzw. Grafik) verdekt von anderm Label AWT, Swing, JavaFX & SWT 2
A TextField und Label AWT, Swing, JavaFX & SWT 8
L Label dynamisch awt AWT, Swing, JavaFX & SWT 2
J Label mit transparentem hintergrund - geht das? AWT, Swing, JavaFX & SWT 21
B Die Werte von getLocation() im Label anzeigen AWT, Swing, JavaFX & SWT 4
Avalarion SWT Listener auf Label oder Text Teile AWT, Swing, JavaFX & SWT 10
C Label Hintergrundbild mit Text AWT, Swing, JavaFX & SWT 6
A SWT - Farbe von Text auf Label ändern AWT, Swing, JavaFX & SWT 2
M gridbaglayout - abstand bei label und field AWT, Swing, JavaFX & SWT 8
hdi SWT Label Text vertikal zentrieren AWT, Swing, JavaFX & SWT 6
T In einem Label scrollen AWT, Swing, JavaFX & SWT 3
Spot84 swt label zeilenumbruch will nicht funktionieren AWT, Swing, JavaFX & SWT 1
L JFreeChar Label für StackedBar AWT, Swing, JavaFX & SWT 3
lumo SWT Label - onResize? AWT, Swing, JavaFX & SWT 5
DasDogma AWT Problem bei Wertzuweisung für Label AWT, Swing, JavaFX & SWT 3
A Label hat falsche Position AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben