Мне трудно перейти к нужному участку цикла

Я пытаюсь сделать так, чтобы пользователь ввел числитель и знаменатель и отобразил частное. Я использую метод, чтобы проверить и убедиться, что номер действителен, используя Integer.parseInt и попытку улова. Проблема в том, что если try catch перехватывает исключение и отображает ошибку, он переходит к следующей части кода, а не возвращается к началу цикла.

public static void main(String[] args) {
        String numerator = "";
        String denominator = "";
        String message = "";
        int num = 0;
        int den = 0;
        int quo = 0;
        int yesNo = 0;
        do
        {
            // Displays a JOptionPane asking the user to input a numerator.
            numerator = JOptionPane.showInputDialog(null, "Please enter a numerator.", "Enter a Numerator",JOptionPane.QUESTION_MESSAGE);
            if(numerator == null)// This breaks the loop if  the user clicks the "cancel" button.
                break;
            num = IsValid(numerator); // Calls the IsValid method, passing it the String entered by the user to validate if it is a proper integer.
            denominator = JOptionPane.showInputDialog(null, "Please enter a denominator.", "Enter a Denominator",JOptionPane.QUESTION_MESSAGE);
            if(denominator == null) // same as above but for the denominator
                break;
            den = IsValid(denominator);
            /*if(den != 0 && num<den) 
            { // This section is unrelated to my problem
                quo = num/den;
                message = "Numerator: " + num + "\n" +
                            "Denominator: " + den + "\n" +
                            "Quotient: ";
                JOptionPane.showMessageDialog(null, message,"Calculation",JOptionPane.INFORMATION_MESSAGE);
            }*/
            yesNo = JOptionPane.showConfirmDialog(null,"Would you like to make another calculation?","Continue?",JOptionPane.YES_NO_OPTION);
        }while(yesNo == JOptionPane.YES_OPTION);
    }
    public static int IsValid(String input)
    {
        int num = 0; // This method is passed the String that the JOptionPane receives and using Integer.parseInt to make sure it's an integer, and assigns it to int "num".
        try{num = Integer.parseInt(input);}
        catch(NumberFormatException ex)
        {
            JOptionPane.showMessageDialog(null, "Error: Invalid number. Please enter a valid number.","Invalid Input",JOptionPane.WARNING_MESSAGE);
        }
        return num;
        // My main issue is that it continues with the code instead of jumping back to the JOptionPane to ask the user for input a second time.
    }

По сути, я хочу вызвать IsValid(numerator) и присвоить его int «num», и если выполняется оператор catch IsValid, вернуться к началу цикла do, чтобы он снова отображал эту JOptionPane. Если оператор catch выполняется для знаменателя, вернитесь к нему, а не к самому началу. Я не могу поместить JOptionPane в метод, потому что метод не сможет определить, отправляю ли я ему числитель или знаменатель. Я новичок в java, и я уверен, что есть более простые способы сделать это, поэтому ЛЮБАЯ помощь приветствуется. Спасибо!


person coreynj    schedule 23.04.2019    source источник
comment
Выбросить исключение из isValid, перехватить его и обработать в цикле   -  person rdas    schedule 23.04.2019
comment
Да, проблема в том, что вы ловите, но не распространяете исключение. Вы всегда просто возвращаетесь в int. Таким образом, процедура более высокого уровня не может сказать, правильно ли пользователь набрал что-то или нет. Что вы можете рассмотреть, так это изменить isValid на цикл, который не выходит до тех пор, пока не будет введено действительное число. Тогда вам не нужно генерировать исключение, и вы также сможете всегда возвращать действительное число.   -  person markspace    schedule 23.04.2019
comment
Вот так?: ``` try{num = IsValid(numerator)} catch(NumberFormatException ex){} ``` И затем внутри метода выполните: if(whatever) { throw NumberFormatException; } Или я совсем не прав?   -  person coreynj    schedule 23.04.2019
comment
Я ожидаю, что функция с именем IsValid вернет логическое значение. Вы должны назвать это ParseNumber или что-то подобное.   -  person Frank Puffer    schedule 23.04.2019
comment
Моя проблема с использованием цикла внутри метода заключается в том, что метод не может определить, отправляется ли ему числитель или знаменатель, и должен говорить расплывчатые вещи, такие как Пожалуйста, введите число вместо того, чтобы быть конкретным.   -  person coreynj    schedule 23.04.2019
comment
Передайте строку в качестве аргумента методу, где строка — это сообщение, которое вы хотите отобразить в цикле.   -  person markspace    schedule 23.04.2019


