# Letting the User Set String (Save As... Dialog)

**URL:** <https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321>\
**Category:** Coding Questions\
**Created:** [July 18, 2021, 5:43pm UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321 "2021-07-18T17:43:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![dtools22](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@dtools22](https://discourse.processing.org/u/dtools22)\
**Post date:** [July 18, 2021, 5:43pm UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/1 "2021-07-18T17:43:08Z")

</div>

Hello,

I am writing a program that contains a “save file” mechanic to it. What I want to do is offer the user of the program a chance to name the save file to whatever they wish. I believe I understand the gist of the steps. But I’m having some trouble understanding how I take in keyboard inputs from the user. Currently the program runs 100% on mouse click buttons.

The base idea I have is that there is some `String filename` that I create and that the user will assign a value to using the keyboard.

My question is, how to I log the keystrokes from the user effectively? I just want the user to be able to name a String in the program something like “My Save” or “Version 1”. I understand how I can turn that String value into a file directory where files get saved.

Thank you all for the help as always!

---

<div class="post-metadata">

**Author:** ![th75](https://avatars.discourse-cdn.com/v4/letter/t/ebca7d/32.png) [@th75](https://discourse.processing.org/u/th75)\
**Post date:** [July 18, 2021, 11:09pm UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/2 "2021-07-18T23:09:06Z")

</div>

hi,

does [selectOutput](https://processing.org/reference/selectOutput_.html) is what you re looking for?  
then filename=selection.getAbsolutePath();

or it s just a filename on screen like in games saved slots?

---

<div class="post-metadata">

**Author:** ![dtools22](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@dtools22](https://discourse.processing.org/u/dtools22)\
**Post date:** [July 19, 2021, 12:09am UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/3 "2021-07-19T00:09:32Z")

</div>

So, I do know selectOutput. I think that’s to call an existing file so that would be for my “load” functionality.

What I’m looking for is for the user to be able to input a string that will be the “save” filename.

My program tracks some information as you use it and stores that information in a spread sheet. But if you close and reopen the program all of those sheets reset. I want to allow the player to save progress with a filename of their choice.

---

<div class="post-metadata">

**Author:** ![th75](https://avatars.discourse-cdn.com/v4/letter/t/ebca7d/32.png) [@th75](https://discourse.processing.org/u/th75)\
**Post date:** [July 19, 2021, 12:40am UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/4 "2021-07-19T00:40:23Z")

</div>

> [@dtools22](#):
>
> call an existing file so that would be for my “load”

to load it s usually selectInput, try selectoutput, it does that: asking user for a filename no?

---

<div class="post-metadata">

**Author:** ![dtools22](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@dtools22](https://discourse.processing.org/u/dtools22)\
**Post date:** [July 20, 2021, 1:09am UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/5 "2021-07-20T01:09:18Z")

</div>

You are right, I misread the processing documentation so thank you for the correction.

However, I’m not sure `selectOutput()` works with my existing code, or I’m possible not understanding it well enough. It still requires that a preexisting file be chosen from the hard drive. I want the user of my program to create a new file location that will be saved to.

A little more background. My program is built to track turns, dice rolls, and other in-game play information from a board game. I want this information saved so that I can create a save-progress function in my program to let the user stop mid game if desired. I currently have all of the information I need written into different .csv files in the `draw()` function. When you stop the program, those files have the stored information from your stop point. The problem is unless you manually move the .csv files to a new directory or change the file names in the code before running again, they just get reset when you run the program a second time.

My goal when I asked this question was to try to let the user create a new directory at the start of the program where the .csv files will go. That way I could eventually write a function that allows that .csv data to be loaded back into the program like a save game style file without the user needing to relocate files on their own machine.

The way I currently have this programmed, all I need is for a prompt to ask the player what to call the save file. Then I can just use something like this to create a directory for the saved data that I can reference later.

`saveTable(tablename, stringchosenbyuser +"/tablename.csv");`

So, should I rewrite the existing code to save the data differently as the user proceeds through the program? Or, how can I prompt the user to assign a String value at the beginning of the program?

---

<div class="post-metadata">

**Author:** ![CodeMasterX](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/codemasterx/32/2942_2.png) [@CodeMasterX](https://discourse.processing.org/u/CodeMasterX)\
**Post date:** [July 20, 2021, 9:04am UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/6 "2021-07-20T09:04:52Z")

</div>

use this as reference [My projects library #4! Gallery Megathread - #2 by CodeMasterX](https://discourse.processing.org/t/my-projects-library-4-gallery-megathread/31103/2)

I’ll post the actual program a bit later

Here:

```auto
import javax.swing.JOptionPane;
String pLines = "Welcome to quasi console!\n ";
void setup() {
  String strInp = JOptionPane.showInputDialog(null,"Please name the file! (FILETYPE: .png" );
  println(strInp+".png");
}
void draw() {
}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [July 20, 2021, 10:41am UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/7 "2021-07-20T10:41:18Z")

</div>

> [@dtools22](#):
>
> sure `selectOutput()` works with my existing code, or I’m possible not understanding it well enough. It still requires that a preexisting file be chosen from the hard drive.

No.

* * *

this is the dialog you are looking for

basically you can

- abort the dialog
- choose a folder / drive
- type in file name
- You can change the Header of the Save Dialog like “Save Your Chess Game” or whatnot
- Consider to add a file extension like .txt when missing automatically

**Remark**

But, sure it is more elegant to let the user type in the name of the save file and the Sketch takes care of the folder location. Or just create a file name by player name + date + time + number of move or so.

I mean even the load file dialog provides too much stuff - you could just handle the list of save games yourself.

Chrisir

```auto
// Demo for selectOutput

int status=0; 
String fileNameFromSave=""; 

void setup() {
  size (600, 600);

  // start our save dialog and connect it to the function fileSelected
  selectOutput("Choose name and location to save:", "fileSelected");
}

void draw() {
  // empty
  background(0); 
  switch(status) {

  case 0: 
    break; 

  case 1: 
    text("abort", 44, 44);
    break; 

  case 2: 
    text("saved as "+fileNameFromSave, 44, 44);
    break; 

  default:
    text("Error 1638 ", 44, 44);
    break;
  }
}

// ------------------------------------------------------------------------------------------

void fileSelected(File selection) {
  if (selection == null) {
    println("Window was closed or the user hit cancel.");
    status=1;
  } else {
    println("User saves as " + selection.getAbsolutePath());

    String[] arrayTest = new String[1];
    arrayTest[0]="Test 33"; 
    saveStrings(selection.getAbsolutePath(), arrayTest);
    status=2; 
    fileNameFromSave = selection.getAbsolutePath();
  }//else
}//func 
//

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [July 20, 2021, 12:23pm UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/8 "2021-07-20T12:23:53Z")

</div>

here 2 examples

- where the user can select a file without using the file dialog
- and WITH dialog

```auto
StringList StringListFileNames;

// for mouse input
int selectedMouse=-1; 
int selectedFile=-1; 
boolean clicked=false;

String[] arrayLoadedFileContent; 

//---------------------------------------------------------------------------
// processing core functions 

void setup() {
  size(880, 800);
  background(111); // gray
}

void draw() {
  background(111); // gray
  updateList(); 
  showList();

  // show file name and content (first line)
  if (selectedFile>-1 && clicked) {
    text(StringListFileNames.get(selectedFile)
      +"\n"
      +"\n"
      +content(), 333, 333);
  }
}

//---------------------------------------------------------------------------
// Tool content()

String content() {

  // abort ? 
  if (arrayLoadedFileContent==null) 
    return ""; 

  // file not empty? ------------------------
  if (arrayLoadedFileContent.length>0) {
    String result=""; 
    for (String s1 : arrayLoadedFileContent) {
      result+= s1 
        + "\n";
    }//for 
    return result; // success
  }//if 

  // return / fail 
  return "";
}//func 

//---------------------------------------------------------------------------
// Other functions 

void updateList() {
  File file = new File(dataPath(""));
  String[] fileList = file.list();

  if (fileList==null) {
    println("Folder is empty.");
  } else {
    // success
    StringListFileNames = new StringList();
    for (String s1 : fileList) { 
      StringListFileNames.append(s1);
    }

    StringListFileNames.sort();
  }//else
}//func 

void showList() {
  if (StringListFileNames==null) 
    return; // leave 

  int i=0; 
  for (String s1 : StringListFileNames) { 
    noFill();
    if (mouseY> 44+i*22-22 && 
      mouseY< 44+i*22 + 0) {
      rect(5, 44+i*22-12, 222, 22);
      selectedMouse=i;
    }
    fill(255); 
    text(s1, 33, 44+i*22);
    i++;
  }//for
  //
}//func

void mousePressed() {
  //
  int i=0; 
  for (String dummy : StringListFileNames) { 
    if (mouseY> 44+i*22-22 && 
      mouseY< 44+i*22 + 0) {
      selectedMouse=i;
      // copy 
      selectedFile=selectedMouse; 
      // set marker
      clicked=true;
      // load 
      arrayLoadedFileContent = loadStrings(StringListFileNames.get(selectedFile));
      return;
    }//if
    i++;
  }//for
}
//

```

* * *

**WITH dialog**

```auto

// states for sketch as a whole 
final int stateWaitForLoad = 0;
final int stateNormal = 1;
final int stateCancel = 2;
int state = stateWaitForLoad;

String loadPath=""; 
String loadedFile = ""; 

String[] arrayLoadedFileContent; 

void setup() {
  size (1000, 600);
  background(111); 
  loadProgram();
}

void draw() {

  background(111);

  switch(state) {

  case stateWaitForLoad:
    text("waiting", 23, 23);
    break; 

  case stateNormal:
    text(loadedFile
      + "\n"
      + "\n"
      + content(), 23, 23);
    break; 

  case stateCancel:
    // cancel 
    text("User hit cancel", 23, 23);
    break; 

  default:
    // error
    break;
  }
}

// -----------------------------------------------------------

void loadProgram() {
  // init the dialog for loading 
  state = stateWaitForLoad;
  loadPath="";
  File start1 = new File(sketchPath("")+"/*.abc"); 
  selectInput("Select a file to load:", "fileSelectedForLoad", start1);
}

void fileSelectedForLoad(File selection) {
  // this gets called when the dialog is ended 
  if (selection == null) {
    // Error 
    println("Window was closed or the user hit cancel.");
    state=stateCancel;
  } else {
    loadPath = selection.getAbsolutePath();
    loadedFile = selection.getAbsolutePath();
    arrayLoadedFileContent = loadStrings(loadedFile); 
    println("User selected " + selection.getAbsolutePath());
    state = stateNormal;
  }
}

//---------------------------------------------------------------------------
// Tool content()

String content() {

  // abort ? 
  if (arrayLoadedFileContent==null) 
    return ""; 

  // file not empty? ------------------------
  if (arrayLoadedFileContent.length>0) {
    String result=""; 
    for (String s1 : arrayLoadedFileContent) {
      result+= s1 
        + "\n";
    }//for 
    return result; // success
  }//if 

  // return / fail 
  return "";
}//func 
//

```

---

<div class="post-metadata">

**Author:** ![dtools22](https://avatars.discourse-cdn.com/v4/letter/d/f19dbf/32.png) [@dtools22](https://discourse.processing.org/u/dtools22)\
**Post date:** [July 20, 2021, 3:26pm UTC](https://discourse.processing.org/t/letting-the-user-set-string-save-as-dialog/31321/9 "2021-07-20T15:26:58Z")

</div>

Thank you all for the help. This forum has been a very big asset for me on this project and I really appreciate the time you all took.

Now I just need to play with your suggestions and see which one works best for my current program 🙂
