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: | 541 / 1086 |
| Version history: | 3 change(s) |
| Referenced in: | [show references] |