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

123
LINES

< > BotCompany Repo | #1034021 // JObjectTable - like JConceptsTable but for any kind of object

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

Transpiled version (17745L) is out of date.

sclass JObjectTable<A> is Swingable {
  new L<A> data;
  
  transient IF1<A, Map> itemToMap;
  transient Set<S> hideFields;
  transient bool debug, fieldsInOrder = true, withSearcher;
  settable IVF1<A> defaultAction;
  
  transient gettable JTable table;
  transient TableSearcher searcher;
  transient bool useStruct = false; // possible breaking change for older modules
  
  event listChanged;
  
  *() {
    itemToMap = a -> {
      if (a instanceof S) ret litorderedmap("" := (S) a);
      Map map = humanizeKeys(fieldsInOrder ? objectToMap_inOrder_withoutFields(a, hideFields) : objectToMap(a));
      if (!useStruct) map = mapValues strOrEmpty(map);
      ret map;
    };
  }
  
  void onListChangedAndNow(Runnable r) {
    if (r == null) ret;
    onListChanged(r);
    r.run();
  }
  
  cachedVisualize {
    L<Map> l = map(itemToMap, data);
    table = dataToTable_uneditable(sexyTable(), l);
    onDoubleClickOrEnter(table, voidfunc(int row) {
      A a = _get(data, row);
      if (a != null) defaultAction?.get(a);
    });
    if (withSearcher)
      ret (searcher = tableWithSearcher2(table)).panel;
    ret jscroll(table);
  }
  
  void updateTable() {
    if (table != null) swing {
      Point scrollPosition = enclosingViewPosition(table);
      if (debug) print("Scroll position: " + scrollPosition);
      dataToTable_uneditable(table, map(itemToMap, data));
      setEnclosingViewPosition(table, scrollPosition);
      if (searcher != null) searcher.rowIndices = null;
      if (debug) print("dataToTable done, alerting " + n2(onListChanged, "listener"));
    }
    listChanged();
  }
  
  void clear() { syncClear(data); fireDataChanged(); }
  void add(A a) { syncAdd(data, a); fireDataChanged(); }
  A addAndReturn(A a) { add(a); ret a; }
  void add(int idx, A a) { syncAdd(data, idx, a); fireDataChanged(); }
  void addAll(Collection<A> l) { if (empty(l)) ret; syncAddAll(data, l); fireDataChanged(); }
  void addAndScrollDown(A a) { add(a); scrollDown(); }
  void remove(A a) { syncRemove(data, a); fireDataChanged(); }
  void removeAll(L<A> a) { syncRemoveAll(data, a); fireDataChanged(); }
  void setList(Iterable<A> data) { setData(data); }
  void removeSelected() { removeAll(allSelected()); }
  
  void setData(Iterable<A> data, bool force default false) {
    swing {
      int[] selection = selectedTableRows_array(table);
      L<A> cloned = cloneList(data);
      if (force || !eq(this.data, cloned)) {
        this.data = cloned;
        updateTable();
      }
      selectTableRows(table, selection);
    }
  }
  int count() { ret syncL(data); }
  
  void setData_force(Iterable<A> data) { setData(data, true); }
  
  // tries to keep selection
  void fireDataChanged() { setData_force(data); }
  
  int rowFromSearcher(int i) {
    ret searcher == null || searcher.rowIndices == null ? i : or(get(searcher.rowIndices, i), -1);
  }
  
  A selected() { ret syncGet(data, rowFromSearcher(selectedTableRowInModel(table))); }
  L<A> allSelected() { ret syncListGetMulti(data, selectedIndices()); }
  int selectedIndex() { ret selectedTableRow(table); }
  L<Int> selectedIndices() { ret map(i -> rowFromSearcher(i), selectedTableRowsInModel(table)); }
  bool selectItem(A a) { int i = indexOf(data, a); selectRow(table, i); ret i >= 0; } // true if item exists
  void doubleClickItem(A a) { if (selectItem(a)) defaultAction?.get(a); }
  
  // run only after visualized!
  void popupMenuItem(S text, IVF1<A> r) {
    tablePopupMenuItemsThreaded(table, text, _convertRunnable(r));
  }
  
  void popupMenuItem_top(S text, IVF1<A> r) {
    tablePopupMenuItemsThreaded_top(table, text, _convertRunnable(r));
  }
  
  // row index => element
  IVF1<Int> _convertRunnable(IVF1<A> r) {
    ret r == null ?: idx -> r.get(syncGet(data, idx));
  }
  
  void hideFields(S... fields) {
    if (hideFields == null) hideFields = new Set;
    _addAll(hideFields, fields);
  }
  
  A getRow(int row) { ret get(data, row); }
  
  void scrollDown { scrollTableDownNow(table); }
  
  void onSelect(IVF1<A> r) {
    visualize();
    onTableSelectionChanged(table, -> pcallF_typed(r, selected()));
  }
  
  L<A> getList() { ret data; }
}

Author comment

Began life as a copy of #1030725

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1034021
Snippet name: JObjectTable - like JConceptsTable but for any kind of object
Eternal ID of this version: #1034021/17
Text MD5: 91b330004687208503c65f877bcc487d
Author: stefan
Category: javax / gui / concepts
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-03-25 22:59:05
Source code size: 4268 bytes / 123 lines
Pitched / IR pitched: No / No
Views / Downloads: 178 / 348
Version history: 16 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)