Ответы (1)


Вызов isValid должен прервать вашу программу, если ввод недействителен. Самый естественный способ - позволить ему генерировать исключение. Затем ваша программа перехватывает исключение и завершает работу.

package so20190423;

import java.awt.HeadlessException;

import javax.swing.JOptionPane;

public class Snippet {
    public static void main(String[] args) {
            String numerator = "";
            String denominator = "";
            String message = "";
            int num = 0;
            int den = 0;
            int quo = 0;
            int yesNo = 0;
            try {
                do
                {
                    // Displays a JOptionPane asking the user to input a numerator.
                    numerator = JOptionPane.showInputDialog(null, "Please enter a numerator.", "Enter a Numerator",JOptionPane.QUESTION_MESSAGE);
                    if(numerator == null)// This breaks the loop if  the user clicks the "cancel" button.
                        break;
                    num = IsValid(numerator); // Calls the IsValid method, passing it the String entered by the user to validate if it is a proper integer.
                    denominator = JOptionPane.showInputDialog(null, "Please enter a denominator.", "Enter a Denominator",JOptionPane.QUESTION_MESSAGE);
                    if(denominator == null) // same as above but for the denominator
                        break;
                    den = IsValid(denominator);
                    /*if(den != 0 && num<den) 
                    { // This section is unrelated to my problem
                        quo = num/den;
                        message = "Numerator: " + num + "\n" +
                                    "Denominator: " + den + "\n" +
                                    "Quotient: ";
                        JOptionPane.showMessageDialog(null, message,"Calculation",JOptionPane.INFORMATION_MESSAGE);
                    }*/
                    yesNo = JOptionPane.showConfirmDialog(null,"Would you like to make another calculation?","Continue?",JOptionPane.YES_NO_OPTION);
                }while(yesNo == JOptionPane.YES_OPTION);
            }
            catch(NumberFormatException ex)
            {
                JOptionPane.showMessageDialog(null, "Error: Invalid number. Please enter a valid number.","Invalid Input",JOptionPane.WARNING_MESSAGE);
            }
        }
        public static int IsValid(String input) throws NumberFormatException
        {
            int num = 0; // This method is passed the String that the JOptionPane receives and using Integer.parseInt to make sure it's an integer, and assigns it to int "num".
            num = Integer.parseInt(input);
            return num;
            // My main issue is that it continues with the code instead of jumping back to the JOptionPane to ask the user for input a second time.
        }
}

Вы даже можете ограничить try/catch циклом while, чтобы восстановиться после неудачного ввода и повторить попытку!

package so20190423;

import java.awt.HeadlessException;

import javax.swing.JOptionPane;

public class Snippet {
    public static void main(String[] args) {
            String numerator = "";
            String denominator = "";
            String message = "";
            int num = 0;
            int den = 0;
            int quo = 0;
            int yesNo = 0;
                do
                {
                    try {
                    // Displays a JOptionPane asking the user to input a numerator.
                    numerator = JOptionPane.showInputDialog(null, "Please enter a numerator.", "Enter a Numerator",JOptionPane.QUESTION_MESSAGE);
                    if(numerator == null)// This breaks the loop if  the user clicks the "cancel" button.
                        break;
                    num = IsValid(numerator); // Calls the IsValid method, passing it the String entered by the user to validate if it is a proper integer.
                    denominator = JOptionPane.showInputDialog(null, "Please enter a denominator.", "Enter a Denominator",JOptionPane.QUESTION_MESSAGE);
                    if(denominator == null) // same as above but for the denominator
                        break;
                    den = IsValid(denominator);
                    /*if(den != 0 && num<den) 
                    { // This section is unrelated to my problem
                        quo = num/den;
                        message = "Numerator: " + num + "\n" +
                                    "Denominator: " + den + "\n" +
                                    "Quotient: ";
                        JOptionPane.showMessageDialog(null, message,"Calculation",JOptionPane.INFORMATION_MESSAGE);
                    }*/
                    yesNo = JOptionPane.showConfirmDialog(null,"Would you like to make another calculation?","Continue?",JOptionPane.YES_NO_OPTION);
                }
                catch(NumberFormatException ex)
                {
                    JOptionPane.showMessageDialog(null, "Error: Invalid number. Please enter a valid number.","Invalid Input",JOptionPane.WARNING_MESSAGE);
                }
                }while(yesNo == JOptionPane.YES_OPTION);
        }
        public static int IsValid(String input) throws NumberFormatException
        {
            int num = 0; // This method is passed the String that the JOptionPane receives and using Integer.parseInt to make sure it's an integer, and assigns it to int "num".
            num = Integer.parseInt(input);
            return num;
            // My main issue is that it continues with the code instead of jumping back to the JOptionPane to ask the user for input a second time.
        }
}


