java - 窗与窗的互动

标签 java user-interface javafx-2

我有一个带有标签 firstLabel 的主屏幕。有一个按钮openSecondWindow

按下该按钮将打开一个新窗口,同时将第一个窗口保留在屏幕上。

  • 如何锁定第一个屏幕,以便用户在第二个窗口关闭之前无法与其交互?

第二个窗口将有一个 TextFieldButton setFirstLabel。当用户在文本字段中输入文本并单击按钮时,第一个窗口中的文本就会更改。

  • 我应该如何从第二个窗口的 Controller 访问第一个窗口的 Controller 类?

  • 如何确保每次仅打开每个窗口的一个实例? (无重复)

最佳答案

我为你做了一个小例子。

如果您点击按钮上的第 1 个阶段来打开第二个阶段,则该按钮将被禁用,因此您无法再打开一个阶段。

如果您在 Stage2 上的文本字段中输入一些文本并单击此处的“更新”按钮,则第 1 阶段上的文本字段将更新,并且第二个阶段将关闭。

这是代码:

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>

第二个 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>

第一个 Controller

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();
    }
}

第二个 Controller

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;
    }
}

然后开始

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);
    }

}

神奇之处在于,将 FirstController 对象移交给 SecondController,您就可以更新第一个 Stage 上的 TextField。

希望这会有所帮助。

帕特里克

关于java - 窗与窗的互动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23303578/

相关文章:

Java:在当前目标上应用样式的方法

java - 找不到符号 MODULE$

java - 如何保证 JPanel 适合 JFrame

c++ - 如何让一个CTreeCtrl项集中显示?

wpf - WPF 中包含下标和内嵌图像的文本的本地化

java - 以编程方式触发定义的 ComboBox<T> EventHandler<ActionEvent>

java - 使用迭代器合并列表

java - Java哈希表中的哈希

java - 通过socket编程报警

JavaFX 动态 TableView 不显示数据库中的数据