Reading from multiple textfields and saving into .txt file

#1

Hello, it’s me once again!

I’ve made some progress into my code, but now I’m thinking a little bit ahead and decided to share some questions with the community (ask for help, actually)

I’m prompting the user with a series of questions, then I want to have the answers saved into a neat little .txt file, so I can feed it into a treemap generator.

So far I managed to create and save some of the information, but things are not going smoothly.

I’m having trouble when saving all the answers into a single file. the ‘state’ variable seems to be working, all conditionals seems to be fulfilling its purposes but I still return with some null and/or weird file name/content. as a bonus I wish I could multiply the answers throughout my array, so they could appear a few more times (it will help with the visual effect of the treemaps). I thought about using a loop, randomizing 25 numbers for each of the 4 answers so far and making copies in to the array slot. Would it work?

Thanks a bunch, the code go as follow:


import controlP5.*;
ControlP5 cp5;

Textfield infosInput;

int state = 0;
int MAXSTATE = 3;

String infos;
String infosOutput[];

void setup(){
  
  size (500, 500);
  
  cp5 = new ControlP5(this);
  
  cp5.addTextarea("titulo")
    .setPosition(100, 100)
    .setSize(400, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    .setText("enTro");
    
  cp5.addTextarea("clique")
    .setPosition(280, 295)
    .setSize(200, 25)
    .setFont(createFont("arial", 12))
    .setLineHeight(14)
    .setColor(color(135))
    .setColorBackground(color(198, 100))
    .setColorForeground(color(255, 100))
    .setText("clique para continuar...")
    ;
    
    infosInput = cp5.addTextfield("")
    .setPosition(120, 100)
    .setSize(390, 30)
    .setFont(createFont("arial", 30))
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    ;
    
    cp5.addTextarea("nome")
    .setPosition(20, 350)
    .setSize(320, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(120))
    .setColorBackground(color(195, 100))
    .setColorForeground(color(249, 100))
    .setText("digite seu nome");
    
}

void draw(){
  
  background(0);
  
  switch (state) {
    case 0:
      cp5.get(Textarea.class, "titulo").setVisible(true);
      cp5.get(Textarea.class, "clique").setVisible(false);
      cp5.get(Textarea.class, "nome").setVisible(false);
      cp5.get(Textfield.class, "").setVisible(false);
      break;
   
    case 1:
      cp5.get(Textarea.class, "titulo").setVisible(true);
      cp5.get(Textarea.class, "clique").setVisible(true);
      break;
      
    case 2:
      cp5.get(Textarea.class, "titulo").setVisible(false);
      cp5.get(Textarea.class, "clique").setVisible(false);
      cp5.get(Textfield.class, "").setVisible(true);
      cp5.get(Textfield.class, "").setPosition(120, 100);
      cp5.get(Textarea.class, "nome").setVisible(true);
      cp5.get(Textarea.class, "nome").setText("digite seu nome");
      cp5.get(Textarea.class, "nome").setPosition(20, 350);
      break;
      
    case 3:
      cp5.get(Textfield.class, "").setPosition(180, 80);
      cp5.get(Textarea.class, "nome").setText("digite sua idade");
      cp5.get(Textarea.class, "nome").setPosition(30, 280);
      break;  
      
      
  }
}

void keyPressed() {
  
  if ( key == RETURN || key == ENTER)
  {
    if (state == 3)
    {
   infosOutput[] = infos[];  
   saveStrings(infosOutput[0]+".txt", infosOutput);
   println(infos);
    }
    if (state > 1)
    {
   infos = infos + "" + infosInput.getText();
   println("boink");
    }  
    
  state = (state+1) % (MAXSTATE+1);
  
  println(state);
  
  }
}
1 Like

#2

Please checking the reference on that

Do you want to use the name of the user as file name?

Use ctrl-t often in processing

What do you encounter that annoys you, what doesn’t run as you want it to?

0 Likes

#3

This is a bit dangerous

Better use else if here because

otherwise it will execute when state is 3

0 Likes

#4

Please revise that line. You should explain what you are trying to attempt with that line.

Kf

0 Likes

#5

hey Chrisir, thanks a lot for your answers!

yes, I’m currently using the name of the person for the file name!

I’ll try to indent my code a bit more, I use a small screen so I tend to keep things a little bit too cluttered :slight_smile:

what is bogusing me is that everytime I’m creating the .txt file it receives the information partially. the saveString method I tried is just something I found online, if you have any suggestions I’ll be glad to try and use it!

thanks in advance

0 Likes

#6

hey kfrajer, thanks for your time!

I’m thinking of using a single string to buffer all the information provided by the user (infos[]) and then replicating into another string (infosOutput[]) in order to save it. I somehow only managed to save the string once I changed from ‘infos[]’ to the Output one…

again, as I said, I’m trying some methods here but anything else you might think it would be useful, don’t refrain to suggest it to me! thanks a lot

0 Likes

#7

It is not clear what you are trying to do. Please remember we have no context about your application. You need to explain what each state suppose to do. You need to also tidy up your code. For instance:

  • if ( key == RETURN || key == ENTER)
  • This is not proper: infosOutput[] = infos[];
  • Explain this infosOutput[0] Where is this coming from?
  • infosInput = cp5.addTextfield("") You need to assign a name to your text field so it is my understanding. Check the ControlP5 reference.

Finally, if you are following some guide, please share it as well as it will help understand what your goal is.

Don’t forget to update your code to show the latest version. share your latest code.

Kf

0 Likes

#8

This is actually correct. See reference

0 Likes

#9

Use a for loop and copy each line separately

0 Likes

#10

I’d place the ENTER condition before the RETURN 1 b/c the former is much more widespread. :wink:

0 Likes

#11

Hello everyone, I find little to no time to actually tidy up my coding macarroni, sorry if it sounds or seems to confusing.

I tried to comment as much as I could into my original code, which I’m going to post, but I think I should address my question a little more directly: what is the best method for reading from cp5 textfields and writing into a single .txt file? at first I thought about using a buffer string array in order to save each question in a single array slot (I’m rusty into coding slang, are there array ‘slots’? hahahah) and then, using some kind of ‘randomizer’ tool, I’d also multiply the user answers throughout the string, in order to achieve a visual result similar to this: http://www.generative-gestaltung.de/2/sketches/?01_P/P_3_1_4_01.

/*

enTro


*/

import controlP5.*;
ControlP5 cp5;

Textfield infosInput; // naming textfield for better calling throughout the code

int state = 0;
int MAXSTATE = 3; // numbers of questions to implement switch/case

String infos;
String infosOutput[];

void setup(){
  
  size (500, 500);
  
  cp5 = new ControlP5(this);
  
  cp5.addTextarea("titulo")
    .setPosition(100, 100)
    .setSize(400, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    .setText("enTro");
    
  cp5.addTextarea("clique")
    .setPosition(280, 295)
    .setSize(200, 25)
    .setFont(createFont("arial", 12))
    .setLineHeight(14)
    .setColor(color(135))
    .setColorBackground(color(198, 100))
    .setColorForeground(color(255, 100))
    .setText("ENTER para continuar...")
    ;
    
    infosInput = cp5.addTextfield("")          //declared earlier, I name the textfield to aid later calling
    .setPosition(120, 100)
    .setSize(390, 30)
    .setFont(createFont("arial", 30))
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    ;
    
    cp5.addTextarea("nome")
    .setPosition(20, 350)
    .setSize(320, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(120))
    .setColorBackground(color(195, 100))
    .setColorForeground(color(249, 100))
    .setText("digite seu nome");
    
}

void draw(){
  
  background(0);
  
  switch (state) {
    case 0:                                                  //splash screen
      cp5.get(Textarea.class, "titulo").setVisible(true);
      cp5.get(Textarea.class, "clique").setVisible(false);
      cp5.get(Textarea.class, "nome").setVisible(false);
      cp5.get(Textfield.class, "").setVisible(false);
      break;
   
    case 1:                                                  //enter to continue
      cp5.get(Textarea.class, "titulo").setVisible(true);
      cp5.get(Textarea.class, "clique").setVisible(true);
      break;
      
    case 2:                                                  //user inputs their name
      cp5.get(Textarea.class, "titulo").setVisible(false);
      cp5.get(Textarea.class, "clique").setVisible(false);   //hides unused textfields
      cp5.get(Textfield.class, "").setVisible(true);
      cp5.get(Textfield.class, "").setPosition(120, 100);
      cp5.get(Textarea.class, "nome").setVisible(true);
      cp5.get(Textarea.class, "nome").setText("digite seu nome");
      cp5.get(Textarea.class, "nome").setPosition(20, 350);
      break;
      
    case 3:                                                  //user inputs their age
      cp5.get(Textfield.class, "").setPosition(180, 80);
      cp5.get(Textarea.class, "nome").setText("digite sua idade"); //changes the question of the box, in order to avoid creating multiple fields
      cp5.get(Textarea.class, "nome").setPosition(30, 280);        //slightly changes the position for aesthetics
      break;  
      
      
  }
}

void keyPressed() {
  
  if ( key == ENTER || key == RETURN)
    {
      if (state == 3)
        {
         /*infosOutput[] = infos[];  
         saveStrings(infosOutput[0]+".txt", infosOutput);
         println(infos);
         
         this step is reserved for saving the string into a .txt, but it raises the question: is it better to do
         after each single keypress or at the very end of the program, when a whole string is formed?
         
         that written, need to research a method for:
         
         - saving textfield into a .txt;
         - each answer from the user is stored in the same .txt;
         - preferrably in this step I already multiply randomly the answers throughout the strings, in order to generate a treemap afterwards:
         http://www.generative-gestaltung.de/2/sketches/?01_P/P_3_1_4_01;
         
         */
        }
      if (state > 1)
    {
     infos = infos + "" + infosInput.getText(); //is this valid? lol 
     println("boink"); //checking if the programs enters this conditional
    }  
    
  state = (state+1) % (MAXSTATE+1);
  
  println(state);
  
  }
}
1 Like

#12

this might be one way to do it.

We gather the inputs in one String infos but separate them by #
When saving we use split and then save

It makes files like Bob.txt, containing

Bob
1220

For each person / name a new file is created.

Remark
Alternatively, we could make one big file names.txt, more like a csv file containing

Bob,120
Ann,2220
Paul,34

Chrisir

import controlP5.*;
ControlP5 cp5;

Textfield infosInput;

int state = 0;
int MAXSTATE = 3;

String infos="";
// String infosOutput[];

void setup() {

  size (500, 500);

  cp5 = new ControlP5(this);

  cp5.addTextarea("titulo")
    .setPosition(100, 100)
    .setSize(400, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    .setText("enTro");

  cp5.addTextarea("clique")
    .setPosition(280, 295)
    .setSize(200, 25)
    .setFont(createFont("arial", 12))
    .setLineHeight(14)
    .setColor(color(135))
    .setColorBackground(color(198, 100))
    .setColorForeground(color(255, 100))
    .setText("clique para continuar...")
    ;

  infosInput = cp5.addTextfield("")
    .setPosition(120, 100)
    .setSize(390, 30)
    .setFont(createFont("arial", 30))
    .setColor(color(128))
    .setColorBackground(color(185, 100))
    .setColorForeground(color(255, 100))
    ;

  cp5.addTextarea("nome")
    .setPosition(20, 350)
    .setSize(320, 40)
    .setFont(createFont("arial", 30))
    .setLineHeight(14)
    .setColor(color(120))
    .setColorBackground(color(195, 100))
    .setColorForeground(color(249, 100))
    .setText("digite seu nome");
}

void draw() {

  background(0);

  text(state, 23, 23);
  infosInput.setFocus(true); 

  switch (state) {
  case 0:
    cp5.get(Textarea.class, "titulo").setVisible(true);
    cp5.get(Textarea.class, "clique").setVisible(false);
    cp5.get(Textarea.class, "nome").setVisible(false);
    cp5.get(Textfield.class, "").setVisible(false);
    break;

  case 1:
    cp5.get(Textarea.class, "titulo").setVisible(true);
    cp5.get(Textarea.class, "clique").setVisible(true);
    break;

  case 2:
    cp5.get(Textarea.class, "titulo").setVisible(false);
    cp5.get(Textarea.class, "clique").setVisible(false);
    cp5.get(Textfield.class, "").setVisible(true);
    cp5.get(Textfield.class, "").setPosition(120, 100);
    cp5.get(Textarea.class, "nome").setVisible(true);
    cp5.get(Textarea.class, "nome").setText("digite seu nome");
    cp5.get(Textarea.class, "nome").setPosition(20, 350);
    break;

  case 3:
    cp5.get(Textfield.class, "").setPosition(180, 80);
    cp5.get(Textarea.class, "nome").setText("digite sua idade");
    cp5.get(Textarea.class, "nome").setPosition(30, 280);
    break;
  }
}

void keyPressed() {

  if ( key == RETURN || key == ENTER)
  {
    if (state > 1)
    {
      // even in state 3 we execute the following lines and save afterwards (so please no else if)
      infos = infos + "#" + infosInput.getText();
      infosInput.setText("");
      println("boink: "+infos);
    }  
    if (state == 3)
    {
      // saving 
      infos=infos.trim(); 
      if (infos.charAt(0) == '#') 
        infos=infos.substring(1); // delete leading # 
      // println("new:"+infos); 
      String[] infosOutput1 = split(infos, '#');  
      // reference says: saveStrings(filename, data)
      saveStrings(infosOutput1[0] + ".txt", infosOutput1);
      // println(infos);
    } 
    if (state==0) {
      // reset
      infos="";
    }

    state = (state+1) % (MAXSTATE+1);

    // println(state);
  }
}//func 
//
0 Likes