如何在JavaFX的主窗口中调用弹出窗口?

时间:2019-06-19 18:54:26

标签: javafx fxml

  

这也是我的第一篇文章。这也是我使用JavaFX的第一个项目。我正在尝试调用一个小的弹出窗口(通过调用某种键,例如F9),该窗口在主窗口的Textfield中将具有TableView。现在,我试图从主窗口上的按钮调用弹出窗口。我当然想将TableView的值返回到主窗口,但是稍后会出现。我甚至在调用弹出窗口时都遇到问题。

我已经在这里查看了各种示例和解决方案,但无法解决我的问题。我最终将在主窗口中调用3个弹出窗口。

我的MVC体系结构中包含以下文件:

  
      
  1. Main.java-(src / sample文件夹)
  2.   
  3. StudentController.java-(src / sample / controller文件夹)
  4.   
  5. StudentDAO.java和sexDAO.java(数据访问对象)-(src / sample / model文件夹)
  6.   
  7. Student.java(公共类学生和构造函数)-(src / sample / model文件夹)
  8.   
  9. OJDBC的util下的DBUtil-(src / sample / util文件夹)
  10.   
  11. 使用Scene Builder创建的FXML文件-(src / sample / view文件夹)      
        
          
    1. RootLayout.fxml
    2.     
    3. StudentView.fxml(主窗口)
    4.     
    5. GenderPopup.fxml(带有显示记录的TableView的弹出窗口)
    6.     
      
  12.   

Main.java

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;

public class Main extends Application {
private Stage primaryStage;
private BorderPane rootLayout;

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("Sample JavaFX App");
    initRootLayout(); // Initialize RootLayout
    showStudentView();
}

//Initializes the root layout.
public void initRootLayout() {
    try {
        FXMLLoader loader = new FXMLLoader();
       loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));
        rootLayout = (BorderPane) loader.load();
        Scene scene = new Scene(rootLayout);
        primaryStage.setScene(scene);
        primaryStage.show(); //Display the primary stage
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//Shows the Patient inside the root layout.
public void showStudentView() {
    try {
      FXMLLoader loader = new FXMLLoader();
      loader.setLocation(Main.class.getResource("view/StudentView.fxml"));
      AnchorPane PatientView = (AnchorPane) loader.load();
      rootLayout.setCenter(PatientView);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
        launch(args);
    }
}

StudentController.java

package sample.controller;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class StudentController {
    @FXML private TextField studentIdText;
    @FXML private TextField lastNameText;
    @FXML private TextField firstNameText;
    @FXML private TextField sexText;
    @FXML private Button popupButton;

    @FXML
    private void initialize () {
// I have additional listeners here doing different things that I have excluded which do pretty much similar things as shown below
    sexText.focusedProperty().addListener((arg0, oldPropertyValue, newPropertyValue) -> {
        if (!newPropertyValue) {
            try {
                searchSexDescription();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    });
}

// Function to Search Sex Description
@FXML
private void searchSexDescription() throws ClassNotFoundException, SQLException {
    try {
        if (!sexText.getText().isEmpty()) {
            // Get Gender Description
            Patient sex = SexDAO.searchSex(sexText.getText());
            populateAndShowSexDescription(sex);
        }
    } catch (SQLException e) {
        System.out.println("Exception raised in searchSexDescription");
        e.printStackTrace();
        throw e;
    }
}

@FXML
public void showGenderPopup() throws IOException {
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("view/GenderPopup.fxml"));
        Parent root = (Parent) fxmlLoader.load();
        Scene scene = new Scene(root);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
} catch (IOException e) {
    e.printStackTrace();
  }
}

StudentView.fxml

  

这是主窗口,其中有一个按钮, onAction 正在调用 showGenderPopup()

因此,在此阶段,我的学生记录正在主窗口中很好地获取。但是,当我按Popup按钮尝试调用Popup窗口时,出现错误(未设置位置)。现在,我知道这不是文件名错误,但确实发生了类似错误。我的路径正确,文件名也正确。我猜想作为孩子的弹出窗口无法找到父对象。任何帮助将不胜感激!

错误:     原因:java.lang.IllegalStateException:未设置位置。

谢谢

2 个答案:

答案 0 :(得分:1)

您的路径不正确。您正在尝试从StudentController类而不是Main类获取FXML资源。如前所述,您的项目结构包括:

  • /sample/Main.java
  • /sample/controller/StudentController.java
  • /sample/view/GenderPopup.fxml

由于您在getClass().getResource(...)内调用StudentController,所以没有前导/的路径是相对于StudentController的位置的。这意味着该路径最终可以解决:

  • /sample/controller/view/GenderPopup.fxml

不存在。

如果使用/sample/view/GenderPopup.fxml查询资源,则需要使用StudentController.class作为路径。

答案 1 :(得分:0)

我的弹出窗口现在正在工作@Slaw。

但是,当我在我的FXML文件中包括一个控制器时(我需要使用StudentController中的函数),我得到了一个N​​ull指针异常。我将控制器添加到GenderPopup.fxml

  

fx:controller =“ sample.controller.StudentController”添加到AnchorPane。

从堆栈跟踪看来,问题可能出在该行中:

父母根=(父母)fxmlLoader.load();

您知道这里会发生什么吗?

@FXML
public void showGenderPopup() throws IOException {
    try {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/sample/view/GenderPopup.fxml"));
        Parent root = (Parent) fxmlLoader.load();
        Scene scene = new Scene(root);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
        searchAllGender(this.actionEvent);
        genderCodeColumn.setCellValueFactory(cellData -> cellData.getValue().genderCodeProperty());
        genderDescriptionColumn.setCellValueFactory(cellData -> cellData.getValue().genderDescriptionProperty());
} catch (IOException e)
    {
    e.printStackTrace();
  } catch (SQLException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}