Is it possible to do real time user input without re-running (re-executing) a sketch for text
in
Programming Questions
•
1 years ago
Currently, I have an applet where users can type something which is saved to a "userinput" text file when they press return twice after typing. Meanwhile, another class comes into this text file which stores the different user inputs as an array of strings, retrieves them randomly and displays them onto the canvas one after another with fades.
However, whatever someone types when the program is executing will not appear on the canvas until I rerun the canvas.
Is it possible to do this? Here is my code below (only the textual sections which are relevant):
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();
}
// mouse and keyboard events
void mousePressed () {
textbox.press(mouseX, mouseY);
}
void mouseDragged() {
textbox.drag (mouseX, mouseY);
}
void mouseReleased () {
textbox.release ();
}
void keyPressed () {
textbox.keyPressed();
}
abstract class InteractiveBoxes {
int boxPosX, boxPosY, boxPosW, boxPosH;
color boxClr;
PFont fontA; // declare a variable that refers to the default font for all the subclasses
int fontHeight;
int marginSpacing;
int boxPosXOff, boxPosYOff;
boolean over = false;
boolean pressed = false;
InteractiveBoxes (int tempBoxPosX, int tempBoxPosY, int tempBoxWidth, int tempBoxHeight, color tempboxClr) {
boxPosX=tempBoxPosX;
boxPosY=tempBoxPosY;
boxPosW=tempBoxWidth;
boxPosH=tempBoxHeight;
boxClr=tempboxClr;
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
void rollOver () {
if ((mouseX>=boxPosX) && (mouseX <=boxPosX+boxPosW) && (mouseY>=boxPosY) && (mouseY<=boxPosY+boxPosH)) {
over=true;
}
else {
over=false;
}
} // end of the rollOver function
void click (int mX, int mY) {
boxPosX=mouseX;
boxPosY=mouseY;
boxPosW=mouseX-boxPosX;
boxPosH=mouseY-boxPosY;
} // end the click function
void press (int mX, int mY) {
if (over==true) {
pressed=true;
boxPosXOff=mX-boxPosX;
boxPosYOff=mY-boxPosY;
}
} // end of the press function
void drag (int mX, int mY) {
if (pressed==true) {
boxPosX=mX-boxPosXOff;
boxPosY=mY-boxPosYOff;
}
} // end of the drag function
void release () {
pressed=false;
} // end of release function
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;
// 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());
}
}
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
}
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
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
However, whatever someone types when the program is executing will not appear on the canvas until I rerun the canvas.
Is it possible to do this? Here is my code below (only the textual sections which are relevant):
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();
}
// mouse and keyboard events
void mousePressed () {
textbox.press(mouseX, mouseY);
}
void mouseDragged() {
textbox.drag (mouseX, mouseY);
}
void mouseReleased () {
textbox.release ();
}
void keyPressed () {
textbox.keyPressed();
}
abstract class InteractiveBoxes {
int boxPosX, boxPosY, boxPosW, boxPosH;
color boxClr;
PFont fontA; // declare a variable that refers to the default font for all the subclasses
int fontHeight;
int marginSpacing;
int boxPosXOff, boxPosYOff;
boolean over = false;
boolean pressed = false;
InteractiveBoxes (int tempBoxPosX, int tempBoxPosY, int tempBoxWidth, int tempBoxHeight, color tempboxClr) {
boxPosX=tempBoxPosX;
boxPosY=tempBoxPosY;
boxPosW=tempBoxWidth;
boxPosH=tempBoxHeight;
boxClr=tempboxClr;
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
void rollOver () {
if ((mouseX>=boxPosX) && (mouseX <=boxPosX+boxPosW) && (mouseY>=boxPosY) && (mouseY<=boxPosY+boxPosH)) {
over=true;
}
else {
over=false;
}
} // end of the rollOver function
void click (int mX, int mY) {
boxPosX=mouseX;
boxPosY=mouseY;
boxPosW=mouseX-boxPosX;
boxPosH=mouseY-boxPosY;
} // end the click function
void press (int mX, int mY) {
if (over==true) {
pressed=true;
boxPosXOff=mX-boxPosX;
boxPosYOff=mY-boxPosY;
}
} // end of the press function
void drag (int mX, int mY) {
if (pressed==true) {
boxPosX=mX-boxPosXOff;
boxPosY=mY-boxPosYOff;
}
} // end of the drag function
void release () {
pressed=false;
} // end of release function
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;
// 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());
}
}
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
}
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
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