1 | sbool dm_SimpleCRUD_searcher = true; |
2 | |
3 | sclass dm_SimpleCRUD<A> { |
4 | DynModule module; |
5 | L<A> theList; |
6 | Class<A> cc; |
7 | JTable table; |
8 | JPanel buttons, panel; |
9 | O renderer; // optional, func(A) -> Map |
10 | S hID = "ID"; |
11 | LS fields; |
12 | |
13 | *(DynModule *module, L<A> *theList, Class<A> *cc) {} |
14 | |
15 | JPanel make() { |
16 | // next line not in swing part to allow passing arguments |
17 | // from outside like showConceptsTable_afterUpdate |
18 | table = makeConceptsTable(cc, wrapRenderer(renderer)); |
19 | swing { |
20 | panel = centerAndSouth(SimpleCRUD_searcher ? tableWithSearcher(table) : table, buttons = jRightAlignedLine( |
21 | jbutton("Add...", r { newConcept() }), |
22 | tableDependButton(table, jbutton("Edit", r { |
23 | editConcept(selectedConcept()) |
24 | })), |
25 | tableDependButton(table, jbutton("Delete", r { |
26 | final L<A> l = selectedConcepts(); |
27 | withDBLock(r { for (A c : l) c.delete() }); |
28 | })))); |
29 | |
30 | O fEdit = voidfunc(int row) { |
31 | editConcept((A) getConcept(toLong(getTableCell(table, row, 0)))) |
32 | }; |
33 | tablePopupMenuItem(table, "Edit...", fEdit); |
34 | onDoubleClick(table, fEdit); |
35 | } |
36 | ret panel; |
37 | } |
38 | |
39 | O wrapRenderer(fO renderer) { |
40 | ret renderer == null ? null : func(A a) { |
41 | putAll(litorderedmap(hID, str(a.id)), (Map) callF(renderer, a)) |
42 | }; |
43 | } |
44 | |
45 | void newConcept { |
46 | final A c = nu(cc); |
47 | final Map<S, JComponent> map = makeComponents(c); |
48 | Runnable r = r { |
49 | saveData(c, map); |
50 | theList.add(c); module.change(); |
51 | }; |
52 | showFormTitled("New " + shortClassName(cc), arrayPlus(mapToObjectArray(map), r)); |
53 | } |
54 | |
55 | void editConcept(final A c) { |
56 | if (c == null) ret; |
57 | final Map<S, JComponent> map = makeComponents(c); |
58 | Runnable r = r { saveData(c, map); module.change(); }; |
59 | showFormTitled("Edit " + shortClassName(cc) + " #" + c.id, arrayPlus(mapToObjectArray(map), r)); |
60 | } |
61 | |
62 | A selectedConcept() { |
63 | ret (A) getConcept(toLong(selectedTableCell(table, 0))); |
64 | } |
65 | |
66 | L<A> selectedConcepts() { |
67 | int[] rows = table.getSelectedRows(); |
68 | new L<A> l; |
69 | for (int row : rows) |
70 | l.add((A) getConcept(toLong(getTableCell(table, row, 0)))); |
71 | ret l; |
72 | } |
73 | |
74 | Map<S, JComponent> makeComponents(A c) { |
75 | Map<S, JComponent> map = litorderedmap(); |
76 | makeComponents(c, map); |
77 | ret map; |
78 | } |
79 | |
80 | JComponent fieldComponent(A c, S field) { |
81 | Class type = getFieldType(cc, field); |
82 | O value = getOpt(c, field); |
83 | //print("Field type: " + field + " => " + type); |
84 | if (type == bool.class) |
85 | ret jCenteredCheckBox(isTrue(value)); |
86 | else try { |
87 | ret autoComboBox(structureOrText_crud(value), new TreeSet<S>(map structureOrText_crud(collect(list(cc), field)))); |
88 | } catch e { |
89 | printException(e); |
90 | ret jTextField(structureOrText_crud(value)); |
91 | } |
92 | } |
93 | |
94 | void saveComponent(A c, S field, JComponent comp) { |
95 | comp = unwrap(comp); |
96 | if (comp instanceof JTextComponent) |
97 | setOpt(c, field, convertToField(getTextTrim((JTextComponent) comp), cc, field)); |
98 | else if (comp instanceof JComboBox) |
99 | setOpt(c, field, convertToField(getTextTrim((JComboBox) comp), cc, field)); |
100 | else if (comp instanceof JCheckBox) |
101 | setOpt(c, field, isChecked((JCheckBox) comp)); |
102 | /*ifclass ImageChooser |
103 | else if (comp instanceof ImageChooser) |
104 | cUpdatePNGFile(c, field, comp/ImageChooser.getImage(), false); |
105 | endif*/ |
106 | } |
107 | |
108 | L<S> fields() { |
109 | if (fields != null) ret fields; |
110 | ret fieldsInOrder(cc); |
111 | } |
112 | |
113 | // override the following two methods to customize edit window |
114 | |
115 | void makeComponents(A c, Map<S, JComponent> map) { |
116 | for (S field : fields()) |
117 | map.put(field, fieldComponent(c, field)); |
118 | } |
119 | |
120 | void saveData(A c, Map<S, JComponent> components) { |
121 | for (S field : keys(components)) |
122 | saveComponent(c, field, components.get(field)); |
123 | } |
124 | } |
Began life as a copy of #1006540
download show line numbers debug dex old transpilations
Travelled to 12 computer(s): bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1019417 |
Snippet name: | dm_SimpleCRUD [dev.] - create/read/update/delete for a list in a dynamic module |
Eternal ID of this version: | #1019417/4 |
Text MD5: | ea40e16ff089881fb736c27839797661 |
Author: | stefan |
Category: | javax / concepts / gui |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2018-11-06 17:09:20 |
Source code size: | 3944 bytes / 124 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 302 / 843 |
Version history: | 3 change(s) |
Referenced in: | [show references] |