JavaFX Mit einer Methode auf Stage zugreifen.

ForianF

Mitglied
Hallo, ich heiße Florian und bin 30 Jahre alt.
Mit JavaFx befasse ich mich jetzt ca 3 Monate.
Bis jetzt konnte ich auch alles nachlesen und habe hier schon viel gelernt.

Ich versuche schon seit 2 Tagen auf die Stage der public void start (Stage stage) Methode zuzugreifen.
Dies will ich erreichen weil ich ein paar Buttons in einer anderen klasse habe und aktionen ausführen wie z.b. das Fenster verschieben zu können.

Meine Idee war nun ein Stage zu erstellen: public static Stage stage1;
und dieses Stage dann der Start-Methode: public void start (stage1)
zu übergeben.
Dies scheint allerdings nicht zu funktionieren.

Gibt es eine Lösung für mein Problem, bzw ist das Überhaupt möglich ?

Hier der Code mit dem ich das versuche zu testen.

Java:
package stageTest;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.scene.control.Label;
import static javafx.application.Application.launch;

public class Test extends Application
{
    public static Stage stage1;
   
    @Override       
    public void start (stage1)

    {
        GridPane grid = new GridPane();
        Label label = new Label("test");
        grid.add(label, 1, 1);

        Scene scene = new Scene(grid, 400, 200);
       
        stage1.setTitle("TestScene");
        stage1.setScene(scene);
        stage1.show();
    }    
   
    public static void main(String[] args)
    {
        launch(args);
    }
}
 
Ich glaube dein Denkansatz ist ein wenig falsch.

Die Stage in der start() Methode ist das Hauptfenster deiner Application.

Du kannst ganz einfach (egal wo) ein neues Stage Objekt anlegen und diese mit show() öffnen.
Für einfache Benachrichtigungen gibt es auch Dialoge. http://code.makery.ch/blog/javafx-dialogs-official/

Für die Verwaltung deiner Fenster bietet es sich an einen FensterController oder ähnliches zu erstellen, welcher die Referenzen auf deine Fenster hält. Der Controller entscheidet dann welches Fenster zurzeit angezeigt wird.
Mit der Methode close() der Stage kannst du nämlich auch Fenster temporär schließen und später erneut öffnen.
 
Danke!
dein Beitrag hat mir weiter geholfen, und du hattest recht .. mein Denkansatz war nicht ganz richtig.

Das mit der close() Methode habe ich an anderen Stellen bereits verwendet.
Einen FensterController werde ich eventuell in einem anderen Projekt testen.

Verstehe ich das richtig das ich jetzt ein Stage in der Startmethode anlege, ohne dieses zu verwenden ?
Und wenn, ist das schlecht ?

Ich habe den Code jetzt wie folgt.

Java:
package stageTest;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.scene.control.Label;
import static javafx.application.Application.launch;

public class Test extends Application
{
    public static Stage stage()
    {
        Stage stage = new Stage();
        GridPane grid = new GridPane();
        Label label = new Label("test");
        grid.add(label, 1, 1);

        Scene scene = new Scene(grid, 400, 200);      
        stage.setTitle("TestScene");
        stage.setScene(scene);      
        return stage;
    }
  
    @Override      
    public void start (Stage Hauptfenster)
    {
        stage().show();
    }   
  
    public static void main(String[] args)
    {
        launch(args);
    }
}
 
Zuletzt bearbeitet von einem Moderator:
Was genau möchtest du denn erreichen? Ich muss zugeben, dass ich gerade nicht ganz hinterherkomme, was dein Ziel ist.
 
Ich habe es wahrscheinlich auch nicht genau genug erklärt.
Mein Programm funktionierte bis jetzt gut, wurde aber unübersichtlich weil fast alles in der Methode start geschrieben war.
Die Buttons habe ich jetzt in einer extra Klasse, diese funktionieren so auch.
Das einzige was nicht funktioniert, ist die Positionierung der Dialoge die beim klicken auf diese Buttons erscheinen.
Ein Button hat zum beispiel die Funktion Fahrzeuge hinzuzufügen.
Klickt man diesen geht ein Dialog (der soll direkt neben dem Button Fahrzeug Hinzufügen erscheinen)auf in dem man das Fahrzeug eingeben kann und beim Klick auf hinzufügen geht es wieder zu, soweit klappt also alles.
Die Positionierung funktioniert allerdings nicht, da diese Position wohl immernoch von deisem in der Startmethode erzeugten Stage ausgeht!?
folgenden befehl habe ich für die Positionierung ursprünglich als alles in der Start Methode stand benutzt:
Code:
            dialog.setX(hauptFenster.getX()+225);
            dialog.setY(hauptFenster.getY()+0);
