Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

179
LINES

< > BotCompany Repo | #1016978 - DynObjectTable

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (18564L/137K).

1  
abstract sclass DynObjectTable<A> extends DynModule {
2  
  new L<A> data;
3  
  
4  
  transient JTable table;
5  
  transient F1<A, Map> itemToMap;
6  
  transient VF1<A> defaultAction;
7  
  transient bool debug, fieldsInOrder = true, withSearcher;
8  
  transient TableSearcher searcher;
9  
  transient L onListChanged;
10  
  transient Set<S> hideFields;
11  
  transient bool useStruct = false; // possible breaking change for older modules
12  
  
13  
  start {
14  
    itemToMap = func(A a) -> Map {
15  
      if (a instanceof S) ret litorderedmap("" := (S) a);
16  
      Map map = humanizeKeys(fieldsInOrder ? objectToMap_inOrder_withoutFields(a, hideFields) : objectToMap(a));
17  
      if (!useStruct) map = mapValues strOrEmpty(map);
18  
      ret map;
19  
    };
20  
    onChange(r updateTable);
21  
  }
22  
  
23  
  void onListChanged(Runnable r) {
24  
    if (r == null) ret;
25  
    onListChanged = addDyn_sync(onListChanged, r);
26  
  }
27  
  
28  
  void onListChangedAndNow(Runnable r) {
29  
    if (r == null) ret;
30  
    onListChanged(r);
31  
    r.run();
32  
  }
33  
  
34  
  void addCountToName {
35  
    onListChangedAndNow(r addCountToNameNow);
36  
  }
37  
  
38  
  void addCountToNameNow() enter {
39  
    setModuleName(programTitle() + " (" + count() + ")");
40  
  }
41  
  
42  
  visualize {
43  
    L<Map> l = map(itemToMap, data);
44  
    table = dataToTable_uneditable(sexyTable(), l);
45  
    onDoubleClickOrEnter(table, voidfunc(int row) {
46  
      temp enter();
47  
      A a = _get(data, row);
48  
      if (a != null) onDoubleClick(a);
49  
    });
50  
    if (withSearcher)
51  
      ret (searcher = tableWithSearcher2(table)).panel;
52  
    ret table;
53  
  }
54  
  
55  
  void unvisualize() { super.unvisualize(); searcher = null; }
56  
  
57  
  void onDoubleClick(A line) { callF(defaultAction, line); }
58  
  
59  
  void updateTable() enter {
60  
    if (table != null) swing {
61  
      Point scrollPosition = enclosingViewPosition(table);
62  
      if (debug) print("Scroll position: " + scrollPosition);
63  
      dataToTable_uneditable(table, map(itemToMap, data));
64  
      setEnclosingViewPosition(table, scrollPosition);
65  
      if (searcher != null) searcher.rowIndices = null;
66  
      if (debug) print("dataToTable done, alerting " + n2(onListChanged, "listener"));
67  
    }
68  
    pcallFAll(onListChanged);
69  
  }
70  
  
71  
  /*TODO void itemChanged(int row, A entry) {
72  
    if (getRow(row) != entry) {
73  
      fireDataChanged();
74  
      warn("Item index mismatch, recreating table");
75  
    }
76  
    rows.add(dataToTable_makeRow(x, cols));
77  
  }*/
78  
  
79  
  void dontPersist() { _persistenceInfo = mapPlus(_persistenceInfo, data := false); }
80  
  
81  
  void clear() { syncClear(data); fireDataChanged(); }
82  
  void add(A a) { syncAdd(data, a); fireDataChanged(); }
83  
  A addAndReturn(A a) { add(a); ret a; }
84  
  void add(int idx, A a) { syncAdd(data, idx, a); fireDataChanged(); }
85  
  void addAll(Collection<A> l) { if (empty(l)) ret; syncAddAll(data, l); fireDataChanged(); }
86  
  void addAndScrollDown(A a) { add(a); scrollDown(); }
87  
  void remove(A a) { syncRemove(data, a); fireDataChanged(); }
88  
  void removeAll(L<A> a) { syncRemoveAll(data, a); fireDataChanged(); }
89  
  void setList(Iterable<A> data) { setData(data); }
90  
  void removeSelected() { removeAll(allSelected()); }
91  
  
92  
  // rare legacy binary compatibility workaround
93  
  void setData(Collection<A> data) { setData((Iterable) data); }
94  
  
95  
  void setData(Iterable<A> data) {
96  
    setData(data, false);
97  
  }
98  
  
99  
  void setData(Iterable<A> data, bool force) {
100  
    // ATTN: new logic. test if it works in all cases
101  
    swing {
102  
      //int selection = selectedIndex();
103  
      int[] selection = selectedTableRows_array(table);
104  
      L<A> cloned = cloneList(data);
105  
      if (setField(data := cloned) || force) {
106  
        updateTable();
107  
        dm_vmBus_send listChanged(module(), cloned);
108  
      }
109  
      if (force) change();
110  
      //selectRow(table, selection);
111  
      selectTableRows(table, selection);
112  
    }
113  
  }
114  
  int count() { ret syncL(data); }
115  
  
116  
  void setData_force(Collection<A> data) {
117  
    setData(data, true);
118  
  }
119  
  
120  
  // tries to keep selection
121  
  void fireDataChanged() {
122  
    setData_force(data);
123  
  }
124  
  
125  
  int rowFromSearcher(int i) {
126  
    ret searcher == null || searcher.rowIndices == null ? i : or(get(searcher.rowIndices, i), -1);
127  
  }
128  
  
129  
  A selected() { ret syncGet(data, rowFromSearcher(selectedTableRowInModel(table))); }
130  
  L<A> allSelected() { ret syncListGetMulti(data, selectedIndices()); }
131  
  int selectedIndex() { ret selectedTableRow(table); }
132  
  L<Int> selectedIndices() { ret map(i -> rowFromSearcher(i), selectedTableRowsInModel(table)); }
133  
  bool selectItem(A a) { int i = indexOf(data, a); selectRow(table, i); ret i >= 0; } // true if item exists
134  
  void doubleClickItem(A a) { if (selectItem(a)) onDoubleClick(a); }
135  
  
136  
  // r : Runnable or VF1<A>
137  
  // run only in visualize()!
138  
  void popupMenuItem(S text, O r) {
139  
    tablePopupMenuItemsThreaded(table, text, _convertRunnable(r));
140  
  }
141  
  
142  
  void popupMenuItem_top(S text, O r) {
143  
    tablePopupMenuItemsThreaded_top(table, text, _convertRunnable(r));
144  
  }
145  
  
146  
  // row index => element
147  
  O _convertRunnable(fO r) {
148  
    if (r == null || r instanceof Runnable) ret r;
149  
    ret voidfunc(int idx) { callF(r, syncGet(data, idx)) };
150  
  }
151  
  
152  
  JTable table() { ret table; }
153  
  
154  
  void hideFields(S... fields) {
155  
    if (hideFields == null) hideFields = new Set;
156  
    _addAll(hideFields, fields);
157  
  }
158  
  
159  
  A getRow(int row) { ret get(data, row); }
160  
  
161  
  void scrollDown { scrollTableDownNow(table); }
162  
  
163  
  // API
164  
  
165  
  L<A> getData() { ret data; } // data is usually immutable
166  
  L<A> data() { ret getData(); }
167  
  L<A> list() { ret getData(); }
168  
  L<A> getList() { ret getData(); }
169  
  
170  
  L<A> clonedList() { ret cloneList(data); }
171  
  
172  
  // log list (and whole module) contents somewhere
173  
  File quickBackup() {
174  
    File f = programFile("backup-" + ymd_minus_hms_minus_millis() + ".gz");
175  
    saveGZStructToFile(f, module());
176  
    printFileInfo(f);
177  
    ret f;
178  
  }
179  
}

Author comment

Began life as a copy of #1016065

download  show line numbers  debug dex   

Travelled to 12 computer(s): aoiabmzegqzx, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, tslmcundralx, tvejysmllsmz, xrpafgyirdlv

No comments. add comment

Snippet ID: #1016978
Snippet name: DynObjectTable
Eternal ID of this version: #1016978/103
Text MD5: d8131ca27ae01e29848f4e709418605d
Transpilation MD5: c27c69b550539575ccd06bd16aaa64ea
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2020-02-21 13:32:58
Source code size: 5878 bytes / 179 lines
Pitched / IR pitched: No / No
Views / Downloads: 524 / 1775
Version history: 102 change(s)
Referenced in: [show references]

Formerly at http://tinybrain.de/1016978 & http://1016978.tinybrain.de