【问题标题】:How to open popup window from an other class without button click in javaFX?如何在javaFX中不单击按钮从其他类打开弹出窗口?
【发布时间】:2020-08-17 09:05:03
【问题描述】:

所以我在 javaFX 控制器类中有一个名为“popup”的方法,它会在实际应用程序窗口的顶部打开一个小弹出窗口。如果将此方法分配给 fxml 中的按钮并单击该按钮,则此方法运行没有问题,但这不是我想要使用它的方式。

我有一个名为“Timer”的另一个类,它有一个新任务(新线程),它从某个数字开始倒计时,并且在某个时候它会打开一个带有消息的弹出窗口。我的目的是从这个“计时器”类中调用并运行“弹出”方法。当我从这里调用“弹出”方法时,它开始执行,但弹出窗口根本没有出现。 (方法调用发生在我从“popup”方法在控制台上收到“in popup”消息时。)

那么为什么当按钮单击从 fxml 文件调用“popup”方法时它会起作用,而当我从其他类调用它时为什么不能呢?谢谢。

请看下面的带有'popup'方法的控制器类和Timer类(在项目中使用Gradle):

“SceneController”控制器类:

package GradleFX;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
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.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Modality;
import javafx.stage.Stage;


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

//import java.awt.event.ActionEvent;

public class SceneController implements Initializable {

    public static String password = "";
    protected static int timercount = 20;


    @FXML
    private Label PWLabel;

    @FXML
    private Label bottomLabel;

    @FXML
    private PasswordField PWField;
    @FXML
    private Label showPWLabel;

    protected static Label myBottomLabel;
    private static PasswordField myPWField;
    private static Label myShowPWLabel;

    private static int tries;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        Timer timerTask = new Timer();

        myBottomLabel = bottomLabel;
        myPWField = PWField;
        myShowPWLabel = showPWLabel;

        new Thread(timerTask).start();
    }

    **/***********************************************************************
     /*This method runs if button is pressed in main application,
     but can't make it work by calling it from Timer Class */

    public void popup() {
        System.out.println("in popup");
        Stage dialogStage = new Stage();
        dialogStage.initModality(Modality.WINDOW_MODAL);

        VBox vbox = new VBox(new Text("Hi"), new Button("Ok."));
        vbox.setAlignment(Pos.CENTER);
        vbox.setPadding(new Insets(15));

        dialogStage.setScene(new Scene(vbox));
        dialogStage.show();
    }

    //****************************************************************************
    public void showPW() {
        myShowPWLabel.setText(myPWField.getText());
    }

    public void hidePW() {
        myShowPWLabel.setText("");
    }

    public void exit() {
        System.exit(0);
    }

    public void write() {
        PWLabel.setText("Mukodik");

    }

    public void writeInput(String in) {

        password = in;
        System.out.println("final password text text: " + password);
        writeFinally();

    }

    public void writeFinally() {

        System.out.println("This is 'password' : " + password);
        //bottomLabel.setText(password);
    }

    public void bottomLabelWrite() {
        bottomLabel.setText(myPWField.getText());
    }

    public static void setLabel() throws InterruptedException {
        myBottomLabel.setText("");
        myBottomLabel.setText("Database has been permanently erased.");
        //Thread.sleep(3000);
        //System.exit(0);
    }

    public static void noKeyEnteredNote() {
        myBottomLabel.setTextFill(Color.BLACK);
        myBottomLabel.setText("No key entered. Type Main Key.");
    }

    public static void rightKey() {
        myBottomLabel.setText("Yes, this is the right key.");
    }

    public static void wrongKey() throws InterruptedException {
        tries = MasterKey.numOfTryLeft;
        if (tries > 0) {
            myBottomLabel.setTextFill(Color.RED);
            myBottomLabel.setText("!!!Wrong key!!! You've got " + tries + " tries left!");

        }
    }

    public void simpleTest(String in) {
        System.out.println("in simpleTest and in is: " + in);
    }


    public void getMainKey() throws IOException, InterruptedException {
        MasterKey masterKey = new MasterKey();
        System.out.println("Inside SceneController");

        masterKey.requestKey(myPWField.getText());


    }

    public void changeScreen(ActionEvent event) throws IOException, InterruptedException {

        getMainKey();
        if (MasterKey.isRightKey) {
            Parent tableViewParent = FXMLLoader.load(getClass().getResource("Menu.fxml"));
            Scene tableViewScene = new Scene(tableViewParent);

            Stage window = (Stage) ((Node) event.getSource()).getScene().getWindow();
            window.setScene(tableViewScene);
            window.show();
        }
    }


}

这是定时器类:

    package GradleFX;


import javafx.concurrent.Task;
import javafx.event.ActionEvent;


public class Timer extends Task {

    private ActionEvent actionEvent;

    @Override
    protected Integer call() throws Exception {
        boolean notCalled = true;

        while (SceneController.timercount > 0) {
            SceneController sceneController = new SceneController();


            System.out.println(SceneController.timercount);
            Thread.sleep(1000);
            SceneController.timercount--;
            if (SceneController.timercount < 19) {

                System.out.println("Less than 5");

                if(notCalled) {
                    sceneController.popup();
                    notCalled = false;
                }



            }


        }
        System.exit(0);

        return null;
    }


}

【问题讨论】:

  • 您没有在 Timer 类中引用相同的 sceneController 实例。这里while (SceneController.timercount &gt; 0) 引用静态字段,稍后您将创建SceneController 的新实例并调用其popup(); 方法
  • 我将'popup'方法修改为静态并这样调用:SceneController.popup();同样的事情发生了,没有打开窗口,但是方法肯定被调用了。

标签: java user-interface javafx scenebuilder popupwindow


【解决方案1】:

将此添加到您的代码中:

@Override
public void initialize(URL location, ResourceBundle resources) {

    Timer timerTask = new Timer();

    myBottomLabel = bottomLabel;
    myPWField = PWField;
    myShowPWLabel = showPWLabel;

    new Thread(timerTask).start();
    timerTask.setOnFinished(e->{
        popup();
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-13
    • 2018-12-18
    • 1970-01-01
    • 2018-11-07
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多