如何在同一程序中显示两个javafx GUI屏幕

时间:2017-06-26 16:05:45

标签: user-interface javafx

我的问题是如何为每个程序显示多个用户界面屏幕。我确定之前已经问过这个问题,但我找不到适用于我的解决方案(或者我应该说我明白了)。关于我所谈论的场景,没有任何异国情调。第一种方法是简单地验证屏幕输入,并在出现错误时重新显示相同的屏幕。

我将根据第二个更复杂的场景提出问题:显示输入数据屏幕,处理输入;然后显示输出。这有点复杂,因为第一个,一个带有5个文本框和一个命令按钮的简单屏幕使用FXML文件,而第二个,多选列表框则没有。流程是:

1。主程序调用

2。一个加载程序,它加载FXML以某种方式或另一种方式调用

3。一个控制器,它接收输入并处理它们以产生输出。

最后一步是以多选列表框的形式显示输出。请注意,第一个GUI使用控制器(一个单独的文件)来处理输入,而第二个GUI使用事件处理程序(与屏幕定义位于同一文件中),以便在用户单击时进行选择一个命令按钮。

各种SO帖子都说,要做的就是在第一个GUI完成后不关闭应用程序,但保持JavaFX运行时间在后台运行

Platform.setImplicitExit(假);

并定义每个GUI并简单地将场景切换到您想要显示的场景。但是,鉴于我描述的场景你在哪里放置代码?第二个GUI有三个部分:屏幕定义,事件处理程序和场景切换代码。你把它们放在哪里? #2或#3。如果你把一些放在#2中,有些放在#3中,#3怎么知道你在#2中做了什么?

FMXL加载程序#2的代码:

    public class inputData extends Application { 
    public static void load() {       
        launch();
    }
    @Override
    public void start(Stage stage) throws Exception {

        GridPane inpRoot = FXMLLoader.load(getClass().getResource("inputData.fxml"));
        Scene inpScene = new Scene(inpRoot, 300, 275);

        stage.setTitle("Amsnag 2.1 - Query Input");
        stage.setScene(inpScene);
        stage.show();
    }   
}

#3的代码,列表框定义和处理程序,它们分别运行良好。只有在我尝试将其与其失败的程序中合并时才会这样。

public class multiList extends Application { 
    public static void load() {       
        launch();  
    }
    public static final ObservableList options = FXCollections.observableArrayList();

    @Override
        public void start(final Stage stage) {    
        final ListView<String> listView = new ListView<>();         
        listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
// load list from DB
        Connection conn = sql.connect();
        try {
    // initialize option table
            ResultSet rs = sql.select(conn, 
                "select distinct connDesc,accom from option order by connDEsc,accom");
            while (rs.next()) {
                String opt = rs.getString("connDesc") + ": " + rs.getString("accom");
                listView.getItems().add(opt);
            }                                                                    
            conn.close();
        }
        catch (SQLException e) {
            System.out.println(e.getMessage()+ " from init");
        }
// button to display fares
        final Button displayButton = new Button("Display Fares");
// handle button click
        displayButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent event) {
            Platform.exit();   // close list box
            ObservableList selectedIndices = listView.getSelectionModel().getSelectedItems();
// lcreate temp table with selected options
            Connection conn = sql.connect();
            try {
// initialize option table
                ResultSet rs = sql.select(conn, 
                    "create temporary table selected (connDesc varchar(200),accom varchar(50))");
                for(Object o : selectedIndices){
                   String option = o.toString();
// extract connDesc+accom from displayed option
                   msg.g(option);
                }        
                conn.close();
            }
            catch (SQLException e) {
               System.out.println(e.getMessage()+ " from init");
            }         
        }
    }    );   // end of display handler
