abstract sclass DynRecordingTextArea extends DynModule { S text; S globalID = aGlobalID(); transient JTextArea ta; transient EditRecorder recorder; transient ReliableSingleThread rstPersistText = rstWithDelay(1000, r persistText); // We have auto-save of deleted modules //bool warnOnDelete() { ret nempty(text); } File logFile() { ret javaxDataDir("Text Area Logs/" + globalID); } visualize { ta = jenableUndoRedo(typeWriterTextArea(text)); logQuoted(logFile(), "text: " + text); recorder = new EditRecorder(voidfunc(EREvent e) { logStructure(logFile(), e); }); recorder.text = text; main.onChange(ta, rstPersistText); ret jscroll(setOpaqueBackground(Color.white, withMargin(ta))); } void persistText enter { if (ta == null) ret; Pair p = textAndCaretPosition(ta); recorder.update(p.a); recorder.updateCaret(p.b); print("persistText " + now()); setField(text := getText(ta)); } void unvisualize { persistText(); super.unvisualize(); } void setText(S text) { main.setText(ta, text); } S text() { ret or(main.getText(ta), text); } S _modifyStructForDuplication(S struct) { // TODO: could fail if module gets more complex ret jreplace_first(struct, "globalID=*", "globalID=" + quote(aGlobalID())); } enhanceFrame { internalFrameMenuItem(f, "Global ID: " + globalID, null); } }