【问题标题】:Set Action on button to do two action in one click在按钮上设置操作以一键执行两项操作
【发布时间】:2017-05-23 12:30:02
【问题描述】:

这是场景,我有一个主窗口,我单击一个按钮会打开一个弹出窗口。在这个弹出窗口中,我有一个表格视图,其中显示了一些数据,并且它有一个名为 select 的按钮。从表格视图中选择数据后,当我按下选择按钮时,我希望这个弹出窗口关闭,我从中选择的数据出现在我的主窗口中。

到目前为止,我唯一能做的就是从弹出窗口中提取数据,我希望它也只需单击一下即可关闭

private void venueDisplay(String title, String message) {
    Stage window = new Stage();

    //Block events to other windows
    window.initModality(Modality.APPLICATION_MODAL);
    window.setTitle(title);
    window.setMinWidth(400);

    HBox hBox = new HBox();
    hBox.setPadding(new Insets(10,10,10,10));
    hBox.setSpacing(10);
    hBox.setMaxHeight(20);
    hBox.setAlignment(Pos.BOTTOM_CENTER);

    hBox.getChildren().add(selectVenueButton);

    //Display all the available venues to choose for allocation
    VBox layout = new VBox(10);
    venueList = new ListView<>();
    ObservableList<Venue> observableVenue = FXCollections.observableArrayList(model.getVenues());
    venueList.setItems(observableVenue);


    layout.getChildren().addAll(venueList, hBox);

    //Display window and wait for it to be closed before returning
    Scene scene1 = new Scene(layout,300,500);
    window.setScene(scene1);
    window.showAndWait();
}

public void selectButtonHandler(EventHandler<ActionEvent> handler) {
    selectVenueButton.setOnAction(handler);
}

【问题讨论】:

  • 您的数据是如何存储的?
  • 它存储在.txt文件中。
  • 我创建了一个类似的应用程序。我使用 SQLite 来存储数据。我认为你应该使用 SQLite。确保您的 TableView 类有一个 ID 变量,您不必在 TableView 中显示此数据。您还需要一个属性表或数据库。您应该将 id 存储在 selectbuttonaction 和/或 popupclose 的属性表中。在 popup.showandwait() 之后检索该 ID 并对其运行查询。
  • 这是一个学校项目,我们只允许使用javafx和txt文件。如果我无法弄清楚一键两次操作,那么我将使用更简单的方法。
  • 好吧,您可以将文本字段视为数据库。每个新行都以唯一的 id 开头,后面的数据可能用冒号分隔。这个想法是一样的,它只是想要和数据库一样快。 Ex id:名字:姓氏:生日。这样,当您根据 id 获取行并将其拆分时,返回的数组将为 array[o] = id、array[1] = firstname array[2] = lastname 和 array[3] =birthday。永远都是这样。如果你缺少数据,你会做类似 => id :: lastname :birthday 之类的事情。

标签: java javafx


【解决方案1】:

请考虑这个示例,您可以将这个想法应用到您的程序中(评论中的解释)。

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class GetInfoFromPopUpWindow extends Application{

    static TextArea textArea = new TextArea(); // to be filled from the pop-up window

    @Override
    public void start(Stage primaryStage) throws Exception {
        // create the main Window and some simple components
        // Suppose it contains a TextArea only for simplicity sake

        Button open = new Button("Open Popup Window");

        //simple container as a root for testing
        HBox root = new HBox();
        root.getChildren().addAll(textArea, open);

        Scene scene = new Scene(root,610,400);

        primaryStage.setScene(scene);
        primaryStage.setTitle("Main Window");
        primaryStage.show();


        //Add Action Listener to the open Button
        open.setOnAction(e->{ // lambda expression, read more about it in the Documentation
            popUpWindow(); // call the method to open a pop-up wondow(see later)
        });

    }

    public static void popUpWindow(){
        VBox root = new VBox();
        Button fetchInfo = new Button("Finish");
        //create a listView and populate it with some info for testing purpose
        // suppose the info you get from some database
        ListView<String> listView = new ListView<String>();
        ObservableList<String> items = FXCollections.observableArrayList (
                                "First Item", "Second Item", "Third Item", "Fourth Item");
        listView.setItems(items);
        //to select more than one item
        listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        //decoration and size are up to your preference
        listView.setPrefWidth(100);
        listView.setPrefHeight(100);

        root.getChildren().addAll(listView, fetchInfo);
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 250,150);

        Stage stage = new Stage();
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.setScene(scene);
        stage.setTitle("Popup Window");
        stage.show();

        // Add action listener to fetchInfo Button in this Window
        fetchInfo.setOnAction(e->{
            // take the info from listView and fill it in the TextArea in the main Window
            // just for testing purposes
            for (String selectedItem : listView.getSelectionModel().getSelectedItems()){
                textArea.appendText(selectedItem + " \n");
            }

            // when it finishes -> close the window and back to the first one
            stage.close();
        });

    }

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

    }

}

测试

点击任何按钮之前的主窗口


单击按钮并选择某些项目后的弹出窗口


点击完成按钮后,关闭弹出窗口,然后返回主菜单并显示信息(选定项目)

【讨论】:

  • @Reboot 请将上述代码复制粘贴到您的 IDE 中并自己尝试。
  • 我认为它会起作用,但我唯一担心的是我实现的弹出窗口是私有 void 类型。 Stage 方法在该方法中,即使在同一个文件中我也无法访问它。
  • @Reboot 为什么private,这是您项目中的强制性要求吗?
  • @Reboot 为什么需要在弹出窗口中访问Stage?它是一个局部变量,您需要从 pop-up Window 旁边的信息打开,一键关闭并将信息返回到主菜单,在本例中为 TextArea
  • 私有化不是强制性的,但他们希望我们编写健壮的编程代码并使用非常防御性的方法,因此用户只能访问他们需要的信息而不是方法。如果我不将其设为私有,我将失去标记。整个分配分为三个 java 文件,视图仅用于 gui,控制器用于事件处理,模型用于逻辑。
【解决方案2】:

我认为你可以这样做:

private Venue venueDisplay(String title, String message) {

    // existing code..

    window.showAndWait();
    return venueList.getSelectionModel().getSelectedItem();
}

然后你的selectVenueButton 只需要关闭窗口:

selectVenueButton.setOnAction(e -> window.hide());

【讨论】:

    【解决方案3】:

    你想在点击选择按钮上执行两个操作

    1. 关闭弹出窗口:

    在按钮上实现这个设置事件处理程序如下

    selectVenueButton.setOnAction(handler);
    

    在处理程序中,您可以编写关闭弹出窗口的逻辑,如下所示:

    private EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() {
    
            public void handle(ActionEvent event) {
                Object source = event.getSource();
                if (source instanceof Button) {
                    Button btn = (Button) source;
                    Stage stage = (Stage) btn.getScene().getWindow();
                    stage.close();
                }
            }
        };
    
    1. 点击按钮后,您希望在主窗口中选择数据:

    要在Class Level Scope (Member Variables) 上实现这个声明地点列表,这样你就可以在一个类之外访问。 在对话框类中:

    ListView<Venue> venueList;
    

    在主窗口中访问数据:

    CustomDialog dialog = new CustomDialog(); //popup class
    dialog.showDialog;
    Venue selectedItem = dialog.venueList.getSelectionModel().getSelectedItems();
    

    【讨论】:

    • 对不起,我没有得到第二部分,第一部分很有魅力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    • 1970-01-01
    相关资源
    最近更新 更多