string index out of bound exception - java

I am trying to generate an invoice number that contains name, branch and city with current date. I have gathered the information from JComboboxes and SimpleDateFormat. But in the end after we concat all the values and set them to a Jtextfield I get string index out of bound exception.
I am new to java and don't have much knowledge about it whatever efforts I have made for this are given as follows. I will be grateful to people interested in supporting me. Boots and Bouquets both are welcome.
private void bt_generateActionPerformed(java.awt.event.ActionEvent evt) {
if (evt.getSource() == bt_generate) {
if ((cb_bkname.getSelectedItem()
.equals("<html><font color=\"red\">SELECT NAME</font></html>"))
|| (cb_brname.getSelectedItem()
.equals("<html><font color=\"red\">SELECT BRANCH</font></html>"))
|| (cb_plname.getSelectedItem()
.equals("<html><font color=\"red\">SELECT PLACE</font></html>"))
){
} else {
String datePrefix = new SimpleDateFormat("MMMM dd, YYYY")
.format(new Date());
tf_rm_dt.setText(datePrefix);
Object name = cb_bkname.getSelectedItem();
String bn = name.toString().substring(0, 3);
Object branch = cb_brname.getSelectedItem();
String br = branch.toString().substring(0, 4);
Object city = cb_bkname.getSelectedItem();
String pl = city.toString().substring(0, 4);
String curdt = new SimpleDateFormat("dd-MM-YY")
.format(new Date());
tf_rm_id.setText("" + bn + "/" + br + "/" + "/" + curdt);
}
}
}
The StackTrace is as follows:
run:
Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.substring(String.java:1955)
at myproj.DATAENTRY.bt_generateActionPerformed(DATAENTRY.java:2215)
at myproj.DATAENTRY.access$2300(DATAENTRY.java:20)
at myproj.DATAENTRY$24.actionPerformed(DATAENTRY.java:597)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)

One of your strings is to short:
The error is either in one of these 3 lines
String bn=name.toString().substring(0, 3);
String br=branch.toString().substring(0, 4);
String pl=city.toString().substring(0, 4);
Print out the string, and check length before doing the substring()

This is an inefficient and overly complicated means to get information from a combo box! Can't you assign the selection, to an object (as an enum type, for example), prior to the concatenation? If you know what the selections are (which hopefully you do) you shouldn't ever need to use substring!

Related

Is there a way loop through 2 arrays and print the element of array 1 if it contains the substring of any element from array 2?

