Проблема, связанная с обработкой и обновлением событий в JavaFX GUI - PullRequest
0 голосов
/ 06 июля 2018

извинения за длину моего кода. Прошлой ночью я понял, что нахожусь на неверном пути, и теперь застрял в проблеме, которая, как мне кажется, связана с обработкой событий JavaFX. Первоначально у меня была логика, работающая вне GUI в базовом цикле, который зависел от взаимодействия через консоль. Все работало отлично. Я сейчас попытался заставить это работать в GUI с взаимодействием от пользователя.

У меня две основные проблемы с кодом ниже.

Во-первых, текст в textArea не обновляется дополнительным текстом после того, как startButton выполняет запуск моей основной логической последовательности. Первое добавление начинается прямо под первым циклом while. Я надеялся, что это отобразится в графическом интерфейсе при выполнении логики. Я не уверен, нужно ли мне указывать графический интерфейс для обновления через определенные промежутки времени или что-то еще не так.

Во-вторых, я не уверен, как заставить программу ждать, пока пользователь введет что-то в textField, прежде чем нажимать текстовую кнопку, которую я создал, чтобы продолжить. Раньше я создавал сканер, который заставлял программу ждать ввода в консоли. Я понимаю, что мне нужен какой-то способ заставить его ждать нажатия кнопки, когда он работает внутри 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 голосов
/ 06 июля 2018

Цикл while блокирует поток приложения JavaFX, который предотвращает обновления графического интерфейса пользователя и обработку событий.

Вместо этого вам нужно выполнить логику одной итерации цикла для каждого «текстового коммита»:

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);                        
        }
    });

Возможно, вам нужно немного исправить логику, чтобы убедиться, что переход действителен, изменить значения некоторых полей и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...