Search code examples
javaexceptioncustom-exceptions

Java custom exception not working properly


I'm creating a little Timer program that has 3 input fields (hours, minutes and seconds). For some reason, the OverTwentyFourException exception doesn't work for the hours input field. Here's parts of my code:

static JTextField userInputHrs;
static JTextField userInputMins;
static JTextField userInputSecs;
static int hrsChosen;
static int minsChosen;
static int secsChosen;

startButton.addActionListener(e -> {
        switch(startButton.getIcon().toString()) {
            case "Pause":
                timer.TimerFunctionality.pause();
                break;
            case "Resume":
                timer.TimerFunctionality.resume();
                break;
            default:
                try {
                    //Calculate seconds from user input
                    hrsChosen = Integer.parseInt(userInputHrs.getText());
                    minsChosen = Integer.parseInt(userInputMins.getText());
                    secsChosen = Integer.parseInt(userInputSecs.getText());
                    secsRemaining = hrsChosen * 3600 +  minsChosen * 60 + secsChosen;
                    if(hrsChosen < 0 || minsChosen < 0 || secsChosen < 0)
                        throw new NegativeException();
                    if(hrsChosen > 24)
                        throw new OverTwentyFourException();
                    //Getter for two thirds of userInput for color change
                    twoThirdsInput = 66.66 * secsRemaining / 100;
                    //Getter for one third of userInput for color change
                    oneThirdInput = 33.33 * secsRemaining / 100;
                    timer.TimerFunctionality.start();
                }
                catch(NegativeException ee) {
                    userInputHrs.setText("00");
                    userInputMins.setText("00");
                    userInputSecs.setText("00");
                }
                catch(OverTwentyFourException ee) {
                    userInputHrs.setText("00");
                }
                catch(NumberFormatException ee) {
                    userInputHrs.setText("00");
                    userInputMins.setText("00");
                    userInputSecs.setText("00");
                    JOptionPane.showMessageDialog(
                            Gui.this, "INPUT ERROR: Please use digits",
                            "Invalid Input",
                            JOptionPane.ERROR_MESSAGE
                    );
                }
        }
    });

OverTwentyFourException class:

class OverTwentyFourException extends Exception {
OverTwentyFourException() {
    Gui gui = new Gui();
    JOptionPane.showMessageDialog(
            gui,
            "INPUT ERROR: The 'Hours' number needs to be lower than 24",
            "Invalid Input - Hours",
            JOptionPane.ERROR_MESSAGE
    );
}

}

If I type '25' inside the hours field, I get the message dialog but the text is not set back to '00' as per my code, and the buttons stop working. I don't understand why as the minutes and seconds fields work perfectly and they're idendical. I don't see any difference between hrsChosen and minsChosen / secsChosen


Solution

  • You've got things backwards here as you're trying to handle the exception from within the exception itself, and that's not what is supposed to be happening. Instead simply have your custom exception class extend the Exception class, perhaps give it a constructor that accepts a String, and call the super's constructor within it with the same String. e.g. the exception could look like this and just this:

    public class OverTwentyFourException extends Exception {
        // allow it to handle exceptions with or without a message String
        // the constructor below will call the super's default constructor
        public OverTwentyFourException() {}
    
        public OverTwentyFourException(String message) {
            super(message);
        }
    } 
    

    There are other Exception constructors that you could consider extending.

    The JOptionPane code should only be in code elsewhere that is supposed to be handling the exception, where you throw the exception.

    catch(OverTwentyFourException ee) {
        // **** JOptionPane code goes here ****
        userInputHrs.setText("00");
    }
    

    Note that your code is also a little unusual in that you're throwing and catching this same exception within the same method. You don't appear to be gaining much by doing this.

    Unrelated issues:

    • You appear to be mis-using the static modifier as you've got fields that should most definitely not be static, marked as such. It looks like you're trying to fix an access to non-static fields in the wrong way. Instead of making those fields static, you will want to avoid accessing them in any static way.
    • This looks strange: startButton.getIcon().toString(). Why would you want to get the String representation of an Icon? Have you printed this? It's not what you think it is, and it's likely messing up your program. Instead perhaps you want to get the ActionEvent's actionCommand.