The problem I am trying to solve is how to read lines from a text file and add it to an array. Then sort each element from this new array by the date that is also in each element. I will explain so its easier to understand but will explain what I am doing.
My text file (First column is name, second is Date of birth and last is the date the person died):
sarah jones,1966-12-02,2018-12-04
matt smith,1983-02-03,2020-03-02
john smith,1967-03-04,2017-04-04
I want to sort this file and output it to another file (testing by printing to console at the moment) by sorting it by the date the person died. A way I thought of doing this is to read each line and pass it to an array. Then read each element within the array, split it and then save the date the person died to another array. Then sort the array that has the death dates, loop through both arrays by seeing if the first element of the death date array matches the first element of the first line in the text file, if so then write it to another file. If not then go to the next line.
For example
BufferedReader reader = new BufferedReader(new FileReader("input_text.txt"));
PrintWriter outputStream = new PrintWriter(new FileWriter("output.txt",true));
ArrayList<String> lines = new ArrayList<String>();
ArrayList<String> substr_date = new ArrayList<String>();
String currentline = reader.readLine();
while(currentline !=null){
String a_line[] = currentline.split(",");
substr_date.add(a_line[2])
lines.add(currentline);
currentline = reader.readLine();
}
Collections.sort(substr_date);
for(String date : substr_date){
for(String line : lines){
if(line.contains(date)){
System.out.println(line);
}
}
}
I expect the output to be:
john smith,1967-03-04,2017-04-04
sarah jones,1966-12-02,2018-12-04
matt smith,1983-02-03,2020-03-02
The results are initially in order but then some lines are repeated multiple times and then the whole text file in repeated to the console and becomes a mess. I am not sure how to go about doing this. I am new to java and not sure if I asked this question properly either so if you need any more info please ask.
I would create class for objects which you can insert into a list and then define a comparator on this class which you can use to sort.
Here is an example of the class you could define:
static class DeceasedPerson {
String name;
LocalDate birthDate;
LocalDate deathDate;
DeceasedPerson(String name, LocalDate birthDate, LocalDate deathDate) {
this.name = name;
this.birthDate = birthDate;
this.deathDate = deathDate;
}
#Override
public String toString() {
return name + ", " + birthDate + ", " + deathDate;
}
}
Then you could simply load objects based on this class into a list which you sort using a comparator. Here is some sample code you can run with the class defined above:
public static void main(String[] args) {
String input =
"matt smith,1983-02-03,2020-03-02\n" +
"sarah jones,1966-12-02,2018-12-04\n" +
"john smith,1967-03-04,2017-04-04\n";
List<DeceasedPerson> deceasedPersonList = new ArrayList<>();
try (Scanner scanner = new Scanner(input)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] array = line.split(",");
DeceasedPerson deceasedPerson = new DeceasedPerson(array[0],
LocalDate.parse(array[1]), LocalDate.parse(array[2]));
deceasedPersonList.add(deceasedPerson);
}
}
deceasedPersonList.sort(Comparator.comparing(o -> o.deathDate));
deceasedPersonList.forEach(System.out::println);
}
If you run the code above using the DeceasedPerson class you should see on the console the following output:
john smith, 1967-03-04, 2017-04-04
sarah jones, 1966-12-02, 2018-12-04
matt smith, 1983-02-03, 2020-03-02
You could actually also use a TreeSet instead of a List in the main method above and achieve the same results. Here is a move concise alternative:
public static void main(String[] args) {
String input =
"matt smith,1983-02-03,2020-03-02\n" +
"sarah jones,1966-12-02,2018-12-04\n" +
"john smith,1967-03-04,2017-04-04\n";
Set<DeceasedPerson> deceasedPersonList = new TreeSet<>(Comparator.comparing(o -> o.deathDate));
try (Scanner scanner = new Scanner(input)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] array = line.split(",");
DeceasedPerson deceasedPerson = new DeceasedPerson(array[0],
LocalDate.parse(array[1]), LocalDate.parse(array[2]));
deceasedPersonList.add(deceasedPerson);
}
}
deceasedPersonList.forEach(System.out::println);
}
The way you are doing is a long shot. You can do this in much simpler way. You could pass a comparator to the Collections.sort() method like this.
Collections.sort(substr_date, new Comparator<String>{
#Override
public int compare(String str1, String str2){
String dd1 = str1.split(",")[2];
String dd2 = str2.split(",")[2];
return dd1.compareTo(dd2);
}
});
Comparing dates like this, though, is not a good approach. You should convert the date string to LocalDateTime and then use isBefore() or isAfter() to compare them. For ex,
public int compare(String str1, String str2){
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd")
LocalDateTime d1 = LocalDateTime.parse(str1.split(",")[2],format);
LocalDateTime d2 = LocalDateTime.parse(str2.split(",")[2],format);
return d1.isBefore(d2)?-1:(d1.isAfter(d2)?1:0);
}

A Very Strange StringIndexOutOfBoundsException

