Failing to append() ... Illegal Argument Exception: Array Element Type Mismatch
in
Programming Questions
•
1 year ago
I am trying to append a string to an array of Strings. in my application, graffiti messages are displayed on a wall. When a user types his graffiti line in a box, it should appear also on the wall but currently it only appears AFTER I run the program again. I have already posted on this problem and was told to add a function called addNewString() which would append the new string to the array. I have tried all kinds of magic incantations of different syntax and nothing works. Referencing books, it seems like doing this should work
void addNewString() {
thisGraffiti = ((Graffiti[])append(thisGraffiti, "textbox.getNewString()"));
}
...but when I do this I get an "Illegal Argument Exception: Array Element Type Mismatch" error...
Here is my code for both input and output to the text file. The problem should be constrained to the WordCollage class or at worse, the TextField class. The rest is for reference:
TextField textbox;
WordCollage wc;
void setup() {
size (screen.width, screen.height);
textbox=new TextField (100, height-200, 370, 100, color (100));
wc=new WordCollage (0, 0, width, height, color(100));
}
void draw() {
background (225, 225, 255);
wc.display();
textbox.display();
textbox.rollOver();
}
void keyPressed () {
textbox.keyPressed();
}
class TextField extends InteractiveBoxes {
String userInputText= ""; // declare and initialize the variable to store text while it is being typed
String captureText= ""; // declare and initialize the variable to save typed text when return key is hit
String[] fullComment;
// constructor of the TextField class
TextField (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color boxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH, boxClr);
}
void appendStrings(String filename, String[] file) // This was a response from the processing forum on how to append text
{
try {
// Create file
FileWriter fstream = new FileWriter(sketchPath(filename), true); // boolean where true means append
PrintWriter out = new PrintWriter(fstream); // // Create a new file in the sketch directory
for (int i =0 ; i < file.length; ++i) { // go through String array
out.println(file[i]); // write each character in the String array in the text file
}
out.close(); //Close the output stream
}
catch (Exception e) { //Catch exception if any
println("Error: " + e.getMessage());
}
}
String getNewString () { // create a function that will return the string
if (key == RETURN || key == ENTER) { // If the return key is pressed...
return captureText; // return the string that the user just typed in
} // end the condition for when the return or enter key would be pressed after a user typed in their text
return null; // statement that must be put at the end of a method that returns a string in case there is nothing in that string at a given moment
} // end of the getNewString function
void keyPressed() {
fullComment = splitTokens(captureText, "/");
if (keyCode == BACKSPACE) {
userInputText = userInputText.substring(0, userInputText.length() - 1); // allow the backspace key to go back and erase characters
}
else
if (key != CODED) userInputText += key; // capture characters of any keys that are pressed except for the coded ones
// If the return key is pressed, save the String and clear it
if (key == RETURN || key == ENTER) {
captureText = userInputText;
appendStrings("userinput.txt", fullComment);
userInputText = ""; // Clear the String by setting it equal to ""
}
}
void display () {
// Display everything
fill (boxClr);
strokeWeight(4);
strokeJoin(ROUND);
rect (boxPosX, boxPosY, boxPosW, boxPosH);
fill(240); // Set the fill for text instructions
fontHeight=16;
textFont(fontA, fontHeight); // Set the font type and size at Arial 16 for text instructions
fill (255); //set the fill for the user's input text
text("Drag this box where you please. Type your graffiti as \na single phrase and hit return twice to add to wall:", boxPosX+marginSpacing, boxPosY+fontHeight+marginSpacing);
fontHeight=20;
textFont(fontA, fontHeight); // Set the font type and size at Arial 20 for text instructions
text(userInputText, boxPosX+marginSpacing, boxPosY+4*fontHeight+marginSpacing);
text(captureText, boxPosX+marginSpacing, boxPosY+4*fontHeight+marginSpacing);
}
} // end of TextField class
class WordCollage extends InteractiveBoxes {
Graffiti[] thisGraffiti;
int nbrAdded;
String [] retrieve;
PFont [] fonts;
String[] fontNames = {
"VinerHandITC-48", "SegoeScript-Bold-48", "RageItalic-48", "Mistral-48", "VladimirScript-48", "Pristina-Regular-48", "BradleyHandITC-48"
};
// constructor of the WordCollage class
WordCollage (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color boxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH, boxClr);
retrieve = loadStrings ("userinput.txt");
fonts=new PFont[fontNames.length];
nbrAdded=0; // declare and initialize a variable that keeps track of the number of graffiti that have been added so far
for (int i = 0; i < fontNames.length; ++i) {
fonts[i] = loadFont(fontNames[i] + ".vlw");
}
try {
thisGraffiti = new Graffiti[retrieve.length];
for (int i = 0; i < retrieve.length; ++i) {
Graffiti candidate;
do {
candidate = new Graffiti( retrieve[(int) random(retrieve.length)], fonts[(int) random(fonts.length)] ); // create each graffiti by retrieving each string in the array one by one and giving it a random font
this.addNewString(); // append the string that the user just typed in or other strings that users will later type in to the thisGraffiti array
}
while (!isDesirable (candidate)); // create a loop that keeps trying new candidates by checking if each are desirable...
thisGraffiti[i] = candidate; // ...until it gets a candidate that is desirable
nbrAdded++; // increment by one the variable that keeps track of the number of graffiti that have been added so far
println ("This is the number added:" + nbrAdded);
}
}
catch (NullPointerException e) {
println("I can't find the text file that contains your array!");
}
} // end of the constructor
void addNewString() {
thisGraffiti = ((Graffiti[])append(thisGraffiti, "textbox.getNewString()"));
}
boolean isDesirable (Graffiti cand)
{
for (int i=0; i<nbrAdded ; i++) { // create a for loop that will go through all the graffiti objects in the array
if ((cand.detectOverlap(thisGraffiti[i])) || (cand.equals(thisGraffiti[i])))
{
// check if candidate passes all desirability checks and return false if it's good, and true if it's bad
return false;
}
println("duplication");
}
return true;
}
void display () {
try {
for (int n = 0; n < thisGraffiti.length; n ++ ) {
thisGraffiti[n].display();
}
}
catch (NullPointerException e) {
println("I can't find your array!");
}
}
}
class Graffiti {
String graffitiText;
int graffitiX, graffitiY;
float opacity, randomOpacity, opacitySpeed;
int opacityDir;
color fClr;
PFont font;
Graffiti(String graffitiText, PFont font) { // constructor for the Graffiti class
this.graffitiText = graffitiText;
this.font = font;
graffitiX = int(random (screen.width));
graffitiX = constrain(graffitiX, 5, screen.width-27*graffitiText.length()); // constrain the x position so that the phrases are not cut off the screen
graffitiY = int(random (screen.height));
graffitiY = constrain(graffitiY, 50, screen.height-110); // constrain the y position so that the phrases are not cut off the screen
fClr = color(random (0, 175), random(0, 175), random(0, 175));
opacity = random(255);
randomOpacity = 1;
opacityDir= int (randomOpacity);
opacitySpeed=random(1, 3);
// println("Added Graffiti: " + graffitiText + " " + graffitiX + "," + graffitiY + "," + opacity + "," + opacityDir);
} // end of the constructor for the Graffiti class
boolean detectOverlap (Graffiti checkOverlap) {
if (checkOverlap == null) {
println("checkOverlap is null!");
return false;
}
if ((graffitiX>(checkOverlap.graffitiX+checkOverlap.graffitiText.length()*27)) || ((graffitiX+(27*graffitiText.length()))< (checkOverlap.graffitiX)) || ((graffitiY)>(checkOverlap.graffitiY+110)) || ((graffitiY+110) < (checkOverlap.graffitiY)))
{ // conditional block (from the vehicle collision detection assignment) that states that if the left of a graffiti is equal or more than the right of another graffiti OR if the right of a graffiti is equal or less than the left of another graffiti OR if the top of a graffiti is equal or more than the bottom of another graffiti OR if the bottom of a graffiti is equal or less than the top of another graffiti, then...
return false; // ...return false if any of these conditions are met
} // end of the if block
else { // if none of these conditions are met...
return true; // return true if there is an overlap
} // end of the else block
} // end of the detect Overlap function
void display() {
// Fade ins and fade outs by incrementing the opacity variable in function of the frameRate
opacity += opacityDir * opacitySpeed; // this is the speed of the fading effect
opacity = constrain(opacity, 0, 255); // constrain the range of the opacity from 0 to 255
if ( (opacity >= 255 && opacityDir == 1) || // When we hit maximum opacity...
(opacity <= 0 && opacityDir == -1)) { //... or when we are at minimum opacity...
opacityDir *= -1; //...change direction of the opacity fade
if (opacity <= 0) { // when graffiti is invisible...
graffitiX = int(random (screen.width)); //...choose new x
graffitiX = constrain(graffitiX, 5, screen.width-27*graffitiText.length()); // constrain the x position so that the phrases are not cut off the screen
graffitiY = int(random (screen.height)); //...choose new y
graffitiY = constrain(graffitiY, 50, screen.height-110); // constrain the y position so that the phrases are not cut off the screen
fClr = color(random (0, 150), random(0, 150), random(0, 150), random(100, 255)); //...and choose new font color
} // end of the loop that deals with the graffiti once it has become invisible
} // end of the loop that deals with the fade ins and fade outs of opacity
textFont(font, 48); // display the graffiti with correct font/color
fill(fClr, opacity); // color the text randomly and fade in/out with the opacity variable
text(graffitiText, graffitiX, graffitiY); // write the graffiti in a random x and y position
} // end the display function
} // end the Graffiti class
void addNewString() {
thisGraffiti = ((Graffiti[])append(thisGraffiti, "textbox.getNewString()"));
}
...but when I do this I get an "Illegal Argument Exception: Array Element Type Mismatch" error...
Here is my code for both input and output to the text file. The problem should be constrained to the WordCollage class or at worse, the TextField class. The rest is for reference:
TextField textbox;
WordCollage wc;
void setup() {
size (screen.width, screen.height);
textbox=new TextField (100, height-200, 370, 100, color (100));
wc=new WordCollage (0, 0, width, height, color(100));
}
void draw() {
background (225, 225, 255);
wc.display();
textbox.display();
textbox.rollOver();
}
void keyPressed () {
textbox.keyPressed();
}
class TextField extends InteractiveBoxes {
String userInputText= ""; // declare and initialize the variable to store text while it is being typed
String captureText= ""; // declare and initialize the variable to save typed text when return key is hit
String[] fullComment;
// constructor of the TextField class
TextField (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color boxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH, boxClr);
}
void appendStrings(String filename, String[] file) // This was a response from the processing forum on how to append text
{
try {
// Create file
FileWriter fstream = new FileWriter(sketchPath(filename), true); // boolean where true means append
PrintWriter out = new PrintWriter(fstream); // // Create a new file in the sketch directory
for (int i =0 ; i < file.length; ++i) { // go through String array
out.println(file[i]); // write each character in the String array in the text file
}
out.close(); //Close the output stream
}
catch (Exception e) { //Catch exception if any
println("Error: " + e.getMessage());
}
}
String getNewString () { // create a function that will return the string
if (key == RETURN || key == ENTER) { // If the return key is pressed...
return captureText; // return the string that the user just typed in
} // end the condition for when the return or enter key would be pressed after a user typed in their text
return null; // statement that must be put at the end of a method that returns a string in case there is nothing in that string at a given moment
} // end of the getNewString function
void keyPressed() {
fullComment = splitTokens(captureText, "/");
if (keyCode == BACKSPACE) {
userInputText = userInputText.substring(0, userInputText.length() - 1); // allow the backspace key to go back and erase characters
}
else
if (key != CODED) userInputText += key; // capture characters of any keys that are pressed except for the coded ones
// If the return key is pressed, save the String and clear it
if (key == RETURN || key == ENTER) {
captureText = userInputText;
appendStrings("userinput.txt", fullComment);
userInputText = ""; // Clear the String by setting it equal to ""
}
}
void display () {
// Display everything
fill (boxClr);
strokeWeight(4);
strokeJoin(ROUND);
rect (boxPosX, boxPosY, boxPosW, boxPosH);
fill(240); // Set the fill for text instructions
fontHeight=16;
textFont(fontA, fontHeight); // Set the font type and size at Arial 16 for text instructions
fill (255); //set the fill for the user's input text
text("Drag this box where you please. Type your graffiti as \na single phrase and hit return twice to add to wall:", boxPosX+marginSpacing, boxPosY+fontHeight+marginSpacing);
fontHeight=20;
textFont(fontA, fontHeight); // Set the font type and size at Arial 20 for text instructions
text(userInputText, boxPosX+marginSpacing, boxPosY+4*fontHeight+marginSpacing);
text(captureText, boxPosX+marginSpacing, boxPosY+4*fontHeight+marginSpacing);
}
} // end of TextField class
class WordCollage extends InteractiveBoxes {
Graffiti[] thisGraffiti;
int nbrAdded;
String [] retrieve;
PFont [] fonts;
String[] fontNames = {
"VinerHandITC-48", "SegoeScript-Bold-48", "RageItalic-48", "Mistral-48", "VladimirScript-48", "Pristina-Regular-48", "BradleyHandITC-48"
};
// constructor of the WordCollage class
WordCollage (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color boxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH, boxClr);
retrieve = loadStrings ("userinput.txt");
fonts=new PFont[fontNames.length];
nbrAdded=0; // declare and initialize a variable that keeps track of the number of graffiti that have been added so far
for (int i = 0; i < fontNames.length; ++i) {
fonts[i] = loadFont(fontNames[i] + ".vlw");
}
try {
thisGraffiti = new Graffiti[retrieve.length];
for (int i = 0; i < retrieve.length; ++i) {
Graffiti candidate;
do {
candidate = new Graffiti( retrieve[(int) random(retrieve.length)], fonts[(int) random(fonts.length)] ); // create each graffiti by retrieving each string in the array one by one and giving it a random font
this.addNewString(); // append the string that the user just typed in or other strings that users will later type in to the thisGraffiti array
}
while (!isDesirable (candidate)); // create a loop that keeps trying new candidates by checking if each are desirable...
thisGraffiti[i] = candidate; // ...until it gets a candidate that is desirable
nbrAdded++; // increment by one the variable that keeps track of the number of graffiti that have been added so far
println ("This is the number added:" + nbrAdded);
}
}
catch (NullPointerException e) {
println("I can't find the text file that contains your array!");
}
} // end of the constructor
void addNewString() {
thisGraffiti = ((Graffiti[])append(thisGraffiti, "textbox.getNewString()"));
}
boolean isDesirable (Graffiti cand)
{
for (int i=0; i<nbrAdded ; i++) { // create a for loop that will go through all the graffiti objects in the array
if ((cand.detectOverlap(thisGraffiti[i])) || (cand.equals(thisGraffiti[i])))
{
// check if candidate passes all desirability checks and return false if it's good, and true if it's bad
return false;
}
println("duplication");
}
return true;
}
void display () {
try {
for (int n = 0; n < thisGraffiti.length; n ++ ) {
thisGraffiti[n].display();
}
}
catch (NullPointerException e) {
println("I can't find your array!");
}
}
}
class Graffiti {
String graffitiText;
int graffitiX, graffitiY;
float opacity, randomOpacity, opacitySpeed;
int opacityDir;
color fClr;
PFont font;
Graffiti(String graffitiText, PFont font) { // constructor for the Graffiti class
this.graffitiText = graffitiText;
this.font = font;
graffitiX = int(random (screen.width));
graffitiX = constrain(graffitiX, 5, screen.width-27*graffitiText.length()); // constrain the x position so that the phrases are not cut off the screen
graffitiY = int(random (screen.height));
graffitiY = constrain(graffitiY, 50, screen.height-110); // constrain the y position so that the phrases are not cut off the screen
fClr = color(random (0, 175), random(0, 175), random(0, 175));
opacity = random(255);
randomOpacity = 1;
opacityDir= int (randomOpacity);
opacitySpeed=random(1, 3);
// println("Added Graffiti: " + graffitiText + " " + graffitiX + "," + graffitiY + "," + opacity + "," + opacityDir);
} // end of the constructor for the Graffiti class
boolean detectOverlap (Graffiti checkOverlap) {
if (checkOverlap == null) {
println("checkOverlap is null!");
return false;
}
if ((graffitiX>(checkOverlap.graffitiX+checkOverlap.graffitiText.length()*27)) || ((graffitiX+(27*graffitiText.length()))< (checkOverlap.graffitiX)) || ((graffitiY)>(checkOverlap.graffitiY+110)) || ((graffitiY+110) < (checkOverlap.graffitiY)))
{ // conditional block (from the vehicle collision detection assignment) that states that if the left of a graffiti is equal or more than the right of another graffiti OR if the right of a graffiti is equal or less than the left of another graffiti OR if the top of a graffiti is equal or more than the bottom of another graffiti OR if the bottom of a graffiti is equal or less than the top of another graffiti, then...
return false; // ...return false if any of these conditions are met
} // end of the if block
else { // if none of these conditions are met...
return true; // return true if there is an overlap
} // end of the else block
} // end of the detect Overlap function
void display() {
// Fade ins and fade outs by incrementing the opacity variable in function of the frameRate
opacity += opacityDir * opacitySpeed; // this is the speed of the fading effect
opacity = constrain(opacity, 0, 255); // constrain the range of the opacity from 0 to 255
if ( (opacity >= 255 && opacityDir == 1) || // When we hit maximum opacity...
(opacity <= 0 && opacityDir == -1)) { //... or when we are at minimum opacity...
opacityDir *= -1; //...change direction of the opacity fade
if (opacity <= 0) { // when graffiti is invisible...
graffitiX = int(random (screen.width)); //...choose new x
graffitiX = constrain(graffitiX, 5, screen.width-27*graffitiText.length()); // constrain the x position so that the phrases are not cut off the screen
graffitiY = int(random (screen.height)); //...choose new y
graffitiY = constrain(graffitiY, 50, screen.height-110); // constrain the y position so that the phrases are not cut off the screen
fClr = color(random (0, 150), random(0, 150), random(0, 150), random(100, 255)); //...and choose new font color
} // end of the loop that deals with the graffiti once it has become invisible
} // end of the loop that deals with the fade ins and fade outs of opacity
textFont(font, 48); // display the graffiti with correct font/color
fill(fClr, opacity); // color the text randomly and fade in/out with the opacity variable
text(graffitiText, graffitiX, graffitiY); // write the graffiti in a random x and y position
} // end the display function
} // end the Graffiti class
1