import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import java.time.Duration;
import java.lang.invoke.VarHandle;
import java.lang.invoke.MethodHandles;
import javax.swing.undo.UndoManager;
import javax.swing.border.*;
import java.awt.geom.*;
import java.awt.datatransfer.StringSelection;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.awt.datatransfer.*;
import java.text.SimpleDateFormat;
import java.nio.charset.Charset;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import static x30_pkg.x30_util.DynamicObject;
import javax.swing.Icon;
import java.nio.file.Path;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
class main {
static class SimpleCRUD_v2 extends JConceptsTable {
JPanel buttons, panel;
Set unshownFields; // not shown in table or form
Set excludeFieldsFromEditing;
String modifiedField; // field to hold last-modified timestamp
TableSearcher tableSearcher;
Set multiLineFields; // string fields that should be shown as text areas
Set dontDuplicateFields;
int formFixer = 12; // stupid value to make submit button appear
boolean showBackRefs = false;
int maxRefsToShow = 3;
boolean showClassNameSelectors = false;
boolean allowNewFields = false;
int newFieldsToShow = 3;
boolean emptyStringsToNull = false; // convert all empty string values to nulls (also means dropping the field if it's dynamic)
int formLabelsWidth = 100; // just another bug fixer
final public SimpleCRUD_v2 setShowSearchBar(boolean showSearchBar){ return showSearchBar(showSearchBar); }
public SimpleCRUD_v2 showSearchBar(boolean showSearchBar) { this.showSearchBar = showSearchBar; return this; } final public boolean getShowSearchBar(){ return showSearchBar(); }
public boolean showSearchBar() { return showSearchBar; }
boolean showSearchBar = true;
final public SimpleCRUD_v2 setShowAddButton(boolean showAddButton){ return showAddButton(showAddButton); }
public SimpleCRUD_v2 showAddButton(boolean showAddButton) { this.showAddButton = showAddButton; return this; } final public boolean getShowAddButton(){ return showAddButton(); }
public boolean showAddButton() { return showAddButton; }
boolean showAddButton = true;
final public SimpleCRUD_v2 setShowEditButton(boolean showEditButton){ return showEditButton(showEditButton); }
public SimpleCRUD_v2 showEditButton(boolean showEditButton) { this.showEditButton = showEditButton; return this; } final public boolean getShowEditButton(){ return showEditButton(); }
public boolean showEditButton() { return showEditButton; }
boolean showEditButton = true;
final public SimpleCRUD_v2 setShowDeleteButton(boolean showDeleteButton){ return showDeleteButton(showDeleteButton); }
public SimpleCRUD_v2 showDeleteButton(boolean showDeleteButton) { this.showDeleteButton = showDeleteButton; return this; } final public boolean getShowDeleteButton(){ return showDeleteButton(); }
public boolean showDeleteButton() { return showDeleteButton; }
boolean showDeleteButton = true;
final public SimpleCRUD_v2 setShowDuplicateButton(boolean showDuplicateButton){ return showDuplicateButton(showDuplicateButton); }
public SimpleCRUD_v2 showDuplicateButton(boolean showDuplicateButton) { this.showDuplicateButton = showDuplicateButton; return this; } final public boolean getShowDuplicateButton(){ return showDuplicateButton(); }
public boolean showDuplicateButton() { return showDuplicateButton; }
boolean showDuplicateButton = true;
final public SimpleCRUD_v2 setIconButtons(boolean iconButtons){ return iconButtons(iconButtons); }
public SimpleCRUD_v2 iconButtons(boolean iconButtons) { this.iconButtons = iconButtons; return this; } final public boolean getIconButtons(){ return iconButtons(); }
public boolean iconButtons() { return iconButtons; }
boolean iconButtons = false;
final public SimpleCRUD_v2 setEditWindowScrollable(boolean editWindowScrollable){ return editWindowScrollable(editWindowScrollable); }
public SimpleCRUD_v2 editWindowScrollable(boolean editWindowScrollable) { this.editWindowScrollable = editWindowScrollable; return this; } final public boolean getEditWindowScrollable(){ return editWindowScrollable(); }
public boolean editWindowScrollable() { return editWindowScrollable; }
boolean editWindowScrollable = false;
final public SimpleCRUD_v2 setScrollableButtons(boolean scrollableButtons){ return scrollableButtons(scrollableButtons); }
public SimpleCRUD_v2 scrollableButtons(boolean scrollableButtons) { this.scrollableButtons = scrollableButtons; return this; } final public boolean getScrollableButtons(){ return scrollableButtons(); }
public boolean scrollableButtons() { return scrollableButtons; }
boolean scrollableButtons = false; // if you have a lot of them
// put a component in here to fill the space left of the buttons
SingleComponentPanel scpButtonFiller;
JComponent wrappedButtonBar;
// After user has submitted edit/create window
transient Set> onConceptSaved;
public SimpleCRUD_v2 onConceptSaved(IVF1 f) { onConceptSaved = createOrAddToSyncLinkedHashSet(onConceptSaved, f); return this; }
public SimpleCRUD_v2 removeConceptSavedListener(IVF1 f) { main.remove(onConceptSaved, f); return this; }
public void conceptSaved(A concept) { if (onConceptSaved != null) for (var listener : onConceptSaved) pcallF_typed(listener, concept); }
SimpleCRUD_v2(Class conceptClass) { super(conceptClass); }
SimpleCRUD_v2(Concepts concepts, Class conceptClass) { super(concepts, conceptClass); }
SimpleCRUD_v2 show(String frameTitle) {
make();
showFrame(frameTitle, panel);
return this;
}
SimpleCRUD_v2 show() {
return show(entityNamePlural());
}
SimpleCRUD_v2 showMaximized() { show(); maximizeFrame(panel); return this; }
JPanel makePanel() { return make(); }
JPanel make() {
db();
framesBot();
return make_dontStartBots();
}
transient IF1> itemToMap_inner;
Map itemToMap_inner(A a) { return itemToMap_inner != null ? itemToMap_inner.get(a) : itemToMap_inner_base(a); }
final Map itemToMap_inner_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : itemToMap_inner_base(a); }
Map itemToMap_inner_base(A a) {
return super.itemToMap_base(a);
}
Map itemToMap_base(A a) {
Map map = itemToMap_inner(a);
if (map == null) return null;
return putAll(map, moreSpecialFieldsForItem(a));
}
// shown on the right (usually)
transient IF1> moreSpecialFieldsForItem;
Map moreSpecialFieldsForItem(A a) { return moreSpecialFieldsForItem != null ? moreSpecialFieldsForItem.get(a) : moreSpecialFieldsForItem_base(a); }
final Map moreSpecialFieldsForItem_fallback(IF1> _f, A a) { return _f != null ? _f.get(a) : moreSpecialFieldsForItem_base(a); }
Map moreSpecialFieldsForItem_base(A a) {
Map map = litorderedmap();
if (showBackRefs) {
Collection refs = allBackRefs(a);
if (nempty(refs)) {
refs = sortedByConceptID(refs);
int more = l(refs)-maxRefsToShow;
map.put("Referenced by",
joinWithComma(takeFirst(maxRefsToShow, refs))
+ (more > 0 ? ", " + more + " more" : ""));
}
}
return map;
}
public JPanel make_dontStartBots() { return (JPanel) visualize(); }
public transient JComponent visualize_cache;
public JComponent visualize() { if (visualize_cache == null) visualize_cache = visualize_load(); return visualize_cache;}
public JComponent visualize_load() { return markVisualizer(this, visualize_impl()); }
JComponent visualize_impl() {
dropFields = asList(unshownFields);
makeTable();
{ swing(() -> {
JButton deleteButton = !showDeleteButton ? null
: tableDependButton(table, makeDeleteButton(new Runnable() { public void run() { try {
List l = selectedConcepts();
withDBLock(concepts, new Runnable() { public void run() { try { for (A c : l) c.delete() ;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "for (A c : l) c.delete()"; }});
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "List l = selectedConcepts();\r\n withDBLock(concepts, r { for (A c ..."; }}));
buttons = jRightAlignedLine(flattenToList(
!showAddButton ? null : makeAddButton(new Runnable() { public void run() { try { newConcept();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "newConcept();"; }}),
!showEditButton || !showDuplicateButton ? null : tableDependButton(table, makeDuplicateButton(new Runnable() { public void run() { try {
duplicateConcept(selectedConcept())
;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "duplicateConcept(selectedConcept())"; }})),
!showEditButton ? null : tableDependButton(table, makeEditButton(new Runnable() { public void run() { try {
editConcept(selectedConcept())
;
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "editConcept(selectedConcept())"; }})),
deleteButton));
wrappedButtonBar = wrapButtonBar(centerAndEastWithMargin(scpButtonFiller = singleComponentPanel(), buttons));
if (showSearchBar) {
tableSearcher = tableWithSearcher2(table, "withMargin" , true);
panel = centerAndSouthWithMargin(tableSearcher.panel, wrappedButtonBar);
} else
panel = centerAndSouthWithMargin(table, wrappedButtonBar);
var fEdit = new VF1() { public void get(Integer row) { try {
editConcept(getItem(row))
; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "editConcept(getItem(row))"; }};
tablePopupMenuItem(table, "Edit", fEdit);
onDoubleClick(table, fEdit);
tablePopupMenuFirst(table, (menu, row) -> {
Concept c = getItem(row);
if (c != null)
addMenuItem(menu, "Delete " + quote(shorten(str(c))), runnableThread(new Runnable() { public void run() { try {
deleteConcept(c);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "deleteConcept(c);"; }}));
});
}); } // end of swing
return panel;
}
transient IF1 wrapButtonBar;
JComponent wrapButtonBar(JComponent buttonBar) { return wrapButtonBar != null ? wrapButtonBar.get(buttonBar) : wrapButtonBar_base(buttonBar); }
final JComponent wrapButtonBar_fallback(IF1 _f, JComponent buttonBar) { return _f != null ? _f.get(buttonBar) : wrapButtonBar_base(buttonBar); }
JComponent wrapButtonBar_base(JComponent buttonBar) {
if (scrollableButtons)
return jBorderlessHigherHorizontalScrollPane(vstack(buttonBar));
return buttonBar;
}
transient Runnable newConcept;
void newConcept() { if (newConcept != null) newConcept.run(); else newConcept_base(); }
final void newConcept_fallback(Runnable _f) { if (_f != null) _f.run(); else newConcept_base(); }
void newConcept_base() {
duplicateConcept(null);
}
transient IF1 createDuplicate;
A createDuplicate(A c) { return createDuplicate != null ? createDuplicate.get(c) : createDuplicate_base(c); }
final A createDuplicate_fallback(IF1 _f, A c) { return _f != null ? _f.get(c) : createDuplicate_base(c); }
A createDuplicate_base(A c) {
A clone = (A) unlisted(_getClass(c));
ccopyFieldsExcept(c, clone, dontDuplicateFields);
return clone;
}
void duplicateConcept(A oldConcept) {
EditWindow ew = new EditWindow();
if (oldConcept == null)
ew.item = unlisted(conceptClass);
else
ew.item = createDuplicate(oldConcept);
csetAll(ew.item, filters);
makeComponents(ew);
// save action
F0 r = new F0() { public Boolean get() { try {
try {
selectAfterUpdate(ew.item);
concepts.register(ew.item);
saveData(ew);
} catch (Throwable e) { printStackTrace(e);
infoBox(e);
return false;
}
return true;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "try {\r\n selectAfterUpdate(ew.item);\r\n concepts.register(ew.item..."; }};
AutoCloseable __2 = tempSetMCOpt("formLayouter1_fixer2" , formFixer); try {
String title = "New " + entityName();
title += appendBracketed(javaClassDescForItem(ew.item));
renameSubmitButton("Create", showAForm(title,
toObjectArray(listPlus(ew.matrix, r))));
} finally { _close(__2); }}
void editConcept(A c) {
if (c == null) return;
EditWindow ew = new EditWindow();
ew.item = c;
makeComponents(ew);
F0 r = new F0() { public Boolean get() { try {
try {
// concept class was changed, replace object
if (ew.item != c) {
print("Replacing object: " + c + " => " + ew.item);
replaceConceptAndUpdateRefs(c, ew.item);
}
saveData(ew);
} catch (Throwable e) { printStackTrace(e);
infoBox(e);
return false;
}
return true;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "try {\r\n // concept class was changed, replace object\r\n if (ew.i..."; }};
AutoCloseable __3 = tempSetMCOpt("formLayouter1_fixer2" , formFixer); try {
renameSubmitButton("Save", showAForm("Edit " + entityName() + " #" + c.id,
toObjectArray(listPlus(ew.matrix, r))));
} finally { _close(__3); }}
JComponent fieldComponent(A c, String field) {
Class type = getFieldType(c.getClass(), field);
Type genericType = genericFieldType(conceptClass, field);
if (type == Concept.Ref.class)
type = getTypeArgumentAsClass(genericType);
Object value = cget(c, field);
if (type == null) type = _getClass(value);
print("Field type: " + field + " => " + type);
if (type == boolean.class)
return jCenteredCheckBox(isTrue(value));
else if (contains(multiLineFields, field) || containsNewLines(optCast(String.class, value)))
return makeTextArea((String) value);
else if (isSubtype(type, Concept.class))
return jcomboboxFromConcepts_str(concepts, type, (Concept) value);
else if (isUneditableFieldType(type))
return jlabel(structureOrText_crud(value));
else try {
return autoComboBox(structureOrText_crud(value), new TreeSet(map(__28 -> structureOrText_crud(__28), collect(list(concepts, conceptClass), field))));
} catch (Throwable e) {
printException(e);
return jTextField(structureOrText_crud(value));
}
}
void saveComponent(A c, String field, JComponent comp) {
comp = unwrap(comp);
Class type = fieldType(c, field);
Type genericType = genericFieldType(conceptClass, field);
if (type == Concept.Ref.class)
type = getTypeArgumentAsClass(genericType);
if (comp instanceof JTextComponent) {
String text = trimIf(!(comp instanceof JTextArea), getText((JTextComponent) comp));
Object value = postProcessValue(text);
Object converted = convertToField(value, c.getClass(), field);
cset(c, field, converted);
}
else if (comp instanceof JComboBox) {
String text = getTextTrim((JComboBox) comp);
if (isSubtype(type, Concept.class))
cset(c, field, getConcept(concepts, parseFirstLong(text)));
else {
Object value = postProcessValue(text);
cset(c, field, convertToField(value, c.getClass(), field));
}
} else if (comp instanceof JCheckBox)
cset(c, field, isChecked((JCheckBox) comp));
}
transient IF1> editableFieldsForItem;
Collection editableFieldsForItem(A c) { return editableFieldsForItem != null ? editableFieldsForItem.get(c) : editableFieldsForItem_base(c); }
final Collection editableFieldsForItem_fallback(IF1> _f, A c) { return _f != null ? _f.get(c) : editableFieldsForItem_base(c); }
Collection editableFieldsForItem_base(A c) {
if (excludeFieldsFromEditing != null && modifiedField != null) excludeFieldsFromEditing.add(modifiedField);
return listWithoutSet(
conceptFieldsInOrder(c),
joinSets(excludeFieldsFromEditing, unshownFields, keys(filters)));
}
void excludeFieldsFromEditing(String... fields) {
excludeFieldsFromEditing = setPlus(excludeFieldsFromEditing, fields);
}
Collection> possibleClasses() {
return (Collection) moveItemFirst(conceptClass, dropTypeParameter(sortClassesByNameIC(myNonAbstractClassesImplementing(conceptClass))));
}
JComboBox> classSelectorComponent(A c) {
return setComboBoxRenderer(jTypedComboBox(possibleClasses(), _getClass(c)),
customToStringListCellRenderer(__29 -> shortClassName(__29)));
}
class NewField {
JTextField tfName = jtextfield();
JTextField tfValue = jtextfield();
JComboBox cbRef = jcomboboxFromConcepts_str(concepts, conceptClass);
JComboBox cbType = jcombobox("String", "Reference");
SingleComponentPanel scpValue = singleComponentPanel();
JPanel panel() {
onChangeAndNow(cbType, new Runnable() { public void run() { try { updateSCP();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "updateSCP();"; }});
return jhgridWithSpacing(
withToolTip("Name for new field", withLabel("Name", tfName)),
withLabel("Value", westAndCenterWithMargin(cbType, scpValue)));
}
String typeStr() { return getText(cbType); }
void updateSCP() {
scpValue.setComponent(eqic(typeStr(), "Reference")
? cbRef
: withToolTip("Contents of new field", tfValue));
}
String field() { return gtt(tfName); }
Object value() {
return eqic(typeStr(), "Reference")
? getConcept(concepts, parseFirstLong(getText(cbRef)))
: gtt(tfValue);
}
}
class EditWindow {
A item;
Map componentsByField = litorderedmap();
List matrix = new ArrayList(); // label, component, label, component, ...
JComboBox> classSelector;
List newFields = new ArrayList();
}
// override the following two methods to customize edit window
void makeComponents(EditWindow ew) {
// class selector
if (showClassNameSelectors) {
addAll(ew.matrix, makeLabel("Java Class"), ew.classSelector = classSelectorComponent(ew.item));
onChange(ew.classSelector, new Runnable() { public void run() { try {
Class extends A> oldClass = _getClass(ew.item);
Class extends A> newClass = getSelectedItem_typed(ew.classSelector);
if (oldClass == newClass) return;
A oldItem = ew.item;
ew.item = unlisted(newClass);
ccopyFields(oldItem, ew.item);
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "Class extends A> oldClass = _getClass(ew.item);\r\n Class extends A>..."; }});
}
// regular fields
for (String field : editableFieldsForItem(ew.item)) {
JComponent c = fieldComponent(ew.item, field);
ew.componentsByField.put(field, c);
addAll(ew.matrix, makeLabel(field), c);
}
// new fields
if (allowNewFields && newFieldsToShow > 0) {
addAll(ew.matrix, " ", jlabel()); // spacing
for (int i = 0; i < newFieldsToShow; i++) {
NewField nf = new NewField();
ew.newFields.add(nf);
addAll(ew.matrix, makeLabel(""/*"New field"*/), nf.panel());
}
}
}
void saveData(EditWindow ew) {
// save regular fields
for (Map.Entry extends String, ? extends JComponent> __0 : _entrySet( ew.componentsByField))
{ String field = __0.getKey(); JComponent component = __0.getValue(); if (isIdentifier(field))
saveComponent(ew.item, field, component); }
// save new fields
for (NewField nf : ew.newFields) {
String field = nf.field();
Object value = nf.value();
if (nempty(field) && notNullOrEmptyString(value))
cset(ew.item, field, value);
}
if (modifiedField != null) cset(ew.item, modifiedField, now());
conceptSaved(ew.item);
}
Object postProcessValue(Object o) {
if (emptyStringsToNull && eq(o, "")) return null;
return o;
}
// labels on left hand side of form
JComponent makeLabel(String label) {
return jMinWidthAtLeast(formLabelsWidth, jlabel(label));
}
transient IF2 showAForm;
JComponent showAForm(String title, Object... parts) { return showAForm != null ? showAForm.get(title, parts) : showAForm_base(title, parts); }
final JComponent showAForm_fallback(IF2 _f, String title, Object... parts) { return _f != null ? _f.get(title, parts) : showAForm_base(title, parts); }
JComponent showAForm_base(String title, Object... parts) {
JForm form = new JForm(parts).disposeFrameOnSubmit();
var panel = form.visualize();
showFrame(title, editWindowScrollable ? jscroll_vertical(panel) : panel);
return panel;
}
boolean isUneditableFieldType(Class type) {
return isSubclassOfAny(type, Map.class, Collection.class, Pair.class);
}
void hideField(String field) { hideFields(field); }
void hideFields(String... fields) {
unshownFields = createOrAddToSet(unshownFields, fields);
}
transient IF0 entityName;
String entityName() { return entityName != null ? entityName.get() : entityName_base(); }
final String entityName_fallback(IF0 _f) { return _f != null ? _f.get() : entityName_base(); }
String entityName_base() { return shortClassName(conceptClass); }
transient IF0 entityNamePlural;
String entityNamePlural() { return entityNamePlural != null ? entityNamePlural.get() : entityNamePlural_base(); }
final String entityNamePlural_fallback(IF0 _f) { return _f != null ? _f.get() : entityNamePlural_base(); }
String entityNamePlural_base() { return plural(entityName()); }
transient IF0 entityNameLower;
String entityNameLower() { return entityNameLower != null ? entityNameLower.get() : entityNameLower_base(); }
final String entityNameLower_fallback(IF0 _f) { return _f != null ? _f.get() : entityNameLower_base(); }
String entityNameLower_base() { return firstToLower(entityName()); }
transient IF0 entityNamePluralLower;
String entityNamePluralLower() { return entityNamePluralLower != null ? entityNamePluralLower.get() : entityNamePluralLower_base(); }
final String entityNamePluralLower_fallback(IF0 _f) { return _f != null ? _f.get() : entityNamePluralLower_base(); }
String entityNamePluralLower_base() { return firstToLower(entityNamePlural()); }
JPanel buttons() { visualize(); return buttons; }
void addButtonInFront(String text, Runnable r) {
addButtonInFront(jbutton(text, r));
}
void addButton(String text, Runnable r) {
addButton(jbutton(text, r));
}
void addButton(JComponent c) {
buttons().add(c);
}
void addButtonInFront(JComponent c) {
addComponentInFront(buttons(), c);
}
JButton makeAddButton(Runnable r) { return makeButton(
"Add...", "Create a new " + entityNameLower(), "#1103069", r); }
JButton makeDeleteButton(Runnable r) { return makeButton(
"Delete", "Delete selected " + entityNamePluralLower(), "#1103067", r); }
JButton makeEditButton(Runnable r) { return makeButton(
"Edit...", "Edit selected " + entityNameLower(), "#1103068", r); }
JButton makeDuplicateButton(Runnable r) { return makeButton(
"Duplicate...", "Duplicate selected " + entityNameLower(), "#1103070", r); }
JButton makeButton(String text, String iconID, Runnable r) { return makeButton(text, null, iconID, r); }
JButton makeButton(String text, String toolTip, String iconID, Runnable r) {
if (iconButtons)
return toolTip(or2(toolTip, text), jimageButtonScaledToWidth(16, iconID, text, r));
else
return toolTip(toolTip, jbutton(text, r));
}
void multiLineField(String field) {
multiLineFields = addOrCreate(multiLineFields, field);
}
transient IF1 makeTextArea;
JComponent makeTextArea(String text) { return makeTextArea != null ? makeTextArea.get(text) : makeTextArea_base(text); }
final JComponent makeTextArea_fallback(IF1 _f, String text) { return _f != null ? _f.get(text) : makeTextArea_base(text); }
JComponent makeTextArea_base(String text) {
return typeWriterTextArea(text);
}
void setButtonFiller(JComponent c) {
scpButtonFiller.set(c);
}
TableSearcher tableSearcher() {
visualize();
return tableSearcher;
}
}
static Set createOrAddToSyncLinkedHashSet(Set set, A a) {
if (set == null) set = syncLinkedHashSet();
set.add(a);
return set;
}
static void remove(List l, int i) {
if (l != null && i >= 0 && i < l(l))
l.remove(i);
}
static void remove(Collection l, A a) {
if (l != null) l.remove(a);
}
static B remove(Map map, Object a) {
return map == null ? null : map.remove(a);
}
static void remove(BitSet bs, int i) {
bs.clear(i);
}
static A pcallF_typed(F0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static B pcallF_typed(F1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static void pcallF_typed(VF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { pcallFail(__e); }
}
static void pcallF_typed(IVF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { pcallFail(__e); }
}
static void pcallF_typed(IVF2 f, A a, B b) {
try {
{ if (f != null) f.get(a, b); }
} catch (Throwable __e) { pcallFail(__e); }
}
static Object pcallF_typed(Runnable r) {
try { { if (r != null) r.run(); } } catch (Throwable __e) { pcallFail(__e); } return null;
}
static A pcallF_typed(IF0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static B pcallF_typed(IF1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static JFrame showFrame() {
return makeFrame();
}
static JFrame showFrame(Object content) {
return makeFrame(content);
}
static JFrame showFrame(String title) {
return makeFrame(title);
}
static JFrame showFrame(String title, Object content) {
return makeFrame(title, content);
}
static JFrame showFrame(final JFrame f) {
if (f != null) { swing(() -> {
if (frameTooSmall(f)) frameStandardSize(f);
if (!f.isVisible()) f.setVisible(true); // XXX
if (f.getState() == Frame.ICONIFIED) f.setState(Frame.NORMAL);
}); }
return f;
}
// make or update frame
static JFrame showFrame(String title, Object content, JFrame frame) {
if (frame == null)
return showFrame(title, content);
else {
frame.setTitle(title);
setFrameContents(frame, content);
return frame;
}
}
static A maximizeFrame(A c) {
JFrame f = swing(new F0() { public JFrame get() { try {
JFrame f = getFrame(c);
if (f != null)
f.setExtendedState(JFrame.MAXIMIZED_BOTH);
return f;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "JFrame f = getFrame(c);\r\n if (f != null)\r\n f.setExtendedState(JFrame...."; }});
// wait until frame is actually maximized so
// we can add components based on correct size
if (f != null && !isAWTThread()) {
Dimension d = maximumWindowBounds().getSize();
long start = sysNow();
while (licensed()) { try {
if (f.getWidth() >= d.getWidth()-100 && f.getHeight() >= d.getHeight()-100) break;
if (sysNow() >= start+100) { warn("maximizeFrame timeout"); break; }
} catch (Throwable __e) { pcallFail(__e); } sleep(1); }
}
return c;
}
static void db() {
conceptsAndBot();
}
// use -10000 for 10 seconds plus slowdown logic
static void db(Integer autoSaveInterval) {
conceptsAndBot(autoSaveInterval);
}
static volatile boolean framesBot_has = false;
static Android3 framesBot() {
if (framesBot_has) return null;
framesBot_has = true;
Android3 android = new Android3();
android.greeting = programIDPlusHome() + " Frames.";
android.console = false;
android.responder = new Responder() {
public String answer(String s, List history) {
if (match("activate frames", s)) {
swingLater(new Runnable() { public void run() { try { // prevent blocking when called from same program's AWT thread
activateMyFrames();
} catch (Exception __e) { throw rethrow(__e); } } public String toString() { return "// prevent blocking when called from same program's AWT thread\r\n act..."; }});
return "OK, activating " + programName();
}
return null;
}
};
return makeBot(android);
}
static Map putAll(Map a, Map extends A,? extends B> b) {
if (a != null && b != null) a.putAll(b);
return a;
}
static MultiMap putAll(MultiMap a, Map extends A,? extends B> b) {
if (a != null) a.putAll((Map) b);
return a;
}
static Map putAll(Map a, Object... b) {
if (a != null)
litmap_impl(a, b);
return a;
}
static LinkedHashMap litorderedmap(Object... x) {
LinkedHashMap map = new LinkedHashMap();
litmap_impl(map, x);
return map;
}
static List allBackRefs(Concept c) {
IdentityHashMap l = new IdentityHashMap();
if (c != null && c.backRefs != null) for (Concept.Ref r : cloneList(c.backRefs))
l.put(r.concept(), true);
return keysList(l);
}
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(IMultiMap mm) { return mm != null && mm.size() != 0; }
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(IntBuffer b) { return b != null && !b.isEmpty(); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static boolean nempty(MultiSet ms) { return ms != null && !ms.isEmpty(); }
static List sortedByConceptID(Collection c) {
return sortedByCalculatedField(__30 -> conceptID(__30), c);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(MultiSet ms) { return ms == null ? 0 : ms.size(); }
static int l(IMultiMap mm) { return mm == null ? 0 : mm.size(); }
static int l(IntBuffer b) { return b == null ? 0 : b.size(); }
static int l(IntSize o) { return o == null ? 0 : o.size(); }
static String joinWithComma(Collection c) {
return join(", ", c);
}
static String joinWithComma(Object... c) {
return join(", ", c);
}
static String joinWithComma(String... c) {
return join(", ", c);
}
static String joinWithComma(Pair p) {
return p == null ? "" : joinWithComma(str(p.a), str(p.b));
}
static List takeFirst(List l, int n) {
return l(l) <= n ? l : newSubListOrSame(l, 0, n);
}
static List takeFirst(int n, List l) {
return takeFirst(l, n);
}
static String takeFirst(int n, String s) { return substring(s, 0, n); }
static String takeFirst(String s, int n) { return substring(s, 0, n); }
static CharSequence takeFirst(int n, CharSequence s) { return subCharSequence(s, 0, n); }
static List takeFirst(int n, Iterator it) {
if (it == null) return null;
List l = new ArrayList();
for (int _repeat_0 = 0; _repeat_0 < n; _repeat_0++) { if (it.hasNext()) l.add(it.next()); else break; }
return l;
}
static List takeFirst(int n, Iterable i) {
if (i == null) return null;
return i == null ? null : takeFirst(n, i.iterator());
}
static List takeFirst(int n, IterableIterator i) {
return takeFirst(n, (Iterator) i);
}
static int[] takeFirst(int n, int[] a) { return takeFirstOfIntArray(n, a); }
static short[] takeFirst(int n, short[] a) { return takeFirstOfShortArray(n, a); }
static byte[] takeFirst(int n, byte[] a) { return takeFirstOfByteArray(n, a); }
static byte[] takeFirst(byte[] a, int n) { return takeFirstOfByteArray(n, a); }
static double[] takeFirst(int n, double[] a) { return takeFirstOfDoubleArray(n, a); }
static double[] takeFirst(double[] a, int n) { return takeFirstOfDoubleArray(n, a); }
static A markVisualizer(Object visualizer, A a) {
return setMetaSrc(a, visualizer);
}
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList() : new ArrayList(Arrays.asList(a));
}
static ArrayList asList(char[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (var i : a) l.add(i);
return l;
}
static ArrayList asList(byte[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (var i : a) l.add(i);
return l;
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Producer p) {
ArrayList l = new ArrayList();
A a;
if (p != null) while ((a = p.next()) != null)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static ArrayList asList(ReverseChain c) {
return c == null ? emptyList() : c.toList();
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
static Object swing(Object f) {
return swingAndWait(f);
}
static void swing(Runnable f) {
swingAndWait(f);
}
static A swing(F0 f) {
return (A) swingAndWait(f);
}
static A swing(IF0 f) {
return (A) swingAndWait(f);
}
static JButton tableDependButton(JTable tbl, JButton b) {
tableDependButtons(tbl, ll(b));
return b;
}
static JButton tableDependButton(JTable tbl, String text, Object action) {
return tableDependButton(tbl, jbutton(text, action));
}
static Object withDBLock(Object r) {
Lock __0 = db_mainConcepts().lock; lock(__0); try {
return callF(r);
} finally { unlock(__0); } }
static A withDBLock(F0 r) {
return (A) withDBLock((Object) r);
}
static Object withDBLock(Concepts concepts, Object r) {
Lock __1 = concepts.lock; lock(__1); try {
return callF(r);
} finally { unlock(__1); } }
static A withDBLock(Concepts concepts, F0 r) {
return (A) withDBLock(concepts, (Object) r);
}
static A withDBLock(Concept concept, IF0 r) {
return (A) withDBLock(concept._concepts, r);
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static JPanel jRightAlignedLine(Component... components) {
return jrightAlignedLine(components);
}
static JPanel jRightAlignedLine(List extends Component> components) {
return jrightAlignedLine(components);
}
static List flattenToList(Object... l) {
Flattener f = new Flattener();
f.add(l);
return f.toList();
}
static A selectedConcept(JTable table, Class cc) {
return (A) getConcept(toLong(selectedTableCell(table, 0)));
}
static JPanel centerAndEastWithMargin(Swingable c, Swingable e) { return centerAndEastWithMargin(c, toComponent(e)); }
static JPanel centerAndEastWithMargin(Swingable c, Component e) { return centerAndEastWithMargin(toComponent(c), e); }
static JPanel centerAndEastWithMargin(Component c, Swingable e) { return centerAndEastWithMargin(c, toComponent(e)); }
static JPanel centerAndEastWithMargin(Component c, Component e) {
return centerAndEastWithMarginInbetween(c, e);
}
static SingleComponentPanel singleComponentPanel() {
return singleComponentPanel(null);
}
static SingleComponentPanel singleComponentPanel(final Component c) {
return swing(new F0() { public SingleComponentPanel get() { try {
return new SingleComponentPanel(c);
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "return new SingleComponentPanel(c);"; }});
}
static class TableSearcher {
JTable table;
JTextField tfInput;
JComponent searchPanel, panel;
F2 rowTester;
List rowIndices;
SingleComponentPanel scpRightOfSearchPanel = scp();
List lastFiltered, lastOriginal;
String input() { return gtt(tfInput); }
void clearSearchField() { setText(tfInput, ""); }
}
static TableSearcher tableWithSearcher2(JTable t, Object... __) {
TableSearcher s = new TableSearcher();
boolean precise = true;
s.table = t;
s.tfInput = jtextfield();
s.rowTester = new F2() { public Boolean get(String pat, Map row) { try { return anyValueContainsIgnoreCase(row, pat); } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "anyValueContainsIgnoreCase(row, pat)"; }};
onUpdate(s.tfInput, new Runnable() {
public void run() {
String pat = s.input();
List