1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

VERY simple: String index out of bounds exception

  1. Jul 9, 2012 #1
    1. The problem statement, all variables and given/known data

    I am making a very, very simple program that takes in the date (of type string) from the user in the form DD/MM/YYYY. It then confirms whether or not the date is legitimate or not. For example, 09/07/2012 is valid, but 09/17/2012 is not valid.

    My program compiles correctly, but no matter what input I give it, the program always generates an exception. Here is my code:

    Code (Text):
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.awt.event.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;

    public class VerifyDate
    {
        //static final int SLASH_1_INDEX = 2;
        //static final int SLASH_2_INDEX = 5;
        static final int JAN = 1;
        static final int FEB = 2;
        static final int MAR = 3;
        static final int APR = 4;
        static final int MAY = 5;
        static final int JUN = 6;
        static final int JUL = 7;
        static final int AUG = 8;
        static final int SEP = 9;
        static final int OCT = 10;
        static final int NOV = 11;
        static final int DEC = 12;
       
        static String date;
       
        static final int DAY_MAX = 31;
        static final int FEB_MAX = 28;
       
        //static int SLASH_1_INDEX = date.indexOf("/");
        //static int SLASH_2_INDEX = date.lastIndexOf("/");
       
        public static void main(String[] args)
        {
            JFrame frame = new JFrame();
            JPanel panel = new JPanel(new FlowLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new FlowLayout());
           
            final int FRAME_WIDTH = 450;
            final int FRAME_HEIGHT = 450;
           
            JTextField inputDate;
           
            frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
            frame.setTitle("Verify a date");
           
            JOptionPane.showMessageDialog(null,
                                 "This program verifies if the input is a correct date." +
                    " \nPress OK to continue.");
           
            JLabel label = new JLabel("Enter date (DD/MM/YYYY): ");
            inputDate = new JTextField(12);
            date = inputDate.getText();
           
            JButton b1 = new JButton("Verify date");
            b1.setVerticalTextPosition(AbstractButton.CENTER);
            b1.setHorizontalTextPosition(AbstractButton.LEADING);
            b1.setActionCommand("verify");
           
            b1.addActionListener(new Action());
           
            panel.add(label);
            panel.add(inputDate);
            panel.add(b1);
            frame.add(panel);
            frame.setVisible(true);
           
        }
       
        static class Action implements ActionListener
        {
            public void actionPerformed (ActionEvent e)
            {
                int SLASH_1_INDEX = date.indexOf("/");
                int SLASH_2_INDEX = date.lastIndexOf("/");
               
                int day = Integer.parseInt(date.substring(0, SLASH_1_INDEX));
                int month = Integer.parseInt(date.substring(SLASH_1_INDEX, SLASH_2_INDEX));
                int year = Integer.parseInt(date.substring(SLASH_2_INDEX));
               
                if (day <= 0 || day > DAY_MAX || month <= 0 || month > DEC || year <= 0)
                    JOptionPane.showMessageDialog(null, "The date specified is not valid");
                else if ((month == APR || month == JUN || month == SEP || month == NOV) && day == DAY_MAX)
                    JOptionPane.showMessageDialog(null, "The date specified is not valid");
                else if (month == FEB && day >= FEB_MAX)
                    JOptionPane.showMessageDialog(null, "The date specified is not valid");
                else
                    JOptionPane.showMessageDialog(null, date + " is a valid date.");
            }
        }
    }
    and here is the error:

    Code (Text):
    Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
        at java.lang.String.substring(Unknown Source)
        at VerifyDate$Action.actionPerformed(VerifyDate.java:80)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
        at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
        at java.awt.Component.processMouseEvent(Unknown Source)
        at javax.swing.JComponent.processMouseEvent(Unknown Source)
        at java.awt.Component.processEvent(Unknown Source)
        at java.awt.Container.processEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Window.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$000(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.awt.EventQueue$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue$2.run(Unknown Source)
        at java.awt.EventQueue$2.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)
    This is line 80 (the line that the exception refers to):

    Code (Text):
    int day = Integer.parseInt(date.substring(0, SLASH_1_INDEX));
    Why will my program refuse to do what it is supposed to? I tried putting '1', '2', and '3' as the index in question but to no avail.

    2. Relevant equations

    None.

    3. The attempt at a solution

    See above.
     
  2. jcsd
  3. Jul 10, 2012 #2

    Filip Larsen

    User Avatar
    Gold Member

    The substring method takes two parameters. Have you checked them both for validity? Can you find a very good reason why SLASH_1_INDEX might be -1?

    Also, for parsing dates you may want to use a parser, like SimpleDateFormat, to check validity of a date. If you really want to parse the string yourself, then you should be aware that you have several more errors in to correct in your code before you can expect it to work.
     
  4. Jul 10, 2012 #3
    Problem has been solved. Thank you for your help anyways. The text field was never turned into a string, because

    Code (Text):
    date = inputDate.getText();
    should have been in the Action subclass! Because that's what we want to be performed. Anyway, I moved that to the Action subclass, and I think I changed the substring indeces (subtracted 1) and it worked.

    As for checking validity of the date, the instructor wants us to just use if, try, and catch statements. The goal of this assignment was to introduce us to exception handling, and a little bit of simple GUI. The program now works (at least it has worked so far). Just in case anyone ever stumbles across this, I'll post my fixed code.

    Anyone who finds this useful, please do not copy and paste my code, I want it to help you, not do an assignment for you! And give credit where it is due if necessary.

    Code (Text):
    import javax.swing.*;
    import java.awt.*;
    import java.util.*;
    import java.awt.event.*;

    /**
    * VerifyDate class.
    *
    * GUI is located here. The user inputs a string in the format DD/MM/YYYY and the program will
    * tell the user if it is a valid date. Leap years are ignored. VerifyDate class contains an action listener
    * class to allow proper execution of the algorithm via a button.
    *  
    * @author
    * @version 1.0
    */

    public class VerifyDate
    {
        /**constants specify the numbers that represent months of the year*/
        static final int JAN = 1;
        static final int FEB = 2;
        static final int MAR = 3;
        static final int APR = 4;
        static final int MAY = 5;
        static final int JUN = 6;
        static final int JUL = 7;
        static final int AUG = 8;
        static final int SEP = 9;
        static final int OCT = 10;
        static final int NOV = 11;
        static final int DEC = 12;
       
        /**instantiate the input objects outside the main method, so they can be used in the Action class*/
        static String date;
        static JTextField inputDate;
       
        /**constants specify the most days in certain months*/
        static final int DAY_MAX = 31;
        static final int FEB_MAX = 28;
       
        public static void main(String[] args)
        {
            /**create new frame, panel, and set layout and close operation*/
            JFrame frame = new JFrame();
            JPanel panel = new JPanel(new FlowLayout());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new FlowLayout());
           
            /**constants specify size of frame*/
            final int FRAME_WIDTH = 450;
            final int FRAME_HEIGHT = 100;
           
            /**set frame size and title*/
            frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
            frame.setTitle("Verify a date");
           
            /**explains what the program does*/
            JOptionPane.showMessageDialog(null,
                                 "This program verifies if the input is a correct date." +
                    " \nPress OK to continue.");
           
            /**explains to the user the required format*/
            JOptionPane.showMessageDialog(null,
                                 "The date must be input in the format DD/MM/YYYY" +
                    " \nPress OK to continue.");
           
            /**new label that instructs user what to do, then creates textfield*/
            JLabel label = new JLabel("Enter date (DD/MM/YYYY): ");
            inputDate = new JTextField(12);
           
            /**create "verify date" button and its attributes*/
            JButton b1 = new JButton("Verify date");
            b1.setVerticalTextPosition(AbstractButton.CENTER);
            b1.setHorizontalTextPosition(AbstractButton.LEADING);
            b1.setActionCommand("verify");
           
            /**add action listener to perform action of the button*/
            b1.addActionListener(new Action());
           
            /**add labels and buttons etc. to panel, then add panel to frame. Then set visible*/
            panel.add(label);
            panel.add(inputDate);
            panel.add(b1);
            frame.add(panel);
            frame.setVisible(true);
           
        }
       
        /**class used to perform the action of the button*/
        static class Action implements ActionListener
        {
            public void actionPerformed (ActionEvent e)
            {
                /**try block: these actions are performed and checked for exceptions*/
                try
                {
                    /**extract String "date" from the textfield*/
                    date = inputDate.getText();
                   
                    /**constants specify the indeces of the separators (can be any character)*/
                    /**note that I could have searched the string and set these constants to the first
                    instance, and last instance (respectively) of the character '/', however, I chose to
                    adhere to the criteria that required the format DD/MM/YYYY. */
                    final int SLASH_1_INDEX = 2;
                    final int SLASH_2_INDEX = 5;
                   
                    /**extract the numbers for the day, month, and year from the input string*/
                    int day = Integer.parseInt(date.substring(0, SLASH_1_INDEX));
                    int month = Integer.parseInt(date.substring(SLASH_1_INDEX+1, SLASH_2_INDEX));
                    int year = Integer.parseInt(date.substring(SLASH_2_INDEX+1));
                   
                    /**various error messages if the incorrect combination of days, months, and years are given.*/
                    if (day <= 0 || day > DAY_MAX || month <= 0 || month > DEC || year <= 0)
                        JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                    else if ((month == APR || month == JUN || month == SEP || month == NOV) && day == DAY_MAX)
                        JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                    else if (month == FEB && day >= FEB_MAX)
                        JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                    /**this error is to require the use of a non-numerical character as the date separators*/
                    else if (date.charAt(SLASH_1_INDEX) == '1' || date.charAt(SLASH_2_INDEX) == '1'
                        || date.charAt(SLASH_1_INDEX) == '2' || date.charAt(SLASH_2_INDEX) == '2'
                    || date.charAt(SLASH_1_INDEX) == '3' || date.charAt(SLASH_2_INDEX) == '3'
                    || date.charAt(SLASH_1_INDEX) == '4' || date.charAt(SLASH_2_INDEX) == '4'
                    || date.charAt(SLASH_1_INDEX) == '5' || date.charAt(SLASH_2_INDEX) == '5'
                    || date.charAt(SLASH_1_INDEX) == '6' || date.charAt(SLASH_2_INDEX) == '6'
                    || date.charAt(SLASH_1_INDEX) == '7' || date.charAt(SLASH_2_INDEX) == '7'
                    || date.charAt(SLASH_1_INDEX) == '8'|| date.charAt(SLASH_2_INDEX) == '8'
                    || date.charAt(SLASH_1_INDEX) == '9' || date.charAt(SLASH_2_INDEX) == '9'
                    || date.charAt(SLASH_1_INDEX) == '0' || date.charAt(SLASH_2_INDEX) == '0')
                        JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                    /**requires a 4 digit year*/
                    else if (year < 1000 || year > 9999)
                        JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                    else
                        JOptionPane.showMessageDialog(null, date + " is a valid date.");
                }
                /**incorrect number format exception, give error message*/
                catch(NumberFormatException exception)
                {
                    JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                }
                /**if the string is too small or too large (out of bounds exception), create error message*/
                catch(StringIndexOutOfBoundsException exception)
                {
                    JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                }
                /**if the string is null (null pointer exception), create error message*/
                /**this exception will never occur since the preceeding catch statements will always throw an exception
                that takes care of NullPointerException*/
                catch(NullPointerException exception)
                {
                    JOptionPane.showMessageDialog(null, date + " is not a valid date.");
                }
            }
        }
    }
     
    Last edited: Jul 10, 2012
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: VERY simple: String index out of bounds exception
  1. Very simple RC-circuit (Replies: 11)

Loading...