Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

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();

}

}