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

298
LINES

< > BotCompany Repo | #1030725 // JConceptsTable - new version of showConceptsTable

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

Libraryless. Click here for Pure Java version (30096L/193K).

1  
sclass JConceptsTable<A extends Concept> is Swingable {
2  
  Class<? extends A> conceptClass;
3  
  Concepts concepts;
4  
  JTable table;
5  
  
6  
  // options
7  
  MapSO filters; // fields to filter by/add to new objects
8  
  S hID = "ID"; // Column header for concept ID
9  
  settable LS dropFields;
10  
  settable bool noSubclasses;
11  
  IF1<L> postProcess;
12  
  Runnable afterUpdate;
13  
  bool latestFirst;
14  
  IF1<Cl<A>> sorter = lambda1 defaultSort;
15  
  int idWidth = 50;
16  
  settable int updateInterval = 100;
17  
  int firstUpdateInterval = 100;
18  
  bool humanizeFieldNames = true;
19  
  Float tableFontSize;
20  
  Int tableRowHeight;
21  
  settable bool addCountToEnclosingTab;
22  
  settable bool useNewChangeHandler;
23  
  settable IVF1<A> defaultAction;
24  
  bool pauseUpdates;
25  
  int count;
26  
  
27  
  event selectionChanged;
28  
  event singleSelectionChanged;
29  
30  
  // internal
31  
  AWTOnConceptChanges changeHandler;
32  
  AWTOnConceptChangesByClass newChangeHandler;
33  
  bool updatingList;
34  
  settable A selectAfterUpdate;
35  
  A lastSelected;
36  
  
37  
  *() {}
38  
  *(Class<? extends A> *conceptClass) {}
39  
  *(Concepts *concepts, Class<? extends A> *conceptClass) {}
40  
  
41  
  swappable MapSO itemToMap(A a) {
42  
    MapSO map = specialFieldsForItem(a);
43  
    try {
44  
      putAll(map, mapValues renderValue(itemToMap_inner2(a)));
45  
    } catch print e {
46  
      map.put("Error", str(e));
47  
    }
48  
    ret map;
49  
  }
50  
  
51  
  swappable O renderValue(O o) {
52  
    ret renderForTable_noStruct(o);
53  
  }
54  
  
55  
  swappable MapSO itemToMap_inner2(A a) {
56  
    ret allConceptFieldsAsMapExcept(a, dropFields);
57  
  }
58  
  
59  
  // shown on the left (usually)
60  
  swappable MapSO specialFieldsForItem(A a) {
61  
    MapSO map = litorderedmap(hID, str(a.id));
62  
    mapPut(map, "Java Class", javaClassDescForItem(a));
63  
    ret map;
64  
  }
65  
  
66  
  S javaClassDescForItem(A a) {
67  
    S className = dynShortClassName(a);
68  
    if (neq(className, shortClassName(conceptClass))) {
69  
      S text = className;
70  
      S realClass = shortClassName(a);
71  
      if (neq(className, realClass))
72  
        text += " as " + realClass;
73  
      ret text;
74  
    }
75  
    null;
76  
  }
77  
  
78  
  S defaultTitle() {
79  
    ret plural(shortClassName(conceptClass));
80  
  }
81  
  
82  
  void showAsFrame(S title default defaultTitle()) {
83  
    makeTable();
84  
    showFrame(title, table);
85  
  }
86  
  
87  
  void makeTable {
88  
    if (table != null) ret;
89  
    if (concepts == null) concepts = db_mainConcepts();
90  
91  
    table = sexyTable();
92  
    if (tableFontSize != null) {
93  
      setTableFontSizes(tableFontSize, table);
94  
      if (tableRowHeight == null)
95  
        tableRowHeight = iround(tableFontSize*1.5);
96  
    }
97  
    if (tableRowHeight != null) setRowHeight(table, tableRowHeight);
98  
    
99  
    if (useNewChangeHandler) {
100  
      newChangeHandler = new AWTOnConceptChangesByClass(concepts, conceptClass, table, l0 _update)
101  
       .delay(updateInterval)
102  
       .firstDelay(firstUpdateInterval);
103  
      newChangeHandler.install();
104  
    } else {
105  
      changeHandler = new AWTOnConceptChanges(concepts, table, l0 _update)
106  
        .delay(updateInterval)
107  
        .firstDelay(firstUpdateInterval);
108  
      changeHandler.install();
109  
    }
110  
    
111  
    onTableSelectionChanged(table, -> {
112  
      if (updatingList) ret;
113  
      selectionChanged();
114  
    });
115  
    
116  
    onSelectionChanged(-> {
117  
      var a = selected();
118  
      if (a != lastSelected) {
119  
        lastSelected = a;
120  
        singleSelectionChanged();
121  
      }
122  
    });
123  
    
124  
    onDoubleClickOrEnter(table, -> {
125  
      A a = selected();
126  
      if (a != null && defaultAction != null)
127  
        pcallF(defaultAction, a);
128  
    });
129  
  }
130  
  
131  
  // e.g. to update enclosing tab when hidden
132  
  void update {
133  
    swing { _update(); }
134  
  }
135  
  
136  
  // run in Swing thread
137  
  void _update {
138  
    if (table == null || pauseUpdates) ret;
139  
    set updatingList;
140  
    bool allRestored;
141  
    A selectAfterUpdate = selectAfterUpdate();
142  
    
143  
    try {
144  
      new L<Map> data;
145  
      
146  
      Set<Long> selection;
147  
      if (selectAfterUpdate != null) {
148  
        selection = litset(selectAfterUpdate._conceptID());
149  
        selectAfterUpdate(null);
150  
      } else
151  
        selection = toSet(selectedConceptIDs());
152  
        
153  
      Cl<? extends A> l = conceptsWhere(concepts, conceptClass, mapToParams(filters));
154  
      if (noSubclasses) l = filter(l, x -> x.getClass() == conceptClass);
155  
      l = postProcess(sorter, l);
156  
      for (A c : l)
157  
        addIfNotNull(data, itemToMap(c));
158  
      if (latestFirst) reverseInPlace(data);
159  
      data = (L) postProcess(postProcess, data);
160  
      count = l(data);
161  
      dataToTable_uneditable(data, table);
162  
      if (humanizeFieldNames)
163  
        humanizeTableColumns();
164  
      tableColumnMaxWidth(table, 0, idWidth);
165  
    
166  
      allRestored = restoreSelection(selection);
167  
168  
      if (addCountToEnclosingTab)
169  
        updateEnclosingTabTitle();
170  
    } finally {
171  
      updatingList = false;
172  
    }
173  
    
174  
    pcallF(afterUpdate);
175  
    
176  
    if (!allRestored || selectAfterUpdate != null)
177  
      selectionChanged();
178  
  }
179  
  
180  
  void updateEnclosingTabTitle {
181  
    updateEnclosingTabTitleWithCount(table, count);
182  
  }
183  
  
184  
  void humanizeTableColumns {
185  
    int n = tableColumnCount(table);
186  
    for i to n:
187  
      setColumnName(table, i, humanizeFormLabel(getColumnName(table, i)));
188  
  };
189  
190  
  visual table();
191  
192  
  JTable table() {
193  
    makeTable();
194  
    ret table;
195  
  }
196  
  
197  
  A selectedConcept() {
198  
    ret (A) concepts.getConcept(toLong(selectedTableCell(table, 0)));
199  
  }
200  
  
201  
  A selected() { ret selectedConcept(); }
202  
  
203  
  long getItemID(int row) {
204  
    ret toLong(getTableCell(table, row, 0));
205  
  }
206  
  
207  
  L<A> getList() swing {
208  
    ret countIteratorAsList(size(), row -> getItem(row));
209  
  }
210  
  
211  
  A getItem(int row) {
212  
    ret (A) concepts.getConcept(getItemID(row));
213  
  }
214  
  
215  
  int size() { ret tableRowCount(table); }
216  
  
217  
  int indexOfConcept(final A c) {
218  
    if (c == null) ret -1;
219  
    ret swing(func -> int {
220  
      int n = size();
221  
      for row to n:
222  
        if (toLong(getTableCell(table, row, 0)) == c.id)
223  
          ret row;
224  
      ret -1;
225  
    });
226  
  }
227  
  
228  
  L<A> selectedConcepts() {
229  
    ret swing(-> {
230  
      int[] rows = table.getSelectedRows();
231  
      new L<A> l;
232  
      for (int row : rows)
233  
        l.add(getItem(row));
234  
      ret l;
235  
    });
236  
  }
237  
  
238  
  L<Long> selectedConceptIDs() {
239  
    ret swing(-> {
240  
      int[] rows = table.getSelectedRows();
241  
      L<Long> l = emptyList(l(rows));
242  
      for (int row : rows)
243  
        l.add(getItemID(row));
244  
      ret l;
245  
    });
246  
  }
247  
  
248  
  // returns true if all selected items still exist
249  
  bool restoreSelection(Set<Long> selection) {
250  
    ret swing(-> {
251  
      int n = size();
252  
      new IntBuffer toSelect;
253  
      for row to n:
254  
        if (selection.contains(getItemID(row)))
255  
          toSelect.add(row);
256  
      selectTableRows(table, toSelect.toIntArray());
257  
      ret toSelect.size() == selection.size();
258  
    });
259  
  }
260  
  
261  
  void setSelected(A a) {
262  
    selectRow(table(), indexOfConcept(a));
263  
  }
264  
  
265  
  Cl<A> defaultSort(Cl<A> l) {
266  
    ret sortByConceptID(l);
267  
  }
268  
  
269  
  selfType addFilter(S field, O value) {
270  
    filters = orderedMapPutOrCreate(filters, field, value);
271  
    this;
272  
  }
273  
  
274  
  void onSelectionChangedAndWhenShowing(Runnable r) {
275  
    bindToComponent(table(), r);
276  
    onSelectionChanged(r);
277  
  }
278  
  
279  
  void onSelectionChangedAndNow(Runnable r) {
280  
    if (r == null) ret;
281  
    onSelectionChanged(r);
282  
    r.run();
283  
  }
284  
  
285  
  selfType updateInterval(double seconds) {
286  
    ret updateInterval(toMS_int(seconds));
287  
  }
288  
  
289  
  selfType pauseUpdates(bool b) {
290  
    swing {
291  
      if (pauseUpdates != b) {
292  
        if (!(pauseUpdates = b))
293  
          _update();
294  
      }
295  
    }
296  
    this;
297  
  }
298  
}

Author comment

Began life as a copy of #1006009

download  show line numbers  debug dex  old transpilations   

Travelled to 5 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030725
Snippet name: JConceptsTable - new version of showConceptsTable
Eternal ID of this version: #1030725/76
Text MD5: 0a61293494dec29dee23d130b6d6b4c8
Transpilation MD5: e4b404ad5e5c1dd7f30581e04988d005
Author: stefan
Category: javax / gui / concepts
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2023-01-17 18:40:16
Source code size: 7632 bytes / 298 lines
Pitched / IR pitched: No / No
Views / Downloads: 467 / 1075
Version history: 75 change(s)
Referenced in: [show references]