Uses 2164K of libraries. Click here for Pure Java version (68294L/362K).
1 | srecord noeq G22JavaObjectVisualizer(G22Utils g22utils) is Swingable { |
2 | settable bool withTypeAndTime = true; |
3 | settable bool singleLineLayout; // TODO |
4 | settable int maxElements = 1000; // max elements of collection to show |
5 | settable bool horizontal; |
6 | settable int floatingPointDigits = 4; |
7 | settable bool allowDescendingIntoListElements; |
8 | settable double scriptTimeout = 10.0; |
9 | settable int stringDisplayLength = 80; |
10 | |
11 | Set seen = identityHashSet(); |
12 | |
13 | transient settable O object; |
14 | transient settable long nanos = -1; |
15 | |
16 | transient SingleComponentPanel scp = scp(); |
17 | |
18 | *(G22Utils *g22utils, O *object) {} |
19 | |
20 | // call after visualizeObject (so properties are filled) |
21 | S objectInfos(O object default this.object) { |
22 | new LS infos; |
23 | infos.add(str(shortClassName2(object))); // shows "null" for null value |
24 | for (key, val : mainVisualizer().properties) { |
25 | S s = n2OrStrOrNull(val); |
26 | if (nempty(s)) |
27 | infos.add(key + " " + s); |
28 | } |
29 | |
30 | if (nanos >= 0) { |
31 | S timeDesc = nanos < 0 ? "" : formatElapsedTimeWithAppropriateUnit(nanosToSeconds(nanos)); |
32 | infos.add(timeDesc); |
33 | } |
34 | |
35 | ret joinNemptiesWithComma(infos); |
36 | } |
37 | |
38 | cachedVisualize { |
39 | //printVars("Visualizing", +this, +withTypeAndTime); |
40 | |
41 | scp.set(visualizeObjectWithExtras(object)); |
42 | ret scp; |
43 | } |
44 | |
45 | JComponent visualizeObject(O object) { |
46 | ret mainVisualizer().visualize(object); |
47 | } |
48 | |
49 | JComponent visualizeObjectWithExtras(O object, Component back default null) { |
50 | JComponent c = visualizeObject(object); |
51 | |
52 | JButton btnBack = back == null ?: jimageButtonScaledToWidth(16, #1103102, -> scp.set(back)); |
53 | |
54 | JComponent lblType = null; |
55 | if (withTypeAndTime) { |
56 | S type = objectInfos(object); |
57 | lblType = withLabel("Type:", jlabel(type)); |
58 | } |
59 | |
60 | if (btnBack != null || lblType != null) { |
61 | JComponent top = or(lblType, jpanel()); |
62 | if (btnBack != null) |
63 | top = westAndCenterWithMargin(btnBack, top); |
64 | ret northAndCenterWithMargins(top, c); |
65 | } |
66 | |
67 | ret c; |
68 | } |
69 | |
70 | simplyCached ObjectVisualizer mainVisualizer() { |
71 | ret new ObjectVisualizer().recurse(true).bigFont(true).horizontal(horizontal); |
72 | } |
73 | |
74 | class ObjectVisualizer { |
75 | settable bool recurse; |
76 | settable bool bigFont; |
77 | settable bool horizontal; |
78 | settable bool scrollable = true; |
79 | |
80 | new LinkedHashMap<S, O> properties; |
81 | |
82 | // only one recursion level so far |
83 | ObjectVisualizer subVisualizer() { |
84 | ret new ObjectVisualizer().horizontal(!horizontal); |
85 | } |
86 | |
87 | ObjectVisualizer subVisualizerOnSameLevel() { |
88 | ret new ObjectVisualizer().horizontal(horizontal) |
89 | .recurse(recurse).bigFont(bigFont) |
90 | .scrollable(false); |
91 | } |
92 | |
93 | JComponent makeBig(JComponent c) { |
94 | if (bigFont) ret fontSizePlus(10, c); |
95 | ret c; |
96 | } |
97 | |
98 | JComponent subVisualizeOnSameLevel(O o) { |
99 | ret subVisualizerOnSameLevel().visualize(o); |
100 | } |
101 | |
102 | JComponent visualize(O object) { |
103 | try { |
104 | ret visualize2(object); |
105 | } catch e { |
106 | ret g22utils.jErrorView(new RuntimeException("Visualization error", e)); |
107 | } |
108 | } |
109 | |
110 | JComponent visualize2(O object) { |
111 | // exception |
112 | |
113 | if (object cast Throwable) |
114 | ret g22utils.jErrorView(object); |
115 | |
116 | // null or empty string |
117 | |
118 | if (object == null || eq(object, "")) |
119 | ret jpanel(); |
120 | |
121 | // array to list |
122 | |
123 | object = arrayToList(object); |
124 | |
125 | // Swing component |
126 | |
127 | if (object cast Swingable) |
128 | object = object.visualize(); |
129 | |
130 | if (object cast JComponent && getParent(object) == null) |
131 | ret object; |
132 | |
133 | // number |
134 | |
135 | if (object cast Int) object = toLong(object); |
136 | if (object cast Long) |
137 | ret bigText(n2(object)); |
138 | if (object cast Double) |
139 | ret toolTip(str(object), bigText(formatDouble(object, floatingPointDigits))); |
140 | if (object cast Number) |
141 | ret bigText(object); |
142 | |
143 | if (object cast Pair) |
144 | ret visualizeTuple(pairToList(object)); |
145 | |
146 | if (object cast T3) |
147 | ret visualizeTuple(tripleToList(object)); |
148 | |
149 | // image |
150 | |
151 | if (object cast MakesBufferedImage) |
152 | object = toBufferedImage(object); |
153 | if (object cast BufferedImage) { |
154 | var is = g22utils.stdImageSurface(object); |
155 | if (!recurse) is.setAutoZoomToDisplay(false); |
156 | ret jscroll_centered_borderless(is); |
157 | } |
158 | |
159 | // FunctionDef |
160 | |
161 | if (object cast GazelleV_LeftArrowScript.FunctionDef) { |
162 | var f = object; |
163 | if (empty(f.args)) |
164 | ret centerAndEastWithMargin(visualizeAsText(f), |
165 | jverticalCenter(jThreadedButton("Call", -> inspectElement(callFunctionDef(f))))); |
166 | } |
167 | |
168 | if (recurse) { |
169 | // TODO |
170 | /*if (!seen.add(object)) |
171 | ret jlabel("Object already seen");*/ |
172 | |
173 | // multi-map |
174 | |
175 | ifclass MultiMap |
176 | if (object cast MultiMap) { |
177 | propertyLength(l(object)); |
178 | propertyKeyCount(object.keyCount()); |
179 | object = multiMapToMapPairs(object); |
180 | } |
181 | endif |
182 | |
183 | ifclass MultiSetMap |
184 | if (object cast MultiSetMap) { |
185 | propertyLength(l(object)); |
186 | propertyKeyCount(object.keyCount()); |
187 | object = multiSetMapToMapPairs(object); |
188 | } |
189 | endif |
190 | |
191 | // map |
192 | |
193 | if (object cast Map) { |
194 | propertyLength(l(object)); |
195 | object = mapToPairs(object); |
196 | } |
197 | |
198 | // array / collection |
199 | |
200 | if (object cast Collection) { |
201 | propertyLength(l(object)); |
202 | var sub = subVisualizer(); |
203 | var elements = map(cloneTakeFirst(maxElements, object), |
204 | element -> { |
205 | var elementVis = sub.visualize(element); |
206 | if (allowDescendingIntoListElements) |
207 | elementVis = centerAndEastWithMargin( |
208 | elementVis, new JPopDownButton().content("Inspect element" := rThread { inspectElement(element) })); |
209 | ret elementVis; |
210 | }); |
211 | |
212 | ret stackElements(elements); |
213 | } |
214 | } // end of if recurse |
215 | |
216 | ret visualizeAsText(object); |
217 | } // end of visualize2 |
218 | |
219 | JComponent visualizeTuple(L tuple) { |
220 | if (horizontal) |
221 | ret jcenteredline(listCombine( |
222 | jlabel("<"), |
223 | intersperseF(-> jlabel(","), map visualize(tuple)), |
224 | jlabel(">"))); |
225 | else |
226 | ret stackElements(listCombine( |
227 | map subVisualizeOnSameLevel(tuple))); |
228 | } |
229 | |
230 | JComponent visualizeAsText(Object object) { |
231 | if (object cast S) { |
232 | propertyLength(l(object)); |
233 | } |
234 | |
235 | S string = str(object); |
236 | if (containsNewLine(string)) |
237 | ret jscroll_borderless(wordWrapTypeWriterTextArea(string)); |
238 | |
239 | if (recurse && l(string) > stringDisplayLength) |
240 | ret jText(string); |
241 | |
242 | var lbl = jcenterNarrowLabel(shorten(string)); |
243 | if (l(string) <= 10) |
244 | ret makeBig(lbl); |
245 | ret lbl; |
246 | } // end of visualizeAsText |
247 | |
248 | void propertyLength(int l) { properties.put("size", l); } |
249 | void propertyKeyCount(int l) { properties.put("keys", l); } |
250 | |
251 | JComponent bigText(O o) { |
252 | ret makeBig(jcenteredLabel(str(o))); |
253 | } |
254 | |
255 | O arrayToList(O object) { |
256 | if (isArray(object)) |
257 | object = wrapArrayAsImmutableList(object); |
258 | ret object; |
259 | } |
260 | |
261 | JComponent stackElements(L<? extends JComponent> elements) { |
262 | var c = horizontal ? hstackWithSpacing(elements) |
263 | : vstackWithSpacing(elements); |
264 | ret scrollable ? jscroll_centered_borderless(c) : c; |
265 | } |
266 | |
267 | } // end of ObjectVisualizer |
268 | |
269 | selfType withType(bool b) { |
270 | ret withTypeAndTime(b); |
271 | } |
272 | |
273 | void inspectElement(O element) { |
274 | var back = scp.getComponent(); |
275 | scp.set(visualizeObjectWithExtras(element, back)); |
276 | } |
277 | |
278 | O callFunctionDef(GazelleV_LeftArrowScript.FunctionDef f) { |
279 | ret evalWithTimeoutOrFail(scriptTimeout, -> f.call(new FlexibleVarContext)); |
280 | } |
281 | } |
download show line numbers debug dex old transpilations
Travelled to 5 computer(s): bhatertpkbcr, ekrmjmnbrukm, iveijnkanddl, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034494 |
Snippet name: | G22JavaObjectVisualizer |
Eternal ID of this version: | #1034494/85 |
Text MD5: | 37f4f9ddeb3609d15f1e3370cf16cb09 |
Transpilation MD5: | d08b157af07f3ff7d3bb2a410b6487fc |
Author: | stefan |
Category: | javax / gazelle 22 |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-02-12 20:05:03 |
Source code size: | 8323 bytes / 281 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 356 / 1051 |
Version history: | 84 change(s) |
Referenced in: | [show references] |