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

250
LINES

< > BotCompany Repo | #1030792 // SimpleCRUD_v2 [backup before dynamic fields]

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

Libraryless. Click here for Pure Java version (21444L/150K).

1  
sbool SimpleCRUD_searcher = true;
2  
3  
sclass SimpleCRUD_v2<A extends Concept> extends JConceptsTable<A> {
4  
  JPanel buttons, panel;
5  
  S hID = "ID"; // Column header for concept ID
6  
  Set<S> unshownFields; // not shown in table or form
7  
  Set<S> excludeFieldsFromEditing;
8  
  S modifiedField; // field to hold last-modified timestamp
9  
  TableSearcher tableSearcher;
10  
  Set<S> multiLineFields; // string fields that should be shown as text areas
11  
  Set<S> dontDuplicateFields;
12  
  int formFixer = 12; // stupid value to make submit button appear
13  
  bool showBackRefs;
14  
  int maxRefsToShow = 3;
15  
16  
  *(Class<A> conceptClass) { super(conceptClass); }
17  
  *(Concepts concepts, Class<A> conceptClass) { super(concepts, conceptClass); }
18  
  
19  
  SimpleCRUD_v2<A> show(S frameTitle) {
20  
    make();
21  
    showFrame(frameTitle, panel);
22  
    this;
23  
  }
24  
  
25  
  SimpleCRUD_v2<A> show() {
26  
    ret show(plural(shortClassName(conceptClass)));
27  
  }
28  
  
29  
  SimpleCRUD_v2<A> showMaximized() { show(); maximizeFrame(panel); ret this; }
30  
  
31  
  JPanel makePanel() { ret make(); }
32  
  JPanel make() {
33  
    db();
34  
    framesBot();
35  
    ret make_dontStartBots();
36  
  }
37  
  
38  
  swappable MapSO itemToMap_inner(A a) {
39  
    ret super.itemToMap_base(a);
40  
  }
41  
  
42  
  MapSO itemToMap_base(A a) {
43  
    MapSO map = itemToMap_inner(a);
44  
    if (map == null) null;
45  
    ret putAll(putAll(specialFieldsForItem(a), map), moreSpecialFieldsForItem(a));
46  
  }
47  
  
48  
  // shown on the left (usually)
49  
  swappable MapSO specialFieldsForItem(A a) {
50  
    MapSO map = litorderedmap(hID, str(a.id));
51  
    mapPut(map, "Java Class", javaClassDescForItem(a));
52  
    ret map;
53  
  }
54  
  
55  
  // shown on the right (usually)
56  
  swappable MapSO moreSpecialFieldsForItem(A a) {
57  
    MapSO map = litorderedmap();
58  
    if (showBackRefs) {
59  
      Cl<Concept> refs = allBackRefs(a);
60  
      if (nempty(refs)) {
61  
        refs = sortedByConceptID(refs);
62  
        int more = l(refs)-maxRefsToShow;
63  
        map.put("Referenced by",
64  
          joinWithComma(takeFirst(maxRefsToShow, refs))
65  
        + (more > 0 ? ", " + more + " more" : ""));
66  
      }
67  
    }
68  
    ret map;
69  
  }
70  
  
71  
  S javaClassDescForItem(A a) {
72  
    S className = dynShortClassName(a);
73  
    if (neq(className, shortClassName(conceptClass))) {
74  
      S text = className;
75  
      S realClass = shortClassName(a);
76  
      if (neq(className, realClass))
77  
        text += " as " + realClass;
78  
      ret text;
79  
    }
80  
    null;
81  
  }
82  
  
83  
  JPanel make_dontStartBots() {
84  
    dropFields = asList(unshownFields);
85  
    makeTable();
86  
    swing {
87  
      buttons = jRightAlignedLine(
88  
        jbutton("Add...", r { newConcept() }),
89  
        tableDependButton(table, jbutton("Edit", r {
90  
          editConcept(selectedConcept())
91  
        })),
92  
        tableDependButton(table, jbutton("Delete", r {
93  
          final L<A> l = selectedConcepts();
94  
          withDBLock(concepts, r { for (A c : l) c.delete() });
95  
        })),
96  
        tableDependButton(table, jbutton("Duplicate...", r {
97  
          duplicateConcept(selectedConcept())
98  
        })));
99  
        
100  
      if (SimpleCRUD_searcher) {
101  
        tableSearcher = tableWithSearcher2(table, withMargin := true);
102  
        panel = centerAndSouthWithMargin(tableSearcher.panel, withBottomMargin(buttons));
103  
      } else
104  
        panel = centerAndSouthWithMargin(table, withBottomMargin(buttons));
105  
      
106  
      O fEdit = voidfunc(int row) {
107  
        editConcept(getItem(row))
108  
      };
109  
      tablePopupMenuItem(table, "Edit...", fEdit);
110  
      onDoubleClick(table, fEdit);
111  
      tablePopupMenuFirst(table, (menu, row) -> {
112  
        Concept c = getItem(row);
113  
        if (c != null)
114  
          addMenuItem(menu, "Delete " + quote(shorten(str(c))), rThread {
115  
            deleteConcept(c);
116  
          });
117  
      });
118  
    } // end of swing
119  
    ret panel;
120  
  }
121  
  
122  
  void newConcept {
123  
    duplicateConcept(null);
124  
  }
125  
    
126  
  void duplicateConcept(A oldConcept) {
127  
    final A c = unlisted(conceptClass);
128  
    ccopyFieldsExcept(oldConcept, c, dontDuplicateFields);
129  
    final Map<S, JComponent> map = makeComponents(c);
130  
    Runnable r = r {
131  
      concepts.register(c);
132  
      saveData(c, map);
133  
    };
134  
    temp tempSetMCOpt(formLayouter1_fixer2 := formFixer);
135  
    showFormTitled2("New " + shortClassName(conceptClass), arrayPlus(mapToObjectArray(map), r));
136  
  }
137  
138  
  void editConcept(final A c) {
139  
    if (c == null) ret;
140  
    final Map<S, JComponent> map = makeComponents(c);
141  
    Runnable r = r { saveData(c, map) };
142  
    temp tempSetMCOpt(formLayouter1_fixer2 := formFixer);
143  
    showFormTitled2("Edit " + shortClassName(conceptClass) + " #" + c.id, arrayPlus(mapToObjectArray(map), r));
144  
  }
145  
  
146  
  A selectedConcept() {
147  
    ret (A) concepts.getConcept(toLong(selectedTableCell(table, 0)));
148  
  }
149  
  
150  
  A selected() { ret selectedConcept(); }
151  
  
152  
  A getItem(int row) {
153  
    ret (A) concepts.getConcept(toLong(getTableCell(table, row, 0)));
154  
  }
155  
  
156  
  int indexOfConcept(final A c) {
157  
    if (c == null) ret -1;
158  
    ret swing(func -> int {
159  
      int n = tableRowCount(table);
160  
      for row to n:
161  
        if (toLong(getTableCell(table, row, 0)) == c.id)
162  
          ret row;
163  
      ret -1;
164  
    });
165  
  }
166  
  
167  
  L<A> selectedConcepts() {
168  
    int[] rows = table.getSelectedRows();
169  
    new L<A> l;
170  
    for (int row : rows)
171  
      l.add(getItem(row));
172  
    ret l;
173  
  }
174  
  
175  
  Map<S, JComponent> makeComponents(A c) {
176  
    Map<S, JComponent> map = litorderedmap();
177  
    makeComponents(c, map);
178  
    ret map;
179  
  }
180  
  
181  
  JComponent fieldComponent(A c, S field) {
182  
    Class type = getFieldType(conceptClass, field);
183  
    O value = getOpt(c, field);
184  
    //print("Field type: " + field + " => " + type);
185  
    if (type == bool.class)
186  
      ret jCenteredCheckBox(isTrue(value));
187  
    else if (contains(multiLineFields, field) || containsNewLines(optCast S(value)))
188  
      ret typeWriterTextArea((S) value);
189  
    else if (isSubtype(type, Concept))
190  
      ret jcomboboxFromConcepts_str(concepts, type, (Concept) value);
191  
    ifclass SecretValue
192  
    else if (type == SecretValue.class)
193  
      ret jpassword(strOrEmpty(getVar(value/SecretValue)));
194  
    endif
195  
    else try {
196  
      ret autoComboBox(structureOrText_crud(value), new TreeSet<S>(map structureOrText_crud(collect(list(concepts, conceptClass), field))));
197  
    } catch e {
198  
      printException(e);
199  
      ret jTextField(structureOrText_crud(value));
200  
    }
201  
  }
202  
  
203  
  void saveComponent(A c, S field, JComponent comp) {
204  
    comp = unwrap(comp);
205  
    Class type = fieldType(c, field);
206  
    ifclass SecretValue
207  
      if (type == SecretValue.class) {
208  
        S text = getTextTrim((JPasswordField) comp);
209  
        cset(c, field, empty(text) ? null : SecretValue(text));
210  
      } else
211  
    endif
212  
    if (comp instanceof JTextComponent)
213  
      cset(c, field, convertToField(trimIf(!comp instanceof JTextArea, getText((JTextComponent) comp)), conceptClass, field));
214  
    else if (comp cast JComboBox) {
215  
      S text = getTextTrim(comp);
216  
      if (isSubtype(type, Concept))
217  
        cset(c, field, getConcept(concepts, parseFirstLong(text)));
218  
      else
219  
        cset(c, field, convertToField(text, conceptClass, field));
220  
    } else if (comp instanceof JCheckBox)
221  
      cset(c, field, isChecked((JCheckBox) comp));
222  
    ifclass ImageChooser
223  
      else if (comp instanceof ImageChooser)
224  
        cUpdatePNGFile(c, field, comp/ImageChooser.getImage(), false);
225  
    endif
226  
  }
227  
  
228  
  L<S> fields() {
229  
    if (excludeFieldsFromEditing != null && modifiedField != null) excludeFieldsFromEditing.add(modifiedField);
230  
    ret listWithoutSet([S field : conceptFieldsInOrder(conceptClass) | fieldType(conceptClass, field) != Concept.Ref.class],
231  
      joinSets(excludeFieldsFromEditing, unshownFields));
232  
  }
233  
  
234  
  void excludeFieldsFromEditing(S... fields) {
235  
    excludeFieldsFromEditing = setPlus(excludeFieldsFromEditing, fields);
236  
  }
237  
  
238  
  // override the following two methods to customize edit window
239  
  
240  
  void makeComponents(A c, Map<S, JComponent> map) {
241  
    for (S field : fields())
242  
      map.put(field, fieldComponent(c, field));
243  
  }
244  
  
245  
  void saveData(A c, Map<S, JComponent> components) {
246  
    for (S field : keys(components))
247  
      saveComponent(c, field, components.get(field));
248  
    if (modifiedField != null) cset(c, modifiedField, now());
249  
  }
250  
}

Author comment

Began life as a copy of #1030726

download  show line numbers  debug dex  old transpilations   

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

No comments. add comment

Snippet ID: #1030792
Snippet name: SimpleCRUD_v2 [backup before dynamic fields]
Eternal ID of this version: #1030792/1
Text MD5: 6d10e55d6b4076c1509ec1b5297f89c1
Transpilation MD5: 98ca5325aa29889c8bc0862c10088ef8
Author: stefan
Category: javax / concepts / gui
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-03-26 14:41:28
Source code size: 8266 bytes / 250 lines
Pitched / IR pitched: No / No
Views / Downloads: 152 / 217
Referenced in: [show references]