문제

I have one main screen with a label firstLabel. There is a button openSecondWindow.

Pressing that button opens up a new window, while leaving the first one on the screen.

  • How would I lock the first screen so that the user cannot interact with it until the second window is closed?

The second window will have a TextField and Button setFirstLabel. When the user enters text in the text field and hits the button, the text from the first window is changed.

  • How am I supposed to access the controller class for the first window from the second window's controller?

  • How do I ensure that only one instance of each window be opened at a time? (No duplicates)

도움이 되었습니까?

해결책

i made a small example for you.

If you click on Stage 1 on the Button to open the second Stage, the Button will be disabled, so you cant open one more Stage.

If you type some text into the TextField on Stage2 and click on the Update Button there, the TextField on Stage 1 will be updated and the second Stage will be closed.

Here is the code:

firstWindow.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="de.professional_webworkx.jfx.twowindows.controller.FirstController">
  <children>
    <TextField fx:id="textField" layoutX="50.0" layoutY="189.0" prefWidth="500.0" promptText="Waiting for input from second Stage..." />
    <Button fx:id="openBtn" layoutX="441.0" layoutY="304.0" mnemonicParsing="false" text="open 2 Stage" />
  </children>
</AnchorPane>

Second fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="de.professional_webworkx.jfx.twowindows.controller.SecondController">
  <children>
    <TextField fx:id="textField" layoutX="50.0" layoutY="66.0" prefWidth="243.0" promptText="Type some text" />
    <Button fx:id="updateBtn" layoutX="50.0" layoutY="118.0" mnemonicParsing="false" text="update Text on Stage 1" />
  </children>
</AnchorPane>

FirstController

package de.professional_webworkx.jfx.twowindows.controller;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

/**
 *
 * @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
 * @version 1.0
 */
public class FirstController implements Initializable {

    @FXML
    Button openBtn;

    @FXML
    TextField textField;

    private boolean secondOpen;
    private Stage secondStage;

    FirstController firstController;
    public FirstController() {

    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        this.firstController = this;
        System.out.println(firstController);
        openBtn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                if(!secondOpen) {
                    openBtn.setDisable(true);
                    try {
                        FXMLLoader loader = new FXMLLoader(getClass().getResource("second.fxml"));
                        Parent load = loader.load();
                        SecondController controller = (SecondController) loader.getController();
                        controller.setFirstController(firstController);
                        Scene scene = new Scene(load);
                        secondStage = new Stage();
                        secondStage.setScene(scene);
                        secondStage.show();
                        secondOpen = true;
                    } catch (IOException ex) {
                        Logger.getLogger(FirstController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        });
    }

    public void updateText(final String text) {
        this.textField.setText(text);
    }

    public void secondClosed() {
        this.secondOpen = false;
        this.openBtn.setDisable(false);
        secondStage.close();
    }
}

SecondController

package de.professional_webworkx.jfx.twowindows.controller;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;

/**
 *
 * @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
 * @version 1.0
 */
public class SecondController implements Initializable {

    @FXML
    AnchorPane mainPane;

    @FXML
    TextField textField;

    @FXML
    Button updateBtn;

    private FirstController firstController;

    @Override
    public void initialize(URL url, ResourceBundle rb) {

        updateBtn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent t) {
                String text = textField.getText();
                firstController.updateText(text);
                firstController.secondClosed();

            }
        });
    }

    public void setFirstController(final FirstController firstController) {
        this.firstController = firstController;
    }
}

And start it

package de.professional_webworkx.jfx.twowindows;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

/**
 *
 * @author Patrick Ott <Patrick.Ott@professional-webworkx.de>
 */
public class TwoStages extends Application {

    @Override
    public void start(Stage primaryStage) {

        try {
            Parent load = FXMLLoader.load(getClass().getResource("firstWindow.fxml"));
            Scene scene = new Scene(load);

            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException ex) {
            Logger.getLogger(TwoStages.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

The Magic is, to hand over a FirstController object to the SecondController, that you are able to update the TextField on the first Stage.

Hope this will help.

Patrick

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top