Read and edit a text file (Editor)

My take on the problem -

A Line based Text File Editor
User requirements

  1. The text is edited on a line by line basis
  2. When a file is selected the original is copied to make a backup
  3. The user can traverse the file forwards and backwards through the file
  4. Lines can be edited in any order.
  5. Line changes are automatically remembered
  6. User can commit all changes to the original file (overwriting it)
  7. Popup dialogs warnings to prevent user going passed beginning and end of file
  8. 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");
}
1 Like