VERY simple: String index out of bounds exception

In summary, a String index out of bounds exception is an error that occurs when trying to access or manipulate a character in a String at an index that does not exist. It can be caused by a few different things, such as an out of range index or a null or empty String. To fix and prevent this exception, it is important to carefully check and validate the index being used, handle potential errors, and use built-in methods in Java. To debug this exception, tools such as a debugger and try-catch blocks can be used to identify the cause of the error.
  • #1
stripes
266
0

Homework Statement



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:
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:
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:
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.

Homework Equations



None.

The Attempt at a Solution



See above.
 
Physics news on Phys.org
  • #2
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 into correct in your code before you can expect it to work.
 
  • #3
Problem has been solved. Thank you for your help anyways. The text field was never turned into a string, because

Code:
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:
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:

Related to VERY simple: String index out of bounds exception

What is a String index out of bounds exception?

A String index out of bounds exception is an error that occurs when trying to access or manipulate a character in a String at an index that does not exist. This can happen if the index is negative, or if it is greater than or equal to the length of the String.

What causes a String index out of bounds exception?

A String index out of bounds exception can be caused by a few different things. It can occur if the index being accessed is out of range, such as a negative index or an index greater than or equal to the length of the String. It can also happen if the String being accessed is null or empty.

How can I fix a String index out of bounds exception?

To fix a String index out of bounds exception, you will need to identify where the error is occurring and make sure that the index being accessed is within the range of the String. You may also need to check if the String is null or empty before trying to access it. You can also use the built-in methods in Java, such as the charAt() method, to ensure that the index being accessed is within the bounds of the String.

Can a String index out of bounds exception be prevented?

Yes, a String index out of bounds exception can be prevented by carefully checking and validating the index being used to access a String. It is also good practice to handle potential errors, such as a null or empty String, to avoid unexpected exceptions. Using built-in methods in Java, such as length() and isEmpty(), can also help prevent this type of exception.

How can I debug a String index out of bounds exception?

To debug a String index out of bounds exception, you can use tools such as a debugger or printing statements to track the values of variables and identify where the error is occurring. You can also use try-catch blocks to handle the exception and print out the specific error message to get more information about the cause of the error.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Programming and Computer Science
Replies
3
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
8
Views
12K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
5K
  • Engineering and Comp Sci Homework Help
Replies
4
Views
2K
Back
Top