Getting an ArrayIndexOutOfBoundsExeption for no apparent reason

This code is intended to take a list of quotes (memories.txt), and format each quote as a scaled square of text, then save an image of the text.

String[] quotes;

public StringList divide(String s) { //divide the quote into lines of text to be drawn
  float w = sqrt(textWidth(s))*4; //calculates the maximum width of a line necessary to maintain a square-ish text shape
  StringList split = new StringList();
  //Splits the string into words and filters the results of the split function into our StringList
  for (int i=0;i<s.split("\\s+").length;i++) {
    split.append(s.split("\\s+")[i]);
  }
  for (int i = 0; i+1 < split.size(); i++) {//for every word...
    while (textWidth (split.get (i)+" "+split.get(i+1)) < w) {//while the length of the "word" (which becomes multiple words) is less than the maximum line width...
      split.set(i, split.get(i)+" "+split.get(i+1)); //add the next word to the current...
      split.remove(i+1); // and remove the next word
    }
  }
  return split;
}

public float deftextsize(String s) { //define the font size based on whether or not a single word is by itself longer than the maximum line width. This section isn't working quite right.
  StringList words = new StringList();
  float textsize = 0;
  float w = sqrt(textWidth(s))*4;
  float widestwordwidth = 0; 
  //Splits the string into words and filters the results of the split function into our StringList
  for (int i=0;i<s.split("\\s+").length;i++) {
    words.append(s.split("\\s+")[i]);
  }
  for (int i = 1; i+1 < words.size(); i++) { //return the width of the widest word
    if (textWidth(words.get(i))>textWidth(words.get(i-1))) {
      widestwordwidth = textWidth(words.get(i));
    }
  }

  if (widestwordwidth>w) {//if the widest word is wider than the maximum allowed width...
    textsize = height/widestwordwidth; //the textsize is determined by the length of the word.
  }
  else { //otherwise...
    words = divide(s);
    textsize = height/words.size(); //the textsize is determined by the number of lines
  }
  return textsize;
}

void setup() {
  size(600, 500);
  quotes = loadStrings("memories.txt"); //load a list of quotes
  textAlign(CENTER);
  for (String quote: quotes) { //for every quote...
    background(0);
    StringList lines = divide(quote); //divide the quote into lines using our divide function...
    float textsize = deftextsize(quote); //and generate the appropriate font size for each quote
    textSize(textsize);
    for (int i = 0; i<lines.size(); i++) { //for every line in every quote...
      String line = lines.get(i);
      text(line, width/2, i*textsize+textsize); //display the line at the appropriate position
    }
    quote=join(split(quote, "\""), ""); //remove unallowed marks for saving
    quote=join(split(quote, "\""), "");
    quote=join(split(quote, "/"), "");
    quote=join(split(quote, ":"), "");
    quote=join(split(quote, "*"), "");
    quote=join(split(quote, "|"), "");
    quote=join(split(quote, "?"), "");
    quote=join(split(quote, "<"), "");
    quote=join(split(quote, ">"), "");
    saveFrame(quote+".png"); //save the frame
  }
  exit();
}

Only two of maybe 30 images are being generated before I receive an error.

Answers

  • These expressions: split.get(i+1), split.remove(i+1)are supposed to access next split's element.
    However, how can you be sure a next element exists at all? Perhaps index i already is the last split's element, don't ya think? 3:-O

  • for (int i = 0; i+1 < split.size(); i++)...

    Shouldn't that only iterate until one element before the last in the loop? The for loop checks the length of the StringList every iteration, right?

  • edited June 2014

    The for loop checks the length of the StringList every iteration, right?

    Correct, however... iterator i surely is a valid index for split. But i+1 is a shot in the dark! [-(

  • But the loop stops at split.size()-1 because of the aforementioned line, so won't i+1 be an index all the way up to the end?

  • edited June 2014 Answer ✓

    When iterator i is the penultimate index and split.remove(i+1) is issued, i becomes the last index!
    Then while (textWidth(split.get(i)+" "+split.get(i+1)) < w) is checked again and crashes;
    b/c split.get(i+1) is beyond last element index now! [..]

  • Oh. Gotcha. Thanks!

  • What about the section that determines the font size? It's giving me weird, inaccurate font sizes. Ideas?

  • Sorry, but I'm no good at font metrics! :o3

  • 'Sall good. Thanks for your help!

Sign In or Register to comment.