Libraryless. Click here for Pure Java version (17927L/107K).
1 | // Note: renderUIUrl etc are called in Swing thread |
2 | |
3 | // TODO: improve AutoComboBox and put it back in |
4 | |
5 | persistable srecord noeq UIURLSystem(transient Enterable owner, transient SimpleLiveValue<S> uiURL) extends MetaWithChangeListeners { |
6 | settable bool showHomeButton = true; |
7 | settable int maxHistoryEntries = 100; |
8 | settable bool showGoButton; |
9 | |
10 | // key: ui URL |
11 | transient Map<S, Entry> uiMap = syncCIMap(); |
12 | |
13 | // these are additionally displayed at the top of the list |
14 | // first URL will be shown as "Home" button (if home button is enabled) |
15 | LS preferredURLs = syncList(); |
16 | |
17 | LS history = syncLinkedList(); |
18 | LS forwardHistory = syncLinkedList(); |
19 | |
20 | sclass Entry { |
21 | S url; |
22 | S toolTip; |
23 | IF0<? extends JComponent> makeComponent; |
24 | |
25 | *(S *url, IF0<? extends JComponent> *makeComponent) {} |
26 | *(S *url, S *toolTip, IF0<? extends JComponent> *makeComponent) {} |
27 | } |
28 | |
29 | settable transient SingleComponentPanel scp; |
30 | transient JComboBox<S> comboBox; |
31 | transient JButton btnHome, btnBack, btnForward; |
32 | |
33 | transient simplyCached JComponent urlBar() { |
34 | //comboBox = autoComboBox(url(), cloneKeys(uiMap)); |
35 | comboBox = jcombobox(urlsForComboBox()); |
36 | //centerComboBox(comboBox); |
37 | comboBox.setRenderer( |
38 | new CenteredComboBoxRenderer( |
39 | new ListCellRendererWithToolTip<S>(url -> toolTipForURL(url), |
40 | (ListCellRenderer<S>) comboBox.getRenderer()))); |
41 | //comboBoxDynamicToolTip(comboBox, url -> toolTipForURL(url)); |
42 | |
43 | onSelectedItem( |
44 | bindComboBoxToLiveValue(comboBox, uiURL), |
45 | url -> showUIURL(url) |
46 | ); |
47 | |
48 | Runnable cbAction = comboBoxAction(comboBox, url -> showUIURL(url)); |
49 | |
50 | JPanel rightButtons = jlineWithSpacing(5, ); |
51 | JPanel leftButtons = jlineWithSpacing(5); |
52 | |
53 | if (showGoButton) |
54 | rightButtons.add(jbutton("Go", cbAction)); |
55 | |
56 | JComponent panel = withLabel("Show", |
57 | centerAndEastWithMargin( |
58 | comboBox, |
59 | rightButtons)); |
60 | |
61 | btnBack = jimageButtonScaledToWidth(16, #1103102, l0 goBack); |
62 | add(rightButtons, btnBack); |
63 | |
64 | btnForward = jimageButtonScaledToWidth(16, #1103103, l0 goForward); |
65 | add(rightButtons, btnForward); |
66 | |
67 | if (showHomeButton) { |
68 | S homeURL = homeURL(); |
69 | btnHome = jimageButtonScaledToWidth(16, #1103101, |
70 | homeURL != null ? "Go to " + homeURL : "Go to home URL", |
71 | l0 goHome); |
72 | add(rightButtons, btnHome); |
73 | } |
74 | |
75 | uiURL.onChangeAndNow(l0 updateButtons); |
76 | |
77 | if (!emptyContainer(leftButtons)) |
78 | panel = westAndCenterWithMargin(leftButtons, panel); |
79 | ret panel; |
80 | } |
81 | |
82 | void updateButtons { |
83 | swing { |
84 | S homeURL = homeURL(); |
85 | setEnabled(btnHome, homeURL != null && !eq(homeURL, url())); |
86 | |
87 | S backURL = last(history); |
88 | setEnabled(btnBack, backURL != null); |
89 | setToolTip(btnBack, backURL == null ? "Go back" : "Go back to " + backURL); |
90 | |
91 | S forwardURL = first(forwardHistory); |
92 | printVars("updateButtons", +forwardURL); |
93 | setEnabled(btnForward, forwardURL != null); |
94 | setToolTip(btnForward, forwardURL == null ? "Go forward" : "Go forward to " + forwardURL); |
95 | } |
96 | change(); |
97 | } |
98 | |
99 | JComponent renderUIUrl aka renderUIURL aka uiGet(S url) { |
100 | try { |
101 | temp tempEnter(owner); |
102 | var entry = uiMap.get(url); |
103 | if (entry == null) ret jCenteredLabel("URL not found: " + url); |
104 | var component = entry.makeComponent!; |
105 | ret component; |
106 | } catch print e { |
107 | ret jErrorView(e); |
108 | } |
109 | } |
110 | |
111 | bool hasURL(S url) { ret uiMap.containsKey(url); } |
112 | |
113 | void showUIURL(S url) swing { |
114 | if (!eqic(url(), url)) { |
115 | addToHistory(url()); |
116 | showUIURL_dontAddToHistory(url); |
117 | } |
118 | } |
119 | |
120 | void addToHistory(S url) { |
121 | printVars("addToHistory", +url); |
122 | if (empty(url) || eqic(last(history), url)) ret; |
123 | removeAllIC_useIterator(history, url); |
124 | history.add(url); |
125 | if (l(history) > maxHistoryEntries) removeFirst(history); |
126 | forwardHistory.clear(); |
127 | updateButtons(); |
128 | } |
129 | |
130 | void showUIURL_dontAddToHistory(S url) { |
131 | temp tempEnter(owner); |
132 | |
133 | setURL(trim(url)); |
134 | go(); |
135 | } |
136 | |
137 | void go { |
138 | setComponent(scp, renderUIUrl(url())); |
139 | } |
140 | |
141 | S url() { ret uiURL!; } |
142 | void setURL(S url) { |
143 | assertURLValid(url); |
144 | uiURL.set(url); |
145 | } |
146 | |
147 | swappable void assertURLValid(S url) { |
148 | if (!uiMap.containsKey(url)) |
149 | fail("UIURL not found: " + url); |
150 | } |
151 | |
152 | selfType put(WithToolTip<S> url, IF0<? extends JComponent> maker) { |
153 | ret put(url!, url.toolTip(), maker); |
154 | } |
155 | |
156 | selfType put(S url, S toolTip default null, IF0<? extends JComponent> maker) { |
157 | uiMap.put(url, new Entry(url, toolTip, maker)); |
158 | setComboBoxItems(comboBox, urlsForComboBox()); |
159 | this; |
160 | } |
161 | |
162 | S toolTipForURL(S url) { |
163 | var e = uiMap.get(url); |
164 | ret e?.toolTip; |
165 | } |
166 | |
167 | LS urlsForComboBox() { |
168 | var sorted = cloneKeys(uiMap); |
169 | ret concatLists(listSetIntersection(preferredURLs, sorted), sorted); |
170 | } |
171 | |
172 | void addPreferredUIURL(S uiURL) { |
173 | addIfNotContained(preferredURLs, uiURL); |
174 | } |
175 | |
176 | S homeURL() { ret first(preferredURLs); } |
177 | |
178 | void goHome { showUIURL(homeURL()); } |
179 | |
180 | void goBack swing { |
181 | S url = popLast(history); |
182 | if (url != null) { |
183 | S currentURL = url(); |
184 | if (nempty(currentURL)) |
185 | forwardHistory.add(0, currentURL); |
186 | printVars("goBack", +url, +currentURL, +forwardHistory); |
187 | updateButtons(); |
188 | showUIURL_dontAddToHistory(url); |
189 | } |
190 | } |
191 | |
192 | void goForward swing { |
193 | S url = popFirst(forwardHistory); |
194 | if (url != null) { |
195 | S currentURL = url(); |
196 | if (nempty(currentURL)) |
197 | history.add(currentURL); |
198 | printVars("goForward", +url, +currentURL, +history); |
199 | updateButtons(); |
200 | showUIURL_dontAddToHistory(url); |
201 | } |
202 | } |
203 | } |
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1033790 |
Snippet name: | UIURLSystem - "UI URLs" (free-form case-insensitive URLs to navigate the UI) for Swing |
Eternal ID of this version: | #1033790/76 |
Text MD5: | dabbd2bd38ce7d11791763fe62b1b16c |
Transpilation MD5: | 7997ef840c5f99db8a90388321d3eeb2 |
Author: | stefan |
Category: | javax / gui |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-12-11 16:33:30 |
Source code size: | 5909 bytes / 203 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 273 / 806 |
Version history: | 75 change(s) |
Referenced in: | [show references] |