I am making an event calendar in Java and am having issues with a \"Java.lang.Ar
ID: 3730913 • Letter: I
Question
I am making an event calendar in Java and am having issues with a "Java.lang.ArrayIndexOutOfBoundsException" bug.
It usually pops up whenever I enter a date and press the "n" or "p" command a few times.
Appologies if the code below is messy.
thank you
import java.io.File;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.Scanner;
import java.util.*;
import java.io.*;
public class Assignment2 {
// sets the width of each cell in the calendar
private static int SIZE = 15;
private static char HORIZONTAL = '=';
private static char VERTICAL = '|';
private static boolean showLine = true;// to show the string date and month
// at end
private static String days[] = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"};
// static value, will be set to find the user specified date.. otherwise will remain -1.
private static int dayValue = -1;
private static String[][] eventArray;
public static boolean loadEventsFromFile(String filename)
{
eventArray = new String[12][];
for(int i = 0; i < 12; i++)
eventArray[i] = new String[getMaximumDays(i)];
try {
Scanner input = new Scanner(new File(filename));
while(input.hasNext())
{
String date = input.next();
String event = input.nextLine().trim();
int day = dayFromDate(date);
int month = monthFromDate(date);
eventArray[month-1][day-1] = event;
}
input.close();
return true;
} catch (FileNotFoundException e) {
//nothing to do if file does not exist
return false;
}
}
public static void drawMonth(PrintStream out, int month, int daysToSkip, int maxDays) {
// calculate the near center where to display month number
int center = SIZE * 3;
String space = " ";
// display blanks upto center
for (int i = 0; i < center; i++)
out.print(space);
// now display month number
out.print(month + " ");
// print week days
for(int i=0; i<days.length; i++) {
out.printf("%-10s", days[i]);
}
out.println();
int start = 1;
// display the days
while (start <= maxDays) {
if(start == 1) {
// first row may need to skip some days
drawRow(out, start, month, maxDays, daysToSkip);
start += 7 - daysToSkip;
} else {
drawRow(out, start, month, maxDays, 0);
start += 7;
}
}
// draw the final horizontal line with HORIZONTAL character
int width = SIZE * 7;
String str = "";
for (int i = 0; i <= width; i++)
str += HORIZONTAL;
out.println(str);
}
public static void drawRow(PrintStream out,int start, int month, int maxDaysInMonth, int skip) {
// total width of the row
String str = "";
int width = SIZE * 7;
// 1st line: make string full of horizontal characters for total width
// and display it
for (int i = 0; i <= width; i++)
str += HORIZONTAL;
out.println(str);
// 2nd line consist of vertical character followded by day number
// followed by padding spaces to match the size of cell
// this pattern of <day> <padding> <vertical_char> will repeat for each
// cell
int day = start;
String space = " ";
out.print("|");
for (int cell = 1; cell <= 7; cell++) {
str = "";
if (cell > skip && day <= maxDaysInMonth) {
if(dayValue == day) {
str += "*" + day++ + "*";
} else {
str += day++;
}
}
// pad it with extra spaces to match SIZE
while (str.length() < SIZE - 1)
str += space;
str += VERTICAL;
out.print(str);
}
// now remaining lines will be similar to above but the day number is
// not there... only spaces padded to match cell SIZE
// the pattern for each cell is <padding_spaces><vertical_char>
int height = SIZE / 2;
day = start;
for (int h = 2 ; h <= height; h++) {
out.print(" |");
for (int cell = 1; cell <= 7; cell++, day++) {
str = "";
if(h == 2 && cell > skip && day <= maxDaysInMonth && eventArray[month-1][day-1] != null)
str = eventArray[month-1][day-1];
while (str.length() < SIZE - 1)
str += space;
str += VERTICAL;
out.print(str);
}
}
out.print(" ");
}
public static void displayDate(PrintStream out,int month, int day) {
if (showLine == true) {
out.println("Month: " + month);
out.println("Day: " + day);
}
}
public static int monthFromDate(String date) {
// split the date into 2 based on / delimiter
String tokens[] = date.split("/");
// convert 1st token and return as month
return Integer.parseInt(tokens[0]);
}
public static int dayFromDate(String date) {
// split the date into 2 based on / delimiter
String tokens[] = date.split("/");
// convert 2nd token and return as day
return Integer.parseInt(tokens[1]);
}
public static void drawCalendar(PrintStream out, int month, int day) {
int startingDay = getStartingDay(month);
int maxDays = getMaximumDays(month);
drawMonth(out, month, startingDay, maxDays);
displayDate(out, month, day);
}
// method to correctly return the next month
public static int nextGoodMonth(int month) {
int mt = month;
if (month == 12)
return 1;
return mt + 1;
}
// method to correctly return the previous month
public static int previousGoodMonth(int month) {
int mt = month;
if (month == 1)
return 12;
return mt - 1;
}
// get what is the starting day of the month
public static int getStartingDay(int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
// in calendar, month starts from 0
cal.set(Calendar.MONTH, month - 1);
return cal.get(Calendar.DAY_OF_WEEK) - 1;
}
// get what is the maximum no of days in the month
public static int getMaximumDays(int month) {
Calendar cal = Calendar.getInstance();
// in calendar, month starts from 0
cal.set(Calendar.MONTH, month - 1);
return cal.getActualMaximum(Calendar.DATE);
}
public static void main(String[] args) {
Scanner keybd = new Scanner(System.in);
String cmd = "";
int day = -1;
int month = -1;
loadEventsFromFile("calendarEvents.txt"); //load events at start up
while (true) {
System.out.println("Please type a command");
System.out.println(" "e" to enter a date and display the corresponding calendar.");
System.out.println(" "ev" to enter an event.");
System.out.println(" "fp" to print calendar to file");
System.out.println(" "t" to get todays date and display the todays calendar");
System.out.println(" "n" to display the next month");
System.out.println(" "p" to display the previous month");
System.out.println(" "q" to quit the progrram");
cmd = keybd.nextLine();
if (cmd.equalsIgnoreCase("e")) {
// get user input date
System.out.print("Enter a date (m/d): ");
String date = keybd.nextLine();
dayValue = day = dayFromDate(date);
month = monthFromDate(date);
showLine = true;
drawCalendar(System.out, month, day);
continue;
}
else if (cmd.equalsIgnoreCase("ev")) {
// get user input date
System.out.print("Enter an event (m/d event_title): ");
String date = keybd.next();
String event = keybd.nextLine().trim();
int d = dayFromDate(date);
int m = monthFromDate(date);
eventArray[m-1][d-1] = event;
}
else if (cmd.equalsIgnoreCase("t")) {
Calendar cal = Calendar.getInstance();
dayValue = day = cal.get(Calendar.DATE);
month = cal.get(Calendar.MONTH) + 1;
System.out.println(" Displaying calendar for today's date "
+ month + "/" + day);
showLine = true;
drawCalendar(System.out, month, day);
} else if (cmd.equalsIgnoreCase("n")) {
if (day != -1 && month != -1) {
day = 1;
dayValue = -1; // as user has not mentioned any value specifically
month = nextGoodMonth(month);
System.out.println(" Displaying calendar for next month "
+ month);
showLine = true;
drawCalendar(System.out, month, day);
continue;
} else {
System.out.println("Please display a calendar first. ");
continue;
}
} else if (cmd.equalsIgnoreCase("p")) {
if (day != -1 && month != -1) {
day = 1;
// as user has not mentioned any value specifically
dayValue = -1;
month = previousGoodMonth(month);
System.out.println(" Displaying calendar for previous month "
+ month);
showLine = true;
drawCalendar(System.out, month, day);
continue;
} else {
System.out.println("Please display a calendar first. ");
continue;
}
}
else if (cmd.equalsIgnoreCase("fp")) {
System.out.print(" Enter month to print (1-12):");
month = keybd.nextInt();
System.out.print("Enter filename: ");
String fname = keybd.next().trim();
keybd.nextLine();//remove newline
dayValue = -1;
try {
PrintStream outfile = new PrintStream(new File(fname));
drawCalendar(outfile, month, day);
outfile.close();
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
}
else if (cmd.equalsIgnoreCase("q")) {
System.out.println("Thank you for using the calendar app.");
System.out.println("Have a nice day.");
break;
} else {
System.out.println("Please enter a valid command. ");
continue;
}
}
keybd.close();
}
}
Explanation / Answer
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Calendar;
import java.util.Scanner;
public class Assignment2 {
// sets the width of each cell in the calendar
private static int SIZE = 15;
private static char HORIZONTAL = '=';
private static char VERTICAL = '|';
private static boolean showLine = true;// to show the string date and month
// at end
private static String days[] = {"Sun", "Mon", "Tue", "Wed", "Thur", "Fri", "Sat"};
// static value, will be set to find the user specified date.. otherwise will remain -1.
private static int dayValue = -1;
private static String[][] eventArray;
public static boolean loadEventsFromFile(String filename)
{
eventArray = new String[12][];
for(int i = 0; i < 12; i++)
eventArray[i] = new String[getMaximumDays(i)];
try {
Scanner input = new Scanner(new File(filename));
while(input.hasNext())
{
String date = input.next();
String event = input.nextLine().trim();
int day = dayFromDate(date);
int month = monthFromDate(date);
eventArray[month-1][day-1] = event;
}
input.close();
return true;
} catch (FileNotFoundException e) {
//nothing to do if file does not exist
return false;
}
}
public static void drawMonth(PrintStream out, int month, int daysToSkip, int maxDays) {
// calculate the near center where to display month number
int center = SIZE * 3;
String space = " ";
// display blanks upto center
for (int i = 0; i < center; i++)
out.print(space);
// now display month number
out.print(month + " ");
// print week days
for(int i=0; i<days.length; i++) {
out.printf("%-10s", days[i]);
}
out.println();
int start = 1;
// display the days
while (start <= maxDays) {
if(start == 1) {
// first row may need to skip some days
drawRow(out, start, month, maxDays, daysToSkip);
start += 7 - daysToSkip;
} else {
drawRow(out, start, month, maxDays, 0);
start += 7;
}
}
// draw the final horizontal line with HORIZONTAL character
int width = SIZE * 7;
String str = "";
for (int i = 0; i <= width; i++)
str += HORIZONTAL;
out.println(str);
}
public static void drawRow(PrintStream out,int start, int month, int maxDaysInMonth, int skip) {
// total width of the row
String str = "";
int width = SIZE * 7;
// 1st line: make string full of horizontal characters for total width
// and display it
for (int i = 0; i <= width; i++)
str += HORIZONTAL;
out.println(str);
// 2nd line consist of vertical character followded by day number
// followed by padding spaces to match the size of cell
// this pattern of <day> <padding> <vertical_char> will repeat for each
// cell
int day = start;
String space = " ";
out.print("|");
for (int cell = 1; cell <= 7; cell++) {
str = "";
if (cell > skip && day <= maxDaysInMonth) {
if(dayValue == day) {
str += "*" + day++ + "*";
} else {
str += day++;
}
}
// pad it with extra spaces to match SIZE
while (str.length() < SIZE - 1)
str += space;
str += VERTICAL;
out.print(str);
}
// now remaining lines will be similar to above but the day number is
// not there... only spaces padded to match cell SIZE
// the pattern for each cell is <padding_spaces><vertical_char>
int height = SIZE / 2;
day = start;
for (int h = 2 ; h <= height; h++) {
out.print(" |");
for (int cell = 1; cell <= 7; cell++, day++) {
str = "";
if(h == 2 && cell > skip && day <= maxDaysInMonth && eventArray[month-1][day-1] != null)
str = eventArray[month-1][day-1];
while (str.length() < SIZE - 1)
str += space;
str += VERTICAL;
out.print(str);
}
}
out.print(" ");
}
public static void displayDate(PrintStream out,int month, int day) {
if (showLine == true) {
out.println("Month: " + month);
out.println("Day: " + day);
}
}
public static int monthFromDate(String date) {
// split the date into 2 based on / delimiter
String tokens[] = date.split("/");
// convert 1st token and return as month
return Integer.parseInt(tokens[0]);
}
public static int dayFromDate(String date) {
// split the date into 2 based on / delimiter
String tokens[] = date.split("/");
// convert 2nd token and return as day
return Integer.parseInt(tokens[1]);
}
public static void drawCalendar(PrintStream out, int month, int day) {
int startingDay = getStartingDay(month);
int maxDays = getMaximumDays(month);
drawMonth(out, month, startingDay, maxDays);
displayDate(out, month, day);
}
// method to correctly return the next month
public static int nextGoodMonth(int month) {
int mt = month;
if (month == 12)
return 1;
return mt + 1;
}
// method to correctly return the previous month
public static int previousGoodMonth(int month) {
int mt = month;
if (month == 1)
return 12;
return mt - 1;
}
// get what is the starting day of the month
public static int getStartingDay(int month) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
// in calendar, month starts from 0
cal.set(Calendar.MONTH, month - 1);
return cal.get(Calendar.DAY_OF_WEEK) - 1;
}
// get what is the maximum no of days in the month
public static int getMaximumDays(int month) {
Calendar cal = Calendar.getInstance();
// in calendar, month starts from 0
cal.set(Calendar.MONTH, month - 1);
//for december - day count is getting wrong
// i have fixed it manually
//but please find correct way to get proper day count for month
if(month == 11)
return 31;
return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
}
public static void main(String[] args) {
Scanner keybd = new Scanner(System.in);
String cmd = "";
int day = -1;
int month = -1;
loadEventsFromFile("calendarEvents.txt"); //load events at start up
while (true) {
System.out.println("Please type a command");
System.out.println(" "e" to enter a date and display the corresponding calendar.");
System.out.println(" "ev" to enter an event.");
System.out.println(" "fp" to print calendar to file");
System.out.println(" "t" to get todays date and display the todays calendar");
System.out.println(" "n" to display the next month");
System.out.println(" "p" to display the previous month");
System.out.println(" "q" to quit the progrram");
cmd = keybd.nextLine();
if (cmd.equalsIgnoreCase("e")) {
// get user input date
System.out.print("Enter a date (m/d): ");
String date = keybd.nextLine();
dayValue = day = dayFromDate(date);
month = monthFromDate(date);
showLine = true;
drawCalendar(System.out, month, day);
continue;
}
else if (cmd.equalsIgnoreCase("ev")) {
// get user input date
System.out.print("Enter an event (m/d event_title): ");
String date = keybd.next();
String event = keybd.nextLine().trim();
int d = dayFromDate(date);
int m = monthFromDate(date);
eventArray[m-1][d-1] = event;
}
else if (cmd.equalsIgnoreCase("t")) {
Calendar cal = Calendar.getInstance();
dayValue = day = cal.get(Calendar.DATE);
month = cal.get(Calendar.MONTH) + 1;
System.out.println(" Displaying calendar for today's date "
+ month + "/" + day);
showLine = true;
drawCalendar(System.out, month, day);
} else if (cmd.equalsIgnoreCase("n")) {
if (day != -1 && month != -1) {
day = 1;
dayValue = -1; // as user has not mentioned any value specifically
month = nextGoodMonth(month);
System.out.println(" Displaying calendar for next month "
+ month);
showLine = true;
drawCalendar(System.out, month, day);
continue;
} else {
System.out.println("Please display a calendar first. ");
continue;
}
} else if (cmd.equalsIgnoreCase("p")) {
if (day != -1 && month != -1) {
day = 1;
// as user has not mentioned any value specifically
dayValue = -1;
month = previousGoodMonth(month);
System.out.println(" Displaying calendar for previous month "
+ month);
showLine = true;
drawCalendar(System.out, month, day);
continue;
} else {
System.out.println("Please display a calendar first. ");
continue;
}
}
else if (cmd.equalsIgnoreCase("fp")) {
System.out.print(" Enter month to print (1-12):");
month = keybd.nextInt();
System.out.print("Enter filename: ");
String fname = keybd.next().trim();
keybd.nextLine();//remove newline
dayValue = -1;
try {
PrintStream outfile = new PrintStream(new File(fname));
drawCalendar(outfile, month, day);
outfile.close();
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
}
}
else if (cmd.equalsIgnoreCase("q")) {
System.out.println("Thank you for using the calendar app.");
System.out.println("Have a nice day.");
break;
} else {
System.out.println("Please enter a valid command. ");
continue;
}
}
keybd.close();
}
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.