Before asking this question , i spent around half an hour on google , but since i didn't find a solution i thought i maybe should ask here.
So basically i'm using Java Reader to read a text file and converting each line of information into an Object that i called Nation ( With a constructor of course ) and making an array out of all those objects.
The problem is that a single line on my text file goes to 75 characters. But i get an error telling me that the length is only 68 ! So Here's the part of the code where i read informations from the file :
static int lireRemplir (String nomFichier, Nation[] nations)
throws IOException
{
boolean existeFichier = true;
int n =0;
FileReader fr = null;
try {
fr = new FileReader(nomFichier);
}
catch (java.io.FileNotFoundException erreur) {
System.out.println("Probléme avec l'ouverture du fichier " + nomFichier);
existeFichier = false;
}
if (existeFichier) {
BufferedReader entree = new BufferedReader(fr);
boolean finFichier = false;
while (!finFichier) {
String uneLigne = entree.readLine();
if (uneLigne == null) {
finFichier=true;
}
else {
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,74),uneLigne.substring(1,15),uneLigne.substring(36,54));
n++;
}
}
entree.close();
}
return n;
}
The Error i get is :
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
begin 64, end 74, length 68
Since i'm new here i tried to post an image of my text but i couldn't, so i'll just try to hand write an exemple:
2ETATS-UNIS WASHINGTON 9629047 291289535
4CHINE PEKIN 9596960 1273111290
3JAPON KYOTO 377835 12761000
There is alot of space between the words it's like an array!
If i change the 74 to 68 i get a result when i try to print my array , but the information is missing.
Here's my constructor:
public Nation(char codeContinent, String superficie, String population, String nom, String capitale) {
this.codeContinent = codeContinent;
this.superficie = superficie;
this.population = population;
this.nom = nom;
this.capitale = capitale;
}
I hope you could help me with this! If you need to know more about my code let me know ! Thank you very much.
To avoid Runtime Exceptions, you need to be careful with your code. In cases where you are dealing with indexes of a String or an array, please check for length of the String to be greater or equal to the maximum index you are using. Enclose you code that is throwing the exception within:
if(uneLigne.length() > 74) {
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,74),uneLigne.substring(1,15),uneLigne.substring(36,54));
} else {
//your logic to handle the line with less than 74 characters
}
This will ensure your code does not break even if any line is smaller than expected characters.
______________________________________________________________________________
Another approach
Adding the comment as an answer:
The other way would be to use split() method of String class or StringTokenizer class to get the array/tokens if the line is delimited with space or some other character. With this, you need not break the string using substring() method where you need to worry about the lengths and possible Runtime.
Check the below code snippet using split() method, for each line you read from file, you probably have to do this way:
Nation nation = null;
String uneLigne = "2ETATS-UNIS WASHINGTON 9629047 291289535";
String[] strArray = uneLigne.split(" ");
if(strArray.length > 3) {
nation = new Nation(getContinentCodeFromFirstElement(strArray[0]), strArray[1],
strArray[2], strArray[3], strArray[4]);
}
//getContinentCodeFromFirstElement(strArray[0]) is your private method to pick the code from your first token/element.
The simpliest way to solve your problem is to change the 74 by uneLigne.length.
Here's the new code.
nations[n] = new Nation(uneLigne.charAt(0),uneLigne.substring(55,63),
uneLigne.substring(64,uneLigne.length),uneLigne.substring(1,15),uneLigne.substring(36,54));

Java JSON decode from OMDB (IMDB) API using Java

I want to get movie data from the OMDB API which is JSON text. I am using Java to decode this and the package JSON-simple.
The URL I want to decode is this for example: http://www.omdbapi.com/?t=icarus
Outcome (directly copy and paste, not structured):
{"Title":"Icarus","Year":"2010","Rated":"TV-14","Released":"10 Dec 2010","Runtime":"42 min","Genre":"Adventure, Drama, Romance","Director":"Mairzee Almas","Writer":"Alfred Gough (creator), Jerry Siegel (character created by: Superman), Miles Millar (creator), Joe Shuster (character created by: Superman), Alfred Gough (developed for television by), Miles Millar (developed for television by), Genevieve Sparling","Actors":"Tom Welling, Erica Durance, Cassidy Freeman, Justin Hartley","Plot":"As the VRA threat intensifies, Clark takes initiative by closing down watchtower and declaring the League go officially underground, but will this be enough to stop trotter and Slade Wilson...","Language":"English","Country":"USA","Awards":"N/A","Poster":"http://ia.media-imdb.com/images/M/MV5BMjIwNDQ2MjM5OV5BMl5BanBnXkFtZTcwODU4NzU0NA##._V1_SX300.jpg","Metascore":"N/A","imdbRating":"8.6","imdbVotes":"367","imdbID":"tt1628582","Type":"episode","Response":"True"}
The code under my button:
String url = "http://www.omdbapi.com/?t=" + jListFilms.getSelectedValue().toString();
try {
JSONParser parser = new JSONParser();
Object obj = parser.parse(url);
JSONObject jsonObj = (JSONObject) obj;
String title = (String) jsonObj.get("Title") ;
System.out.println(title);
} catch (ParseException e){
System.out.println(e);
}
When I print out the variable title
Unexpected character (h) at position 0.
Does anyone know why I don't get the title of the movie?
What your code is doing is parsing the string URL which starts "http://", hence the h at location 0.
You need to issue an HTTP GET request at that url in order to get the JSON back.
Here's an answer for how to issue the GET request
Thanks Adam for leading me into the right direction. I am using InputStream and Google Gson instead of JSON.Simple now.
This is my code now and it works how I wanted it to work.
try {
String selectedItem = jListFilms.getSelectedValue().toString().replace("\\s+", "+");
InputStream input = new URL("http://www.omdbapi.com/?t=" + URLEncoder.encode(selectedItem, "UTF-8")).openStream();
Map<String, String> map = new Gson().fromJson(new InputStreamReader(input, "UTF-8"), new TypeToken<Map<String, String>>(){}.getType());
String title = map.get("Title");
String year = map.get("Year");
String released = map.get("Released");
String runtime = map.get("Runtime");
String genre = map.get("Genre");
String actors = map.get("Actors");
String plot = map.get("Plot");
String imdbRating = map.get("imdbRating");
String poster = map.get("Poster");
testForm tf = new testForm(title, year, released, runtime, genre, actors, plot, imdbRating);
tf.setVisible(true);
} catch (JsonIOException | JsonSyntaxException | IOException e){
System.out.println(e);
}

