Aufruf einer Methode einer anderen Klasse

didi577

Bekanntes Mitglied
Hallo,

ich grübele jetzt schon lange über diesem Problem:

Ich habe eine JavaFx GUI mit 2 Fenstern. Ich möchte aus Fenster 1 einen String an Fenster 2 übergeben. Der Code aus Fenster 1:
Java:
twc.setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());

Der Code aus Fenster 2 wo der Wert ankommen soll:
Java:
public void setWidgets(String name) {

       lblNameTarget.setText(name);

   }

Am Ende soll der Wert:
Java:
lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname()
aus Fenster 1 im Label aus Fenster 2 stehen:
Java:
lblNameTarget.setText(name)

wer kann mir weiter helfen?
 
wenn ich die Methode aufrufe erhalte ich eine NPE mit Verweis auf diese Stelle
Java:
    twc.setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
 
Dann am besten mal schauen ob twc oder lvEmploye null sind bzw sicherstellen dass das ganze nur aufgerufen wird wenn auch wirklich ein Item in der Liste ausgewählt ist. Sonst kann auch lvEmploye.getSelectionModel().getSelectedItem() null werden.
 
Java:
twc
scheint das Problem zu sein. Ich habe in der aufrufenden Klasse diese Zeile:
Java:
private TargetWindowController twc;

TargetWindowController ist die Klasse in der die Methode:
Java:
public void setWidgets(String name) {

       lblNameTarget.setText(name);

   }
steht
 
ok, ich habe jetzt in der initialize Methode die Zeile:
Java:
TargetWindowController twc = new TargetWindowController();
die NPE ist damit weg, Danke

jetzt habe ich noch eine NPE mit Verweis auf diese Zeile:
Java:
lblNameTarget.setText(name);
in der Methode:
Java:
public void setWidgets(String name) {

       lblNameTarget.setText(name);

   }

??
 
der String "name" wird jetzt mit dem gewünschten Wert belegt

die NPE bezieht sich also auf das Label dass scheinbar zum Zeitpunkt noch nocht da ist

wo muss ich jetzt noch umbauen?
 
lblNameTarget vermutlich null bzw. nicht initialisiert.
das es sich hier um eine FXML Anwendung handelt wird das Label "lblNameTarget" doch beim Fensterstart initialisiert?! Wenn ich die oben beschriebenen Methoden zum setzen des Textes auskonmmentiere ist das Label beim Fensterstart mit dem default Wert aus dem Scene Builder auch vorhanden. Hat noch jemand ei e Idee??
 
Okay das scheint zu passen.
Wie lädst du denn deinen FXML Datei? Kann es sein dass du 2 Instanzen deiner Controller-Klasse hast und die Variable daher null ist?
 
in der Klasse MainWindowController wird bei Klick auf einen Button folgendes ausgeführt:
Java:
btnAddTarget.setOnAction(ev -> {

           myTeam.TargetWindow();
           
           twc.setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
           
       });
myTeam.TargetWindow(); lädt die FXML:
Java:
public void TargetWindow() {

       try {
           FXMLLoader loader = new FXMLLoader(
                   MyTeam.class.getResource("/view/TargetView.fxml"));
           GridPane pane = loader.load();

           Scene scene = new Scene(pane);
           Stage targetWindowStage = new Stage();
           TargetWindowController targetWindowController = loader
                   .getController();
           targetWindowController.setMyTeam(this, targetWindowStage);

           targetWindowStage.setScene(scene);
           
           targetWindowStage.setTitle("Zielvereinbarungen");
           targetWindowStage.initOwner(primaryStage);
           targetWindowStage.initModality(Modality.APPLICATION_MODAL);
           targetWindowStage.show();

       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }

   }
twc.setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
.getFirstname()); übergibt den String an das Label in der Klasse TargetWindowController:
Java:
public void setWidgets(String name) {
       
       lblNameTarget.setText(name);
       System.out.println(name);
   }
die Variable name hat den richtigen Wert
 
Du solltest nirgendwo mit new einen neuen TargetWindowController erstellen, sondern den in TargetWindow initialisierten benutzen.
 
TargetWindowController als Instanzvariable setzten und einen Getter dafür bereit stellen, und diesen dann in der anderen Klasse aufrufen
 
