Here is a new version based on my previous one.
You can still load and save but you now have an Editor from the g4p library (also a GUI library).
Again, Sketch is in one part, but you can split it up into tabs.
[NEW VERSION BELOW]
// ********************************************************************************
// joined pde-file of folder
// ********************************************************************************
// ********************************************************************************
// tab: Editor2.pde main file (file name is folder name)
// Editor ::: using G4P : GTextArea as Editor Element
// Demo for Editor and Save and load handling
// SEE 3 buttons lower right corner !!!!!!!!!!!!!!!!!!!!!!!!
// SKETCH EXPECTS A SUB FOLDER texts in the Sketch folder, see: final String pathFolder = "texts";
//
//
// from https : // forum.processing.org/two/discussion/comment/112902/#Comment_112902
import g4p_controls.*;
GTextArea txaSample;
// editor path and file extension
final String pathFolder = "texts";
final String fileExtension = ".txt";
// editor content
// String str = "Test ";
// states of the program:
// unique constants:
final int normal = 0;
final int save = 1;
final int load = 2;
///current state (must be one of them)
int state=normal;
// blinking cursor:
boolean blinkIsOn=true;
// Paths (returned by 'callback' functions)
String savePath="";
String loadPath="";
// ------------------------------------------------
// Core functions of processing
void setup() {
size(900, 900);
// Create a text area with both horizontal and
// vertical scrollbars that automatically hide
// when not needed.
txaSample = new GTextArea(this,
20, 20,
width-200, height-60,
G4P.SCROLLBARS_BOTH | G4P.SCROLLBARS_AUTOHIDE);
txaSample.setText("Hello", 310);
// Set some default text
// txaSample.setPromptText("Please enter some text");
}//func
void draw() {
switch (state) {
case normal:
drawForStateNormal() ;
break;
case save:
// wait for Save Dialog
waitForSaveDialog();
break;
case load:
// wait for Load Dialog
waitForLoadDialog();
break;
default:
//Error
println("Error: 4711");
exit();
break;
//
}//switch
//
}//func
//
// ********************************************************************************
// tab: InputsKeys.pde
// keep it simple
void keyPressed() {
if (state!=normal)
return;
// for the editor:
//if ( keyCode == DELETE || keyCode == BACKSPACE ) {
// if ( str.length() > 0 ) {
// str = str.substring(0, str.length()-1);
// }
//} else {
// if ( key != CODED ) {
// str += key;
// }
//}
}
//
// ********************************************************************************
// tab: InputsMouse1.pde
//
void mousePressed() {
if (state!=normal)
return;
// for the buttons
if ( overSave() ) {
initSave();
}
//---
else if ( overLoad() ) {
initLoad();
}
//---
else if ( overNew() ) {
// str="";
txaSample.setText("Hello", 310);
}
//
}//func
// ----------------------------------------------------------
// functions to register if mouse is over buttons
boolean overSave() {
return( mouseX > width-40 &&
mouseY > height-20 );
}
boolean overLoad() {
return( mouseX > width-40 &&
mouseY > height-50 &&
mouseY < height-50+25 );
}
boolean overNew() {
return( mouseX > width-40 &&
mouseY > height-80 &&
mouseY < height-80+25 );
}
//
// ********************************************************************************
// tab: SaveLoad.pde
// Save and load
// 4 blocks with 2 functions each, for save and load
void initSave() {
// init save process
// reset
savePath="";
// make date time stamp (the expression nf(n,2) means leading zero: 2 becomes 02)
String dateTimeStamp = year()
+ nf(month(), 2)
+ nf(day(), 2)
+ "-"
+ nf(hour(), 2)
+ nf(minute(), 2)
+ nf(second(), 2);
// prepare fileDescription which occurs in the dialogue
File fileDescription = new File( sketchPath()
+ "//"
+ pathFolder
+ "//"
+ dateTimeStamp
+ fileExtension);
// open the dialog
selectOutput("Select a file to write to", "fileSelectedSave", fileDescription);
// set state to wait
state=save;
}
void initLoad() {
// init load process
// reset
loadPath="";
// prepare fileDescription which occurs in the dialogue
File fileDescription = new File( sketchPath()+"//"+pathFolder+"//"+"*" + fileExtension );
// open the dialog
selectInput("Select a file to load", "fileSelectedLoad", fileDescription);
// set state to wait
state=load;
}
// --------------------------------------------------------------------
void fileSelectedSave(File selection) {
// the 'callback' function
if (selection == null) {
// println("Window was closed or the user hit cancel.");
// go back
state=normal;
} else {
// println("User selected " + selection.getAbsolutePath());
savePath=selection.getAbsolutePath();
}
}
void fileSelectedLoad(File selection) {
// the 'callback' function
if (selection == null) {
// println("Window was closed or the user hit cancel.");
// go back
state=normal;
} else {
// println("User selected " + selection.getAbsolutePath());
loadPath=selection.getAbsolutePath();
}
}
// ----------------------------------------------------
// waiting
void waitForSaveDialog() {
if (!savePath.equals("")) {
// waiting is over
saveIt();
// go back
state=normal;
}
}
void waitForLoadDialog() {
if (!loadPath.equals("")) {
// waiting is over
loadIt();
// go back
state=normal;
}
}
// ----------------------------------------------------
void saveIt() {
// save
// split at line break and make array (to save it)
// get the data from the text Area
String[] strs = split(txaSample.getText(), "\n" );
// check if file extension (fileExtension, e.g. .txt) is there
int len = savePath.length();
if (len<4 || !savePath.substring( len-4 ).equals(fileExtension)) {
// file Extension is not present, we have to add it
savePath += fileExtension; // add the file Extension
}
// save
println("Saved: " + savePath);
saveStrings( savePath, strs );
}
void loadIt() {
// load
String[] strs = loadStrings( loadPath );
String str1 = join(strs, "\n");
txaSample.setText(str1, 310);
}
//
// ********************************************************************************
// tab: States.pde
void drawForStateNormal() {
background(0);
textSize(14);
// title
fill(255, 2, 2);
text("My Little Editor",
width-133, 20,
130, 422);
// show the text the user entered
//fill(255);
//text(str+blink(),
// 20, 20, width-177, height-20);
// ----------------------
// buttons
textSize(11);
fill(128);
if ( overSave() ) {
fill(196);
}
rect(width-40, height-20, 40, 20);
fill(255);
text("Save",
width-40+7, height-9+5);
// ---
fill(128);
if ( overLoad() ) {
fill(196);
}
rect(width-40, height-50, 40, 20);
fill(255);
text("Load",
width-40+7, height-50+9+5);
// ---
fill(128);
if ( overNew() ) {
fill(196);
}
rect(width-40, height-80, 40, 20);
fill(255);
text("New",
width-40+7, height-80+9+5);
}
// ********************************************************************************
// tab: Tools.pde
// Misc
String blink() {
// toggle blinkIsOn
if (frameCount%17 == 0)
blinkIsOn=!blinkIsOn;
// depending from blinkIsOn
if (blinkIsOn)
return "|";
else return "";
}
//
// End of joined file. ********************************************************************************
NEW VERSION
new version with button class, better button handling
// ********************************************************************************
// joined pde-file of folder Editor2
// ********************************************************************************
// ********************************************************************************
// tab: Editor2.pde main file (file name is folder name)
// Editor ::: using G4P : GTextArea as Editor Element
// Demo for Editor and Save and load handling
// SEE 3 buttons !!!!!!!!!!!!!!!!!!!!!!!!
// SKETCH EXPECTS A SUB FOLDER texts in the Sketch folder, see: final String pathFolder = "texts";
//
//
// from https : // forum.processing.org/two/discussion/comment/112902/#Comment_112902
import g4p_controls.*;
GTextArea txaSample;
// editor path and file extension
final String pathFolder = "texts";
final String fileExtension = ".txt";
// states of the program:
// unique constants:
final int normal = 0;
final int save = 1;
final int load = 2;
///current state (must be one of them)
int state=normal;
// blinking cursor:
boolean blinkIsOn=true;
// Paths (returned by 'callback' functions after using save and load)
String savePath="";
String loadPath="";
// list of buttons
ArrayList<Button> listButton = new ArrayList();
// ------------------------------------------------
// Core functions of processing
void setup() {
size(900, 900);
// Create a text area with both horizontal and
// vertical scrollbars that automatically hide
// when not needed.
txaSample = new GTextArea(this,
20, 20,
width-200, height-60,
G4P.SCROLLBARS_BOTH | G4P.SCROLLBARS_AUTOHIDE);
txaSample.setText("Hello", 310);
// Set some default text
// txaSample.setPromptText("Please enter some text");
// init buttons
int i=0;
listButton.add(new Button ("Save", width-70, 60+i*40, 50, 25));
i++;
listButton.add(new Button ("Load", width-70, 60+i*40, 50, 25));
i++;
listButton.add(new Button ("New", width-70, 60+i*40, 50, 25));
i++;
}//func
void draw() {
switch (state) {
case normal:
drawForStateNormal() ;
break;
case save:
// wait for Save Dialog
waitForSaveDialog();
break;
case load:
// wait for Load Dialog
waitForLoadDialog();
break;
default:
//Error
println("Error: 4777");
exit();
break;
//
}//switch
//
}//func
//
// ********************************************************************************
// tab: classButton.pde
class Button {
String textButton;
PVector position = new PVector();
float sizeW, sizeH;
// constructor
Button ( String s1_,
float x_, float y_,
float sizeW_, float sizeH_ ) {
position.set(x_, y_);
sizeW = sizeW_;
sizeH = sizeH_;
textButton=s1_;
}// constructor
// ------------------------------------------
// methods
void display() {
// show button
// rect
stroke(200);
//noFill();
fill(255);
if (checkMouse())
fill(255, 0, 0);
if (checkMouse()&&mousePressed)
fill(255, 0, 120);
rect(position.x, position.y,
sizeW, sizeH);
// text
fill(0);
text(textButton,
position.x+5, position.y+17);
}// method
boolean checkMouse() {
// returns true when inside
return
mouseX > position.x &&
mouseX < position.x + sizeW &&
mouseY > position.y &&
mouseY < position.y + sizeH;
} // method
//
}//class
//
// ********************************************************************************
// tab: InputsKeys.pde
// keep it simple
void keyPressed() {
if (state!=normal)
return;
}
//
// ********************************************************************************
// tab: InputsMouse1.pde
//
void mousePressed() {
if (state!=normal)
return;
String command="";
// for the buttons
for (Button currentButton : listButton) {
if (currentButton.checkMouse()) {
command=currentButton.textButton;
break;
}
}//for
if (command.equals(""))
return;
switch(command) {
case "Load":
initLoad();
break;
case "Save":
initSave();
break;
case "New":
txaSample.setText("Hello", 310);
break;
default:
// Error
println("unknown command "+command);
exit();
break;
}//switch
//
} //func
//
// ********************************************************************************
// tab: SaveLoad.pde
// Save and load
// 4 blocks with 2 functions each, for save and load
// --------------------------------------------------------------------
// the two init functions
void initSave() {
// init save process
// reset
savePath="";
// make date time stamp (the expression nf(n,2) means leading zero: 2 becomes 02)
String dateTimeStamp = year()
+ nf(month(), 2)
+ nf(day(), 2)
+ "-"
+ nf(hour(), 2)
+ nf(minute(), 2)
+ nf(second(), 2);
// prepare fileDescription which occurs in the dialogue
File fileDescription = new File( sketchPath()
+ "//"
+ pathFolder
+ "//"
+ dateTimeStamp
+ fileExtension);
// open the dialog
selectOutput("Select a file to write to", "fileSelectedSave", fileDescription);
// set state to wait
state=save;
}
void initLoad() {
// init load process
// reset
loadPath="";
// prepare fileDescription which occurs in the dialogue
File fileDescription = new File( sketchPath()+"//"+pathFolder+"//"+"*" + fileExtension );
// open the dialog
selectInput("Select a file to load", "fileSelectedLoad", fileDescription);
// set state to wait
state=load;
}
// --------------------------------------------------------------------
// the two 'callback' functions
void fileSelectedSave(File selection) {
// the 'callback' function
if (selection == null) {
// println("Window was closed or the user hit cancel.");
// go back
state=normal;
} else {
// println("User selected " + selection.getAbsolutePath());
savePath=selection.getAbsolutePath();
}
}
void fileSelectedLoad(File selection) {
// the 'callback' function
if (selection == null) {
// println("Window was closed or the user hit cancel.");
// go back
state=normal;
} else {
// println("User selected " + selection.getAbsolutePath());
loadPath=selection.getAbsolutePath();
}
}
// ----------------------------------------------------
// waiting
void waitForSaveDialog() {
if (!savePath.equals("")) {
// waiting is over
saveIt();
// go back
state=normal;
}
}
void waitForLoadDialog() {
if (!loadPath.equals("")) {
// waiting is over
loadIt();
// go back
state=normal;
}
}
// ----------------------------------------------------
// executing save and load
void saveIt() {
// save
// split at line break and make array (to save it)
// get the data from the text Area
String[] strs = split(txaSample.getText(), "\n" );
// check if file extension (fileExtension, e.g. .txt) is there
int len = savePath.length();
if (len<4 || !savePath.substring( len-4 ).equals(fileExtension)) {
// file Extension is not present, we have to add it
savePath += fileExtension; // add the file Extension
}
// save
println("Saved: " + savePath);
saveStrings( savePath, strs );
}
void loadIt() {
// load
String[] strs = loadStrings( loadPath );
String str1 = join(strs, "\n");
txaSample.setText(str1, 310);
}
//
// ********************************************************************************
// tab: States.pde
void drawForStateNormal() {
background(0);
textSize(14);
// title
fill(255, 2, 2);
text("My Little Editor",
width-133, 20,
130, 422);
// buttons
for (Button currentButton : listButton) {
currentButton.display();
} //for
//
}
//
// End of joined file. ********************************************************************************