Reading line by line from file in java

I have problems with BufferedReader in java. I am reading line by line from large file, parsing lines and inserting into HashMap, but in the result only few lines are in HashMap
Map< Integer, String> data = new HashMap<>(1000000);
int completedTestsCount = 0;
BufferedReader reader = new BufferedReader(new FileReader("file.txt"), 120000);
String line = null;
while ((line = reader.readLine()) != null) {
if (line.contains("START executing FOR"))
{
String tempId = line.substring(42, line.length() - 38);
int startId = Integer.parseInt(tempId);
String dateTime = line.substring(6, 14);
data.put(startId, dateTime);
}
And it's an example of line from file that I want to parse "INFO 00:00:09 - START executing FOR test3625 at Mon Sep 23 00:00:09 GMT+00:00 2013", so keys are test id
HashMap saves data as , where key is unique, so may in your case,
String tempId = line.substring(42, line.length() - 38);
is the key, and as you are reading it from file, this might not be unique. This is the problem, you have to make sure key is unique.
The most likely explanation is that lots of lines in the file have the same startId. Each time you put a key/value pair with the same key, you will actually replace the previous map entry for that key. (A Map maps one key to exactly one value ...)
This might be because the ids are genuinely the same, or it might be that the way you are extracting the id from each line is incorrect; e.g. if the actual id doesn't always start at character 42.
By my counting, character 42 of your example line is the 2 in 3625 ... and that does not seem correct!
For using HashMaps, you will need all the stardId values to be unique.
You should be using a list, instead of a map in this case.
Define a custom KeyValuePair class and add the objects in the list.
class KeyValuePair{
int startId;
String dateTime;
}
List<KeyValuePair> data = new ArrayList<>();
String tempId = line.substring(42, line.length() - 38);
int startId = Integer.parseInt(tempId);
String dateTime = line.substring(6, 14);
data.add(new KeyValuePair(startId, dateTime))

NullPointerException [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I am facing some problem in this function where I'm running into null values and getting a null pointer exception. sqlDate and sqlTime are null.
private void setCalendarComboDetails(Map tenantConnInfo, HttpSession session, HttpServletRequest request) {
logger.info("Enter setCalendarComboDetails");
Appointment appointmentInfo = new Appointment();
Date sqlDate;
Time sqlTime;
try {
CompanyDbImpl companyImpl = new CompanyDbImpl(tenantConnInfo);
PatientDbImpl patientImpl = new PatientDbImpl(tenantConnInfo);
DoctorDbImpl doctorImpl = new DoctorDbImpl(tenantConnInfo);
CalendarDbImpl calendarImpl = new CalendarDbImpl(tenantConnInfo);
ConfigurationDbImpl configurationImpl = new ConfigurationDbImpl(tenantConnInfo);
session.setAttribute("isvalid",true);
session.removeAttribute("appointmentInfo");
// session.removeAttribute("index");
List<CompanyBranchDetails> branchDetailsList = companyImpl.getCompanyNBranchList();
session.setAttribute("companyBranchList", branchDetailsList);
List<PatientInfo> patientList = patientImpl.getPatientInfoList();
session.setAttribute("patientInfoList", patientList);
String whereClause = " dbd.branch_id=" + branchDetailsList.get(0).getBranchId();
List<DoctorBranchDetails> doctorBranchDetailsList = doctorImpl.getDoctorBranchDetailsListByWhereClause(whereClause);
System.out.println("doctor branch list size " + doctorBranchDetailsList.size());
session.setAttribute("doctorBranchList", doctorBranchDetailsList);
Map configMap = configurationImpl.getConfigurationMapByConfigType(ApplicationConstants.CONFIGURATION_TYPE_CALENDAR);
int timeFormatId = Integer.parseInt(configMap.get("time_format_id").toString());
whereClause = " time_format_id=" + timeFormatId;
String dbTimeFormat = calendarImpl.getTimeFormatListByWhereClause(whereClause).get(0).getTimeFormatType();
int dateFormatId = Integer.parseInt(configMap.get("date_format_id").toString());
whereClause = " date_format_id=" + dateFormatId;
String dbDateFormat = calendarImpl.getDateFormatListByWhereClause(whereClause).get(0).getDateFormatType();
session.setAttribute("calendarDateFormat", dbDateFormat);
String jsStart = request.getParameter("start1");
String jsEnd = request.getParameter("end1");
String jsDateNTimeFormat = ApplicationConstants.JS_DATENTIME_PATTERN;
System.out.println("start1 " + request.getParameter("start1") + " " + new java.util.Date());
sqlDate = appointmentInfo.getStartDate().getDatepickerDate();
appointmentInfo.setStrStartDate(ApplicationUtils.formatSqlDate(dbDateFormat, sqlDate));
System.out.println("sqlDate1"+sqlDate);
sqlTime = appointmentInfo.getStartTime().getTimepickerTime();
appointmentInfo.setStrStartTime(ApplicationUtils.formatSqlTime(dbTimeFormat, sqlTime));
java.util.Date date1 = ApplicationUtils.getDateFromSqlDateNTime(sqlDate, sqlTime);
sqlDate = appointmentInfo.getEndDate().getDatepickerDate();
appointmentInfo.setStrEndDate(ApplicationUtils.formatSqlDate(dbDateFormat, sqlDate));
sqlTime = appointmentInfo.getEndTime().getTimepickerTime();
appointmentInfo.setStrEndTime(ApplicationUtils.formatSqlTime(dbTimeFormat, sqlTime));
java.util.Date date2 = ApplicationUtils.getDateFromSqlDateNTime(sqlDate, sqlTime);
String diff = ApplicationUtils.getDateDifference(date1, date2);
appointmentInfo.setDuration(diff);
System.out.println("difference"+diff);
if(session.getAttribute("index") != null) {
doctorBranchDetailsList = (ArrayList<DoctorBranchDetails>)session.getAttribute("doctorBranchDetailsList");
int selectedIndex = Integer.parseInt(session.getAttribute("index").toString());
DoctorBranchDetails doctorBranchInfo = doctorBranchDetailsList.get(selectedIndex);
appointmentInfo.getDoctorBranchDetails().setDoctorBranchId(doctorBranchInfo.getDoctorBranchId());
appointmentInfo.getDoctorBranchDetails().getCompanyBranchDetails().setBranchId(doctorBranchInfo.getCompanyBranchDetails().getBranchId());
appointmentInfo.getDoctorBranchDetails().setDoctorName(doctorBranchInfo.getDoctorInfo().getFullName());
appointmentInfo.getDoctorBranchDetails().setBranchNType(doctorBranchInfo.getBranchNType());
}
appointmentInfo.setStrStartDate(ApplicationUtils.converDateFormats(jsStart, jsDateNTimeFormat, dbDateFormat));
appointmentInfo.setStrStartTime(ApplicationUtils.converDateFormats(jsStart, jsDateNTimeFormat, dbTimeFormat));
appointmentInfo.setStrEndDate(ApplicationUtils.converDateFormats(jsEnd, jsDateNTimeFormat, dbDateFormat));
appointmentInfo.setStrEndTime(ApplicationUtils.converDateFormats(jsEnd, jsDateNTimeFormat, dbTimeFormat));
session.setAttribute("appointmentInfo", appointmentInfo);
} catch (Exception e) {
logger.error(e, e);
}
logger.info("Exit setCalendarComboDetails");
}
Learn to Debug.
You have many tools at your disposal. Try them. Figure this out. If you can't break apart your code and find problems, you won't be much use as a programmer on anything other than tiny applications. This site is not a replacement for a debugger. Here are some things you should work on.
Figure out the debugger yourself or use an IDE like Eclipse that has those functions built in. Set breakpoints at the start of the function and step through it. Make sure all variables contain what you want at each step of the way.
Add System.out.println() lines to the code or use a logging framework like log4j to output the contents of variables along the way. Review the console after running this part of the code and make sure that all variables contain what you want each step of the way.
Refactor the code into smaller methods. Unit test each one individually. This helps isolate the part of the code that is breaking from the parts that aren't.

Categories