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

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!

hi,

does selectOutput is what you re looking for?
then filename=selection.getAbsolutePath();

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

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.

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

1 Like

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?

use this as reference My projects library #4! Gallery Megathread - #2 by CodeMasterX

I’ll post the actual program a bit later

Here:

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() {
}
1 Like

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

// 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 
//

2 Likes

here 2 examples

  • where the user can select a file without using the file dialog
  • and WITH dialog
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



// 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 
//

1 Like

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 :slight_smile:

2 Likes