sclass InputChooser implements Swingable { DynModule module; bool myInput; S ownInput; transient int delay; transient S input; transient JPanel panel; transient JTextField tfInput; transient JCheckBox cbInput; *() {} // only for persistence *(DynModule *module) {} S input() { ret input; } S _freshInput() { ret myInput ? ownInput : dm_getInterestingString(); } void forceUpdate { input = null; module.updateMe(); } void forgetInput { input = null; } bool update() { S s = _freshInput(); ifdef InputChooser_verbose print("Fresh input: " + s); endifdef if (neq(input, s)) { input = s; true; //dm_updateModule(); } false; } public JComponent visualize() { if (panel != null) ret panel; tfInput = jcenteredtextfield(ownInput); cbInput = setToolTip("Use my own input", jcheckbox(myInput)); onChangeAndNow(cbInput, r { setEnabled(tfInput, isChecked(cbInput)); myInput = isChecked(cbInput); updateModule(); }); onChange(tfInput, r { if (myInput) { ownInput = getText(tfInput); updateModule(); } }); ret panel = westAndCenter(cbInput, tfInput); } void updateModule { doLaterOrNow(delay, r { module.updateMe() }); } }