Updating a string array with user input
in
Programming Questions
•
1 years ago
I have a text file that is a string array that appends a string everytime the user types some words and hits return twice.
The strings in that array are displayed on the canvas.
However, when an user makes a new contribution it can only be displayed if I rerun the application.
What I would like is that once the user types return twice, this new string is not only appended but also displayed.
I think the problem is with loadStrings but since it is in the constructor of a class, I am assuming that it is updated everytime draw is called. Perhaps I am assuming wrong?
TextField textbox;
WordCollage wc;
void setup() {
size (screen.width, screen.height);
background (225, 225, 255);
textbox=new TextField (100, height-200, 370, 100, color (100));
wc=new WordCollage (0, 0, width, height);
}
void draw() {
background (225, 225, 255);
wc.display();
textbox.display();
}
void keyPressed () {
textbox.keyPressed();
}
abstract class InteractiveBoxes {
int boxPosX, boxPosY, boxPosW, boxPosH;
PFont fontA; // declare a variable that refers to the default font for all the subclasses
int fontHeight;
int marginSpacing;
InteractiveBoxes (int tempBoxPosX, int tempBoxPosY, int tempBoxWidth, int tempBoxHeight) {
boxPosX=tempBoxPosX;
boxPosY=tempBoxPosY;
boxPosW=tempBoxWidth;
boxPosH=tempBoxHeight;
fontA = loadFont("ArialMT-48.vlw"); // Load the default font that the subclasses will be able to use
fontHeight=48; // set a default value for the font height (determined by the font size limit)
marginSpacing=5;
}
// methods of the abstract InteractiveBoxes class
abstract void display();
}
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;
color boxClr;
// constructor of the TextField class
TextField (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color tempBoxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH);
boxClr=tempBoxClr;
}
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());
}
}
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) {
super (boxPosX, boxPosY, boxPosW, boxPosH);
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
}
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 updateArray () {
retrieve = loadStrings ("claudefortin_project3.txt");
}
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
The strings in that array are displayed on the canvas.
However, when an user makes a new contribution it can only be displayed if I rerun the application.
What I would like is that once the user types return twice, this new string is not only appended but also displayed.
I think the problem is with loadStrings but since it is in the constructor of a class, I am assuming that it is updated everytime draw is called. Perhaps I am assuming wrong?
TextField textbox;
WordCollage wc;
void setup() {
size (screen.width, screen.height);
background (225, 225, 255);
textbox=new TextField (100, height-200, 370, 100, color (100));
wc=new WordCollage (0, 0, width, height);
}
void draw() {
background (225, 225, 255);
wc.display();
textbox.display();
}
void keyPressed () {
textbox.keyPressed();
}
abstract class InteractiveBoxes {
int boxPosX, boxPosY, boxPosW, boxPosH;
PFont fontA; // declare a variable that refers to the default font for all the subclasses
int fontHeight;
int marginSpacing;
InteractiveBoxes (int tempBoxPosX, int tempBoxPosY, int tempBoxWidth, int tempBoxHeight) {
boxPosX=tempBoxPosX;
boxPosY=tempBoxPosY;
boxPosW=tempBoxWidth;
boxPosH=tempBoxHeight;
fontA = loadFont("ArialMT-48.vlw"); // Load the default font that the subclasses will be able to use
fontHeight=48; // set a default value for the font height (determined by the font size limit)
marginSpacing=5;
}
// methods of the abstract InteractiveBoxes class
abstract void display();
}
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;
color boxClr;
// constructor of the TextField class
TextField (int boxPosX, int boxPosY, int boxPosW, int boxPosH, color tempBoxClr) {
super (boxPosX, boxPosY, boxPosW, boxPosH);
boxClr=tempBoxClr;
}
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());
}
}
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) {
super (boxPosX, boxPosY, boxPosW, boxPosH);
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
}
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 updateArray () {
retrieve = loadStrings ("claudefortin_project3.txt");
}
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