// quit  button
    final Button resetButton = new Button("Quit");
    resetButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
        public void handle(ActionEvent event) {
            Platform.exit();
        }
    });
    final HBox controls = new HBox(10);
    controls.setAlignment(Pos.CENTER);
    controls.getChildren().addAll(displayButton, resetButton);

    final VBox layout = new VBox(10);
    layout.setAlignment(Pos.CENTER);
    layout.setStyle("-fx-padding: 10; -fx-background-color: cornsilk;");
    layout.getChildren().setAll(listView, controls);
    layout.setPrefWidth(320);``enter code here

    Scene scene = new Scene(layout);
 //   stage.setScene(new Scene(layout));
    stage.setScene(scene);
    stage.setTitle("Select one or more options");
    stage.show();
  }  
  public static void main(String[] args) { launch(args); }
}

1 个答案:

答案 0 :(得分:0)

您不能在其他应用程序中重用Application子类。

Application类代表整个应用程序,或者更具体地说是它的生命周期。因此,它具有init()start()stop()等方法,这些方法由FX Application Toolkit在应用程序生命周期的适当时刻调用。

multiList(除了:请使用proper naming conventions)类的布局是在start()方法中执行的,因此它只能在应用程序的开头发生。通过在此处放置布局代码,您无法重复使用,以便稍后在不同的应用程序中执行。

所以将MultiList的布局移到一个单独的类:

public class MultiList  { 

    public static final ObservableList options = FXCollections.observableArrayList();

    private final VBox view ;

    public MultiList() {    
        final ListView<String> listView = new ListView<>();         
        listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        // load list from DB
        Connection conn = sql.connect();
        try {
            // initialize option table
            ResultSet rs = sql.select(conn, 
                "select distinct connDesc,accom from option order by connDEsc,accom");
            while (rs.next()) {
                String opt = rs.getString("connDesc") + ": " + rs.getString("accom");
                listView.getItems().add(opt);
            }                                                                    
            conn.close();
        }
        catch (SQLException e) {
            System.out.println(e.getMessage()+ " from init");
        }
        // button to display fares
        final Button displayButton = new Button("Display Fares");
            // handle button click
            displayButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent event) {
                Platform.exit();   // close list box
                ObservableList selectedIndices = listView.getSelectionModel().getSelectedItems();
                // create temp table with selected options
                Connection conn = sql.connect();
                try {
                    // initialize option table
                    ResultSet rs = sql.select(conn, 
                        "create temporary table selected (connDesc varchar(200),accom varchar(50))");
                    for(Object o : selectedIndices){
                       String option = o.toString();
    // extract connDesc+accom from displayed option
                       msg.g(option);
                    }        
                    conn.close();
                } catch (SQLException e) {
                   System.out.println(e.getMessage()+ " from init");
                }         
            }
        });   // end of display handler
        // quit  button
        final Button resetButton = new Button("Quit");
        resetButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
            public void handle(ActionEvent event) {
                Platform.exit();
            }
        });
        final HBox controls = new HBox(10);
        controls.setAlignment(Pos.CENTER);
        controls.getChildren().addAll(displayButton, resetButton);

        view = new VBox(10);
        view.setAlignment(Pos.CENTER);
        view.setStyle("-fx-padding: 10; -fx-background-color: cornsilk;");
        view.getChildren().setAll(listView, controls);
        view.setPrefWidth(320);


    }  

    public Parent getView() {
        return view ;
    }

}

现在,如果你想自己测试一下,你可以为它编写一个应用程序:

public class MultiListApp extends Application {

    @Override
    public void start(Stage primaryStage) {
        MultiList multiList = new MultiList() ;
        Scene scene = new Scene(multiList.getView());
        primaryStage.setScene(scene);
        primarStage.setTitle("Select one or more options");
        primaryStage.show();
    }
}

或者在InputData.fxml的控制器类中,您可以执行相同的操作:

public class InputDataController {

    @FXML
    private void someEventHandler() {
        MultiList multiList = new MultiList() ;
        Scene scene = new Scene(multiList.getView());
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setTitle("Select one or more options");
        stage.show();
    }
}