abstract sclass DynDialogWithUser > DynModule { L dialog = synchroList(); S input; transient JTextArea taDialog; transient JTextField tfInput; sclass DialogItem { S author, line; long timestamp = now(); toString { ret "[" + localTimeWithSeconds(timestamp) + "] " + author + ": " + line; } } visualize { ret centerAndSouthWithMargins( jSection("Dialog", taDialog = jLiveValueWordWrapTypeWriterTextArea_autoScroll(mapLiveValue_f0(func -> S { dialogToString() }, S, dm_fieldLiveValue('dialog)))), withLabel("Your input:", tfInput = dm_fieldTextField('input))); } // API S dialogToString() { ret lines_rtrim(allToString(cloneList(dialog))); } void addLine(S author, S line) { dialog.add(nu(DialogItem.class, +author, +line)); } }