My take on the problem -
A Line based Text File Editor
User requirements
- The text is edited on a line by line basis
- When a file is selected the original is copied to make a backup
- The user can traverse the file forwards and backwards through the file
- Lines can be edited in any order.
- Line changes are automatically remembered
- User can commit all changes to the original file (overwriting it)
- Popup dialogs warnings to prevent user going passed beginning and end of file
- Popup warning before committing changes allowing original file to be unchanged
Java Swing is not used instead this sketch uses the G4P library (install from Contributions Manager).
import g4p_controls.*;
// GUI controls
GTextField txfLine;
GButton btnFirst, btnPrev, btnNext, btnLast, btnSave, btnOpen;
GLabel lblTitle, lblGuide, lbl0, lbl1, lblLineNo, lblNbrLines;
// File editing variables
String fname;
String[] lines;
int ln = 0, nbrLines = 0;
public void setup() {
size(600, 300, JAVA2D);
createGUI();
}
public void draw() {
background(230);
}
void openFile() {
fname = G4P.selectInput("Text file to edit", "txt", "text files");
if (fname != null) {
lines = loadStrings(fname);
saveStrings(fname + ".copy", lines);
ln = 1;
nbrLines = lines.length;
displayLineCounter();
showCurrentLine();
}
}
void saveChanges() {
int reply = G4P.selectOption(this, "This will overwrite the original file",
"Do you wish to continue?", G4P.WARN_MESSAGE, G4P.OK_CANCEL);
if (reply == G4P.CANCEL || reply == G4P.CLOSED) {
println("Cancelled");
return;
}
keepEditedLine();
saveStrings(fname, lines);
}
void nextLine() {
if (ln == nbrLines) {
G4P.showMessage(this, "Currently showing last line",
"No next line", G4P.WARN_MESSAGE);
return;
}
keepEditedLine();
ln++;
displayLineCounter();
showCurrentLine();
}
void prevLine() {
if (ln == 1) {
G4P.showMessage(this, "Currently showing first line",
"No previous line", G4P.WARN_MESSAGE);
return;
}
keepEditedLine();
ln--;
displayLineCounter();
showCurrentLine();
}
void firstLine() {
if (ln > 1) {
keepEditedLine();
ln = 1;
displayLineCounter();
showCurrentLine();
}
}
void lastLine() {
if (ln < nbrLines) {
keepEditedLine();
ln = nbrLines;
displayLineCounter();
showCurrentLine();
}
}
void keepEditedLine() {
lines[ln - 1] = txfLine.getText();
}
void showCurrentLine() {
txfLine.setText(lines[ln - 1]);
}
void displayLineCounter() {
lblLineNo.setText("" + ln);
lblNbrLines.setText("" + nbrLines);
}
// G4P event handlers
public void gotoPrevLine(GButton source, GEvent event) {
prevLine();
}
public void gotoNextLine(GButton source, GEvent event) {
nextLine();
}
public void saveChanges(GButton source, GEvent event) {
saveChanges();
}
public void openFile(GButton source, GEvent event) {
openFile();
}
public void gotoFirst(GButton source, GEvent event) {
firstLine();
}
public void gotoLast(GButton source, GEvent event) {
lastLine();
}
public void createGUI(){
G4P.messagesEnabled(false);
G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
G4P.setMouseOverEnabled(false);
G4P.setDisplayFont("Arial", G4P.PLAIN, 14);
G4P.setInputFont("Arial", G4P.PLAIN, 14);
surface.setTitle("Sketch Window");
txfLine = new GTextField(this, 10, 140, 580, 36, G4P.SCROLLBARS_HORIZONTAL_ONLY | G4P.SCROLLBARS_AUTOHIDE);
txfLine.setOpaque(false);
lblTitle = new GLabel(this, 10, 10, 490, 30);
lblTitle.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
lblTitle.setText("Line by Line File Editor");
lblTitle.setOpaque(true);
btnPrev = new GButton(this, 10, 180, 110, 30);
btnPrev.setText("Previous");
btnPrev.addEventHandler(this, "gotoPrevLine");
btnNext = new GButton(this, 130, 180, 110, 30);
btnNext.setText("Next");
btnNext.addEventHandler(this, "gotoNextLine");
btnSave = new GButton(this, 510, 210, 80, 80);
btnSave.setText("Save Changes");
btnSave.setLocalColorScheme(GCScheme.RED_SCHEME);
btnSave.addEventHandler(this, "saveChanges");
btnOpen = new GButton(this, 510, 10, 80, 120);
btnOpen.setText("Open File to Edit");
btnOpen.setLocalColorScheme(GCScheme.GREEN_SCHEME);
btnOpen.addEventHandler(this, "openFile");
lblGuide = new GLabel(this, 10, 40, 490, 90);
String guide = "Click on the green button to select the file to edit. ";
guide += "A copy of the original file will be created with a '.code' extension. \n";
guide += "You can move forward and backwards through the file making changes but ";
guide += "these will not overwrite the original file unless you click on the ";
guide += "'Save Changes' button.";
lblGuide.setText(guide);
lblGuide.setOpaque(false);
lbl0 = new GLabel(this, 440, 180, 40, 20);
lbl0.setTextAlign(GAlign.RIGHT, GAlign.MIDDLE);
lbl0.setText("Line ");
lbl0.setOpaque(false);
lblLineNo = new GLabel(this, 480, 180, 40, 20);
lblLineNo.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
lblLineNo.setText("?");
lblLineNo.setOpaque(true);
lblNbrLines = new GLabel(this, 550, 180, 40, 20);
lblNbrLines.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
lblNbrLines.setText("?");
lblNbrLines.setOpaque(true);
lbl1 = new GLabel(this, 520, 180, 30, 20);
lbl1.setTextAlign(GAlign.CENTER, GAlign.MIDDLE);
lbl1.setText("of");
lbl1.setOpaque(false);
btnFirst = new GButton(this, 10, 220, 50, 20);
btnFirst.setText("First");
btnFirst.addEventHandler(this, "gotoFirst");
btnLast = new GButton(this, 190, 220, 50, 20);
btnLast.setText("Last");
btnLast.addEventHandler(this, "gotoLast");
}