Последний вариант, если вы хотите повторять каждый ввод до тех пор, пока он не станет действительным (или не будет отменен пользователем):

package so20190423;

import javax.swing.JOptionPane;

public class Snippet {
    public static void main(String[] args) {
        String numerator = "";
        String denominator = "";
        String message = "";
        int num = 0;
        int den = 0;
        int quo = 0;
        int yesNo = 0;
        do {
            boolean userCancelled = false;
            boolean numeratorIsOk = false;
            do {
                try {
                    numerator = JOptionPane.showInputDialog(null, "Please enter a numerator.", "Enter a Numerator",
                            JOptionPane.QUESTION_MESSAGE);
                    if (numerator == null) {
                        userCancelled = true;
                    } else {
                        num = IsValid(numerator);
                        numeratorIsOk = true;
                    }
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "Error: Invalid number. Please enter a valid number.",
                            "Invalid Input", JOptionPane.WARNING_MESSAGE);
                }
            } while (!numeratorIsOk && !userCancelled);
            if (userCancelled) {
                break;
            }

            boolean denominatorIsOk = false;
            do {
                try {
                    denominator = JOptionPane.showInputDialog(null, "Please enter a denominator.",
                            "Enter a Denominator", JOptionPane.QUESTION_MESSAGE);
                    if (denominator == null) {
                        userCancelled = true;
                    } else {
                        den = IsValid(denominator);
                        denominatorIsOk = true;
                    }
                    /*
                     * if(den != 0 && num<den) { // This section is unrelated to my problem quo =
                     * num/den; message = "Numerator: " + num + "\n" + "Denominator: " + den + "\n"
                     * + "Quotient: "; JOptionPane.showMessageDialog(null,
                     * message,"Calculation",JOptionPane.INFORMATION_MESSAGE); }
                     */
                    yesNo = JOptionPane.showConfirmDialog(null, "Would you like to make another calculation?",
                            "Continue?", JOptionPane.YES_NO_OPTION);
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "Error: Invalid number. Please enter a valid number.",
                            "Invalid Input", JOptionPane.WARNING_MESSAGE);
                }

            } while (!denominatorIsOk && !userCancelled);
            if (userCancelled) {
                break;
            }
        } while (yesNo == JOptionPane.YES_OPTION);

    }

    public static int IsValid(String input) throws NumberFormatException {
        int num = 0; // This method is passed the String that the JOptionPane receives and using
                        // Integer.parseInt to make sure it's an integer, and assigns it to int "num".
        num = Integer.parseInt(input);
        return num;
        // My main issue is that it continues with the code instead of jumping back to
        // the JOptionPane to ask the user for input a second time.
    }
}

ХТХ!

person Highbrainer    schedule 23.04.2019
comment
Моя проблема заключается в том, что это приведет к возврату к началу цикла, а не к той части цикла, где возникает ошибка, т.е. если пользователь вводит недопустимый знаменатель, это заставит его повторно ввести числитель, чтобы получить действительный знаменатель. Я хочу, чтобы он перешел к знаменателю, если проблема заключается в знаменателе. - person coreynj; 23.04.2019
comment
@coreynj затем используйте два оператора try/catch, по одному для каждого вызова isValid, и добавьте цикл do-while, который повторно запускает try/isValid до тех пор, пока все не будет в порядке ... Смотрите мой обновленный ответ! - person Highbrainer; 24.04.2019