与JavaFX GUI事件处理和更新有关的问题

时间:2018-07-06 11:16:05

标签: javafx event-handling

对于我的代码长度,我们深表歉意。昨晚我意识到自己走错了路,现在陷入了一个我认为与JavaFX事件处理有关的问题。最初,我有一个逻辑在GUI之外的基本循环中运行,这取决于通过控制台进行的交互。一切都很好。现在,我试图通过用户的交互使它在GUI中工作。

下面的代码有两个主要问题。

第一个是在startButton执行我的主逻辑序列的开始之后,textArea中的文本未使用其他文本更新。第一个追加从第一个while循环开始。我希望在逻辑执行时将其显示在GUI中。我不确定是否需要告诉GUI每隔一定时间进行更新,或者是否还有其他问题。

第二,我不确定如何让程序等待用户在textField中键入内容,然后再点击我创建的textButton继续。我曾经创建过一个扫描仪,导致程序在控制台中等待输入。我意识到我需要一种告诉它在JavaFX内部运行时等待按钮按下的方法。

我选择不包括其余代码以使内容更易于阅读,但是可以添加它,如果它有助于解决此问题。

谢谢大家的帮助!

public class FxApp extends Application {

//Creates FileParser object with methods that alter the incoming Array of Strings into the format we need
FileParser fileParser = new FileParser();
Configure configure = new Configure();

private String text;
private String initialState;

private ArrayList<Machine> machines = new ArrayList<Machine>();
private Map<String, String> initialStates = new HashMap<String, String>();
private Map<String, String> states = new HashMap<String, String>();
private Map<String, ArrayDeque<String>> queues = new HashMap<String, ArrayDeque<String>>();
private Map<Integer, ArrayList<String>> parsedData = new HashMap<Integer, ArrayList<String>>();

@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("File Chooser");

    FileChooser fileChooser = new FileChooser();
    fileChooser.getExtensionFilters().addAll(new ExtensionFilter("Text Files", "*.txt"));

    Button startButton = new Button("Start");
    Button openButton = new Button("Click to open a file...");
    openButton.setPrefSize(200, 80);
    Button textButton = new Button("Enter"); 

    TextArea textArea = new TextArea();
    textArea.setWrapText(true);
    TextField textField = new TextField();

    Label lbl = new Label();
    VBox vbox = new VBox(lbl, openButton, startButton, textArea, textField, textButton);  
    vbox.setSpacing(10);
    vbox.setPadding(new Insets(15));
    lbl.setText("This tool creates virtual automata based \ron the file.");

    Scene scene = new Scene(vbox, 640, 480);
    primaryStage.setScene(scene);
    primaryStage.show();  

    openButton.setOnAction(
        new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
                File file = fileChooser.showOpenDialog(primaryStage);
                if (file != null) {
                    //Execute the method to convert to string array before sending to file parser                           
                    try {
                        fileParser.convertFile(file);                           
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        });


    textButton.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            text = textField.getText();                              
        }
    });

    startButton.setOnAction(new EventHandler <ActionEvent>()
    {
        public void handle(ActionEvent event)
        {
            machineCreation();

            String exit = "no";
            String nextLine = null;
            ArrayList<String> listOfCurrentTransitions = new ArrayList<String>();
            int nextInt = 0;
            states = initialStates;

            while(!(exit.toLowerCase().equals("yes"))) {
                textArea.appendText("Choose a state to load");

                //Print out the states possible for each machine
                ArrayList<String> tempTrans = machines.get(nextInt).getTransitions();
                //This loops through the list of transitions of the machine and pulls possible transitions from its current state
                for(int i = 0; i < tempTrans.size(); i++) {
                    String pull = tempTrans.get(i);
                    String[] apart = pull.split(" ");
                    pull = apart[0];
                    if(states.get(Integer.toString(nextInt)).equals(pull)) {
                        listOfCurrentTransitions.add(tempTrans.get(i));
                    }
                }
                if(!(listOfCurrentTransitions.isEmpty())) {
                    textArea.appendText("The following transitions are possible. Choose one: " + listOfCurrentTransitions);
                }       
                else {
                    textArea.appendText("No transitions for this machine exist from its current state");
                }

    //Tell GUI to wait for user input in textField and execute textButton which assigns to String text. Resume on button click.

1 个答案:

答案 0 :(得分:0)

while循环阻塞了JavaFX应用程序线程,该线程阻止了GUI的更新和事件的处理。

您需要在每个“文本提交”上执行循环的一次迭代的逻辑:

private TextArea textArea;

private void activateState(int nextInt) {
    ArrayList<String> listOfCurrentTransitions = new ArrayList<String>();
    textArea.appendText("Choose a state to load");

    //Print out the states possible for each machine
    ArrayList<String> tempTrans = machines.get(nextInt).getTransitions();
    //This loops through the list of transitions of the machine and pulls possible transitions from its current state
    for(int i = 0; i < tempTrans.size(); i++) {
        String pull = tempTrans.get(i);
        String[] apart = pull.split(" ");
        pull = apart[0];
        if(states.get(Integer.toString(nextInt)).equals(pull)) {
            listOfCurrentTransitions.add(tempTrans.get(i));
        }
    }
    if(listOfCurrentTransitions.isEmpty()) {
        textArea.appendText("No transitions for this machine exist from its current state");
    } else {
        textArea.appendText("The following transitions are possible. Choose one: " + listOfCurrentTransitions);
    }
}

@Override
public void start(Stage primaryStage) throws Exception {
    ...

    textArea = new TextArea();

    ...

    startButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            machineCreation();
            activateState(0);
        }
    });
    textButton.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            // read input and ask for more input...
            int nextState = Integer.parseInt(textField.getText()); // TODO: deal with invalid input
            activateState(nextState);                        
        }
    });

您可能需要稍微修改一下逻辑以验证过渡是否有效,更改某些字段的值等等...