Как я могу сделать actionPerformed внутри оператора switch? - PullRequest
0 голосов
/ 17 октября 2019

Я пытаюсь создать простую программу с графическим интерфейсом, основанную на командной строке (т.е. введите команду и нажмите кнопку ввода). Всякий раз, когда пользователь нажимает кнопку ввода, вся информация, введенная им в JTextArea, обрабатывается, а затем выводится на основе его ввода (например, ввода / выхода для закрытия программы).

Всякий раз, когдаПользователь вводит / выходит, появляется запрос, спрашивающий пользователя, уверены ли они, что хотят выйти. Однако, как только это появляется, оно заменяется недействительным вводимым сообщением, которое я вставляю, если пользователь вводит что-то, что не было распознано. Моя единственная причина, по которой это происходит, заключается в том, что класс ActionListener все еще имеет / выход, сохраненный в строке inputHolder, которая является строкой, которую я использую для хранения входных данных пользователя и их обработки.

package msai;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MainFrame extends JFrame implements ActionListener {
    JTextArea output;
    JButton inputButton;
    JTextArea commandLine;
    String inputHolder;
    String invalid = "Invalid input!";

    public MainFrame() {
        super("MSAI");
        setLookAndFeel();
        setSize(650, 350);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FlowLayout flo = new FlowLayout();
        setLayout(flo);

        output = new JTextArea("Hi! I'm MSAI. Type any command to get started, or type /help for a list of commands and syntax!", 8, 40);
        inputButton = new JButton("ENTER");
        inputButton.addActionListener(this);
        commandLine = new JTextArea(8, 40);
        commandLine.setLineWrap(true);
        commandLine.setWrapStyleWord(true);
        JScrollPane scroll = new JScrollPane(commandLine, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        add(output);
        add(inputButton);
        add(scroll);

        setVisible(true);

    }

    public void actionPerformed(ActionEvent event) {

        inputHolder = commandLine.getText();
        switch(inputHolder) {
            "/exit":
                output.setText("Are you sure you want to terminate this session?");
                inputHolder = commandLine.getText();
                switch(inputHolder.toUpperCase()) {
                    case "YES":
                        System.exit(0);
                        break;
                    case "NO":
                        output.setText("Your session has not been terminated.");
                        break;
                    default:
                        output.setText(invalid);
                        break;
            }
        } 
    }  
    private void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel(
            "javax.swing.plaf.nimbus.NimbusLookAndFeel"
            );
        } catch (Exception exc) {
            //ignore error
        }
    }


    public static void main(String[] args) {
        MainFrame frame = new MainFrame();
    }
}

В настоящее время мой единственныйЧтобы решить эту проблему, нужно добавить другой оператор actionPerformed в оператор / switch, но я не уверен, как это сделать, или это даже лучшее решение. Я буду рад любым ответам и отзывам, только, пожалуйста, не будьте токсичными!

Ответы [ 2 ]

0 голосов
/ 17 октября 2019

Проблема в том, что код в вашем actionPeformed полностью выполняется, и у пользователя нет возможности ввести ДА или НЕТ и нажать кнопку «ВВОД». Внутренний переключатель выполняется с параметром inputHolder, имеющим значение «/ exit», что приводит к регистру по умолчанию.

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

Вот код, который пытается приблизиться к вашей первоначальной идее.

    boolean exitCommand = false;  //has the user issued exit command?


    public void actionPerformed(ActionEvent event) {
        inputHolder = commandLine.getText();
        if (exitCommand){
            switch (inputHolder.toUpperCase()) {
                    case "YES":
                        System.exit(0);
                        break;
                    case "NO":
                        exitCommand = false; //forget exit command.
                        output.setText("Your session has not been terminated.");
                        break;
                    default:
                        output.setText(invalid);
                        break;
                }
        }


        switch (inputHolder) {
            case "/exit": 
                exitCommand = true;
                commandLine.setText("");
                output.setText("Are you sure you want to terminate this session?");
                inputHolder = commandLine.getText();
                if (!exitCommand) {
                    exitCommand = true;
                    return;
                }  

        }
    }
0 голосов
/ 17 октября 2019

Когда вы делаете

output.setText("Are you sure you want to terminate this session?");
inputHolder = commandLine.getText();

Пользователь еще не обновил commandLine и не нажал кнопку, поэтому ничего не изменилось. Вам нужно «подождать», пока пользователь ответит второй раз.

Вам нужно перенести «состояние» запроса на следующий раз, когда вызывается ActionPerformed, например ...

private boolean wantsToExit = false
public void actionPerformed(ActionEvent event) {

    inputHolder = commandLine.getText();

    if (wantsToExit) {
        if (wantsToExit && inputHolder.equals("YES")) {
            // Better to close the frame and let the system deal with it
        } else if (wantsToExit && inputHolder.equals("NO")) {
            output.setText("Your session has not been terminated.");
        }
        wantsToExit = false;
    } else {
        switch(inputHolder) {
            "/exit":
                wantsToExit = true;
                output.setText("Are you sure you want to terminate this session?");
                break;
        } 
    }  
}

Если вы хотите сделать это в одном потоке, то вам следует рассмотреть возможность использования JOptionPane, чтобы запросить пользователя вместо

...