Jetzt habe ich versucht diese Ausrichtung an der neuen Stage Methode anzuwenden, mit diesem Code:
Code:
            dialog.setX(hauptstage.getX()+225);
            dialog.setY(hauptstage.getY()+0);


Hier die aktuelle Start-Klasse:
Code:
import javafx.application.Application;
import javafx.stage.Stage;
import static javafx.application.Application.launch;

public class Start extends Application
{
    @Override       
    public void start (Stage Hauptfenster)
    {
        Hauptstage.stage().show();
    }
    public static void main(String[] args)
    {
        launch(args);
    }
}

und die Hauptstage Klasse:
Java:
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundImage;
import javafx.scene.layout.BackgroundPosition;
import javafx.scene.layout.BackgroundRepeat;
import javafx.scene.layout.BackgroundSize;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Hauptstage
{
        public static double xOffset = 0;
        public static double yOffset = 0;
        public static Label StatusLabel = new Label();
            
        public static Stage stage()
    {
         //hintergrundbild
        BackgroundImage myBI= new BackgroundImage(new Image("/style/hintergrund.png",800,533,false,true),
        BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.DEFAULT,
        BackgroundSize.DEFAULT);
       
        GridPane grid = new GridPane();
        grid.setGridLinesVisible(false);
        grid.setHgap(10);//gibt horinzontaler abstand der elemente an
        grid.setVgap(10);//gibt vertikaler abstand der elemente an
        grid.setPadding(new Insets(10, 10, 10, 10)); //gibt abstand von grid zu fensterrand an
        grid.setBackground(new Background(myBI));
       
        Scene scene = new Scene(grid, 800, 533);
        scene.getStylesheets().add("/style/style.css");
        scene.setFill(new Color(0, 0, 0, 1.00));
       
        Stage stage = new Stage();
        stage.setTitle("BikeSetup");
        stage.setScene(scene);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setResizable(false);
       
        //Fenster verschieben
        grid.setOnMousePressed((MouseEvent event) ->
        {
            xOffset = event.getSceneX();
            yOffset = event.getSceneY();
        });
        grid.setOnMouseDragged((MouseEvent event) ->
        {
            stage.setX(event.getScreenX() - xOffset);
            stage.setY(event.getScreenY() - yOffset);
        });
       
       
        grid.add(Buttons.exit(),1,2);
        grid.add(Feld_Location.location(),1,1);
        grid.add(Feld_Location.loctaion_inhalt(),1,1);
       
        return stage;
    }
}

Ich hoffe so habe ich das Problem verständlicher erklärt.
Danke schonmal für die Hilfe hier 🙂
Ich hatte lange gewartet und gegoogelt bevor ich mich hier gemeldet habe, aber leider bin ich nicht wirklich weiter gekommen.
 
Warum machst du dir nicht einfach eine Getter?
Java:
public static getMainStage(){
     return mainStage;
}
// Zugriff aus einer anderen Klasse
//....
MainApp.getMainStage();
 
Jetzt habe ich das Problem gelöst.
Das mit dem Getter habe ich versucht, wollte aber nicht so recht.
Irgendwas habe ich wohl falsch gemacht daran.
Nachdem ich nach "getMainStage" gegoogelt habe und mir ein paar codes angeschaut habe, fand ich die Lösung für mein Problem.
Durch die Antworten die mich nicht weitergebracht haben, habe ich trotzdem dazugelernt. 🙂

Nochmals danke für die Unterstützung hier !

Hier ein ausschnitt der Klasse :
Java:
public class Start extends Application
{
    public static Stage primaryStage;

    @Override      
    public void start (Stage primaryStage)
    {
        this.primaryStage = primaryStage;
       primaryStage.show();
    }
 
genau das was ich geschrieben habe...

wenn du es jetzt so lässt, also 'public' dann könnte man die Stage aus einer anderen Klasse manipulieren.
wenn du es private und mit getter machst dann ist dein object geschützt.
also für andere Klassen nur über getter ansprechbar

Java:
public class MainApp extends Application{
           private static Stage mainStage; // private object kann icht von aussen manipuliert werden

          public void start(Stage mainStage){
              this.mainStage = mainStage;
         }
}

/* Getter von MainStage */
public static Stage getMainStage(){return mainStage;}

// ---------- KLASSE B ------//

public class KlasseB{
        public static void main(String[]args){
               System.out.println(MainApp.getMainStage().toString());
        }
}
 
Ok, jetzt funktioniert es mit dem Getter.
Mein Fehler beim ersten versuch mit einem Getter zu arbeiten war das ich den Befehl
Java:
this.mainStage = mainStage;
vergessen hatte.
Danke vielmals, jetzt klappt alles wie es soll 🙂
 

Neue Themen


Zurück
Oben