ich habe jetzt in der MainWindowController:
Java:
private TargetWindowController twc;
...
...
btnAddTarget.setOnAction(ev -> {

           myTeam.TargetWindow();
          
           getTwc().setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
           
           
       });

in der TargetWindowController:
Java:
public void setWidgets(String name) {
       
       lblNameTarget.setText(name);

   }

ich bekomme weiter eine NPE in dieser Zeile:
Java:
getTwc().setWidgets(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
 
ich glaube du meintest es anders, TargetWindowController:
Java:
private TargetWindowController twc;
...
...
public TargetWindowController getTwc() {
       return twc;
   }

MainWindowController:
Java:
private TargetWindowController twc;
...
...
twc.getTwc().setWidgets(
                   lvEmploye.getSelectionModel().getSelectedItem()
                           .getFirstname());

trotzdem die NPE:
Java:
twc.getTwc().setWidgets...
 
Ja, ich mein was anderes. In deinem Code benutzt du ja auch nirgendwo Getter, sondern führst nur neue Variablen ein, die logischerweise null sind.

Aber bei den kurze Codestückchen kann man nicht wirklich was sagen...
 
hier mal mein Ziel wo ich hin möchte:

2017-05-31_10h28_38.png
aus der Listview des Hauptfensters soll der markierte Name "Patrick S" den Labeltext "Name aus LV" im Fenster "Zielvereinbarungen" ersetzen, das selbe dann für das Jahr "2017" im Hauptfenster nach "Jahr aus cb" . Das Fenster "Zielvereinbarungen" öffnet sich wenn ich im Hauptfenster auf den Button "Ziel erfassen" klicke

wie baue ich das am besten?
 
hier mein aktueller Code mit Bezug zum Problem:
Java:
public class MainWindowController {
   private String s;
@FXML
   private void initialize() {
btnAddTarget.setOnAction(ev -> {

           myTeam.TargetWindow();
           setS(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
System.out.println(s);
}

public String getS() {
           
       return s;
   }

   public void setS(String s) {
       this.s = s;
   }
}

der String soll als Text im Label der folgenden Klasse landen:
Java:
public class TargetWindowController {

   @FXML
   private Label lblNameTarget;

private MainWindowController mwc;

@FXML
   private void initialize() {

       setTextlbl();
   }
public void setTextlbl() {
       MainWindowController mwc = new MainWindowController();
       lblNameTarget.setText(mwc.getS());
   }

es gibt keinen Fehler aber "mwc.getS()" liefert null und somit ist der Text im Label leer

"System.out.println(s);" gibt den Namen richtig aus

vielleicht kann mir jetzt jemand helfen 🙁
 
Moin,
wenn das ist , wie du schreibst, dann klingt das für mich so, als würde "getS" in "setTextlbl" VOR dem 'initialize' in 'MainWindowController' aufgerufen!
Versuch' mal den String zu initialisieren:
Java:
private String s = "Test";

VG Klaus
 
Hi,

Java:
public class MainWindowController {
   
   private String s = "Test";
...

mwc.getS() liefert jetzt "Test"
 
Ausgehend von Post#16 und Post#7 kann man sagen dass der Fehler immer noch darin liegt, dass du 2 Instanzen deiner Controller Klasse hast.
In deiner TargetWindow() Methode lädst du die FXML Datei und gleichzeitig auch den Controller. Die Instanz existiert also. Gleichzeit sagst du aber, dass du in der initialize() Methode mittels TargetWindowController twc = new TargetWindowController(); eine weiter Instanz erstellst. Das sollte man niemals tun! Entfern die Zeile aus der initialize() Methode und ruf die setWidgets(String s) Methode aus deiner TargtWindow() Methode auf. Irgendwie so:

Java:
public void TargetWindow()
{
     FXMLLoader loader = ...
     ...
     TargetWindowController targetWindowController = loader.getController();
     ....
     targetWindowController.setWidgets(lvEmploye.getSelectionModel().getSelectedItem().getFirstname());
     ...
}
 
Sorry das hatte ich übersehen.
Dennoch solltest du deine anfängliche Idee mMn nicht verwerfen.
In deiner TargetWindowController Klasse hast du Methoden um die Werte in die Labels zu schreiben. (bspw. setWidgets(String s)).
Sobald du das FXML File geladen hast holst du dir dein Controller (wie du es bereits in Post#16 gemacht hast) und rufst die Methode setWidgets(..) auf. Erst danach darfst du die show() Methode aufrufen. Hier mal ein Beispiel aus einen meiner Projekte:
Java:
try
{
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(Manager.class.getResource("view/PlayerEditDialog.fxml"));
    AnchorPane page = (AnchorPane) loader.load();

    Stage dialogStage = new Stage();
    dialogStage.setTitle("Spieler bearbeiten");
    dialogStage.initModality(Modality.WINDOW_MODAL);
    dialogStage.initOwner(primaryStage);
    Scene scene = new Scene(page);
    dialogStage.setScene(scene);

    PlayerEditDialogController c = loader.getController();
    c.setDialogStage(dialogStage);
    c.setPlayer(player); // <-- das könnte deine setWidgets(String s) Methode sein

    dialogStage.showAndWait();

    return c.isOkClicked();
}
catch(IOException e)
{
    e.printStackTrace();
    return false;
}
 
ich glaube ich habe es

ich rufe
Java:
myTeam.TargetWindow(lvEmploye.getSelectionModel().getSelectedItem()
                   .getFirstname());
mit dem gewünschten String als Parameter auf
Java:
public void TargetWindow(String name) {

       try {
           FXMLLoader loader = new FXMLLoader(
                   MyTeam.class.getResource("/view/TargetView.fxml"));
           GridPane pane = loader.load();
           
           Scene scene = new Scene(pane);
           Stage targetWindowStage = new Stage();
           TargetWindowController targetWindowController = loader
                   .getController();
           targetWindowController.setMyTeam(this, targetWindowStage);
           Label lblNameTarget = new Label();
           lblNameTarget.setText(name);
           pane.add(lblNameTarget, 1, 0);
           targetWindowStage.setScene(scene);
           
           targetWindowStage.setTitle("Zielvereinbarungen");
           targetWindowStage.initOwner(primaryStage);
           targetWindowStage.initModality(Modality.APPLICATION_MODAL);
           targetWindowStage.show();

       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }

   }
in der Methode erzeuge ich ein neues Label, setze den Text aus dem Parameter und platziere das Label an die richtige Stelle, das Ergebnis passt

keine Ahnung ob das so "legal" ist 😉
 
ok, habe umgebaut:
Java:
public class TargetWindowController {
...
...
public void setWidgets(String name) {
       
       lblNameTarget.setText(name);
   }
}

und

Java:
public class MyTeam extends Application {
...
...
public void TargetWindow() {

       try {
           FXMLLoader loader = new FXMLLoader(
                   MyTeam.class.getResource("/view/TargetView.fxml"));
           GridPane pane = loader.load();

           Scene scene = new Scene(pane);
           Stage targetWindowStage = new Stage();
           TargetWindowController targetWindowController = loader
                   .getController();
           targetWindowController.setMyTeam(this, targetWindowStage);
           targetWindowController.setWidgets(LvEmploye().getSelectionModel().getSelectedItem().getFirstname());

           targetWindowStage.setScene(scene);

           targetWindowStage.setTitle("Zielvereinbarungen");
           targetWindowStage.initOwner(primaryStage);
           targetWindowStage.initModality(Modality.APPLICATION_MODAL);
           targetWindowStage.show();

       } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }

   }

beim Ausführen:
Exception in thread "JavaFX Application Thread" java.lang.Error: Unresolved compilation problem:
The method LvEmploye() is undefined for the type MyTeam

at controller.MyTeam.TargetWindow(MyTeam.java:181)

klar, lvEmploye kommt aus der Klasse MainWindowController

habe probiert:
Java:
public MainWindowController mwc;
...
targetWindowController.setWidgets(mwc.getLvEmploye().getSelectionModel().getSelectedItem().getFirstname());

aber NPE auf targetWindowController.setWidgets(mwc.getLvEmploye().getSelectionM...

ich denke wir sind nah am Ziel...was fehlt noch
 

Zurück
Oben