Libraryless. Click here for Pure Java version (5063L/36K/119K).
1 | // The Runner! |
2 | |
3 | !1003872 // neeeeww |
4 | |
5 | static JFrame frame; |
6 | static JList list; |
7 | static JTextField tfCmd; |
8 | static JLabel status; |
9 | static JButton btnReload, btnRun, btnClear; |
10 | static S submittedInput; |
11 | //static JCheckBox cbAll; |
12 | static TrayIcon trayIcon; |
13 | static volatile boolean searching; |
14 | static long lastSearch; // time of last search |
15 | |
16 | static S menuSnippet = "#1000880"; |
17 | static S menuScript; |
18 | |
19 | static int searchDelay = 100; |
20 | static int maxResults = 100; |
21 | static int autoResearchInterval = 30000; // 30 secs |
22 | static boolean useFastNohup = true; // use pre-spun VMs if available |
23 | |
24 | static L<S> actionHistory = synchroList(); |
25 | |
26 | !include #1000839 // PopupMenuHelper |
27 | |
28 | p {
|
29 | becomeBotVMIfFirst(); |
30 | |
31 | S title = "JavaX Starter"; |
32 | makeAndroid3(title + "."); |
33 | try {
|
34 | frame = new JFrame(title); |
35 | } catch (HeadlessException e) {
|
36 | System.out.println("We're headless...");
|
37 | return; |
38 | } |
39 | |
40 | setFrameIconLater(frame, "#1003596"); |
41 | |
42 | list = new JList(); |
43 | |
44 | new PopupMenuHelper() {
|
45 | void fillMenu() {
|
46 | try {
|
47 | if (menuScript == null) |
48 | menuScript = loadSnippet(menuSnippet); |
49 | |
50 | JMenuItem mi; |
51 | int idx = list.locationToIndex(point); |
52 | final String item = cast list.getModel().getElementAt(idx); |
53 | list.setSelectedIndex(idx); |
54 | |
55 | L<S> tok = javaTok(menuScript); |
56 | for (int i = 1; i+4 < tok.size(); i += 2) |
57 | if (tok.get(i+2).equals("=")) {
|
58 | final S snip = unquote(tok.get(i+4)); |
59 | S text = unquote(tok.get(i)); |
60 | mi = new JMenuItem(text); |
61 | mi.addActionListener(actionListener {
|
62 | runCustom(snip, item); |
63 | }); |
64 | menu.add(mi); |
65 | } |
66 | } catch (Throwable e) {
|
67 | popup(e); |
68 | } |
69 | } |
70 | }.install(list); |
71 | |
72 | // install double click listener on list |
73 | list.addMouseListener(new MouseAdapter() {
|
74 | public void mouseClicked(MouseEvent evt) {
|
75 | if (evt.getClickCount() == 2) {
|
76 | int idx = list.locationToIndex(evt.getPoint()); |
77 | final String item = cast list.getModel().getElementAt(idx); |
78 | list.setSelectedIndex(idx); |
79 | runCustom("", item);
|
80 | } |
81 | } |
82 | }); |
83 | |
84 | // install enter key listener on list |
85 | |
86 | list.addKeyListener(new KeyAdapter() {
|
87 | public void keyReleased(KeyEvent ke) {
|
88 | if (ke.getKeyCode() == KeyEvent.VK_ENTER) {
|
89 | run(); |
90 | } |
91 | } |
92 | }); |
93 | |
94 | ActionListener go = actionListener {
|
95 | tfCmd.selectAll(); |
96 | search(true); |
97 | }; |
98 | |
99 | btnReload = new JButton(isWindows() ? "Reload" : "\u27F3"); |
100 | btnReload.addActionListener(go); |
101 | |
102 | btnClear = new JButton("X");
|
103 | btnClear.setToolTipText("Show latest");
|
104 | btnClear.addActionListener(actionListener { tfCmd.setText(""); });
|
105 | |
106 | tfCmd = new JTextField; |
107 | |
108 | /*cbAll = new JCheckBox("Runnables", true);
|
109 | cbAll.setToolTipText("Show only runnable programs (not random text snippets)");
|
110 | cbAll.addActionListener(go);*/ |
111 | |
112 | JPanel controls = new JPanel(new FlowLayout); |
113 | //controls.add(cbAll); |
114 | controls.add(btnReload); |
115 | controls.add(btnClear); |
116 | |
117 | JPanel north = new JPanel(new BorderLayout); |
118 | north.add(BorderLayout.CENTER, withLabel("Search term:", tfCmd));
|
119 | north.add(BorderLayout.EAST, controls); |
120 | |
121 | btnRun = new JButton("Run");
|
122 | btnRun.addActionListener(actionListener {
|
123 | run(); |
124 | }); |
125 | |
126 | status = new JLabel(" ");
|
127 | JPanel panel = northCenterAndSouth(north, list, |
128 | centerAndEast(status, btnRun)); |
129 | |
130 | tfCmd.addActionListener(go); |
131 | |
132 | frame.addWindowListener(new WindowAdapter() {
|
133 | public void windowOpened(WindowEvent e) {
|
134 | tfCmd.requestFocus(); |
135 | } |
136 | |
137 | public void windowClosing(WindowEvent e) {
|
138 | frame.setVisible(false); |
139 | } |
140 | |
141 | public void windowActivated(WindowEvent e) {
|
142 | search(false); |
143 | } |
144 | }); |
145 | |
146 | installTimer(tfCmd, new Runnable() {
|
147 | String lastContents; |
148 | boolean autoSearchOn = true; |
149 | |
150 | public void run() {
|
151 | String text = getInput(); |
152 | if (text.equals(lastContents)) {
|
153 | if (now() > lastSearch + autoResearchInterval || |
154 | (!text.equals(submittedInput) && autoSearchOn && !searching)) |
155 | search(false); |
156 | } else |
157 | lastContents = text; |
158 | } |
159 | }, searchDelay); |
160 | |
161 | frame.add(panel); |
162 | frame.setBounds(100, 100, 500, 400); |
163 | frame.setVisible(true); |
164 | frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); |
165 | //exitOnFrameClose(frame); |
166 | hideFrameOnMinimize(frame); |
167 | |
168 | trayIcon = installTrayIcon("JavaX!", "#1003596", popupItems());
|
169 | |
170 | thread "Updating Menu every 10 minutes" {
|
171 | sleepMinutes(10); |
172 | while (licensed()) {
|
173 | pcall {
|
174 | print("Updating menu.");
|
175 | trayIcon.setPopupMenu(makePopupMenu(popupItems())); |
176 | } |
177 | sleepMinutes(10); |
178 | } |
179 | } |
180 | |
181 | hideConsole(); |
182 | |
183 | search(false); |
184 | } |
185 | |
186 | static O[] popupItems() {
|
187 | new L topTenItems; |
188 | pcall {
|
189 | L<S> calls = programTopTenWithArgs().getTopTen(); |
190 | new Set<S> ids; |
191 | for (S s : calls) |
192 | ids.add(onlyUntilSpace(s)); |
193 | Map<S, S> titles = getSnippetTitles(asList(ids)); |
194 | |
195 | for (final S call : calls) {
|
196 | S id = onlyUntilSpace(call); |
197 | topTenItems.add(menuItem(id + " [" + lookupSnippetID(titles, id) + "]" + (eq(id, call) ? "" : " " + trim(dropPrefix(id, call))), |
198 | r { runCmd(call); }));
|
199 | } |
200 | } |
201 | |
202 | ret flattenArray( |
203 | r { bringUpFrame(); }, // on left click
|
204 | toObjectArray(topTenItems), |
205 | "***", |
206 | menuItem("Show Runner", r { bringUpFrame(); }),
|
207 | menuItem("Show Console", r { showConsole(); }),
|
208 | menuItem("Restart Runner", r { restart(); }),
|
209 | //menuItem("Hide Console", r { hideConsole(); }),
|
210 | menuItem("Exit", r { System.exit(0); }));
|
211 | } |
212 | |
213 | static S getInput() {
|
214 | ret tfCmd.getText().trim(); |
215 | } |
216 | |
217 | static void search(String cmd, final boolean requestFocus) ctex {
|
218 | searching = true; |
219 | try {
|
220 | status("Searching " + quote(cmd) + "...");
|
221 | if (empty(cmd)) cmd = "_"; |
222 | //if (cbAll.isSelected()) |
223 | cmd += " type:runnable"; |
224 | S page = loadPage("http://tinybrain.de:8080/tb/search.php?q=" + urlencode(cmd) + "&limit=" + maxResults + "&sort=modified");
|
225 | Matcher m = Pattern.compile(">(#\\d+)</a> - (.*?)<br>").matcher(page);
|
226 | |
227 | final new DefaultListModel model; |
228 | while (m.find()) {
|
229 | String title = m.group(2); |
230 | title = join(dropAllTags(htmlcoarsetok(title))); |
231 | model.addElement(htmldecode(m.group(1) + " - " + title)); |
232 | } |
233 | |
234 | awt {
|
235 | list.setModel(model); |
236 | status("Found " + model.size() + (model.size() == maxResults ? "+" : "") + (true/*cbAll.isSelected()*/ ? " runnable(s)." : " snippet(s)."));
|
237 | if (requestFocus) |
238 | tfCmd.requestFocus(); |
239 | } |
240 | } finally {
|
241 | searching = false; |
242 | } |
243 | } |
244 | |
245 | static void status(final S s) {
|
246 | awt { status.setText(s); }
|
247 | } |
248 | |
249 | static void runCmd(final S cmd) {
|
250 | print("Running " + cmd);
|
251 | S msg = format3("*: Running *", now(), cmd);
|
252 | actionHistory.add(msg); |
253 | logQuoted("run.log", msg);
|
254 | |
255 | thread { // new thread so we can see progress messages, e.g. for loading the JavaX jar
|
256 | if (useFastNohup) |
257 | fastNohupJavax(cmd); |
258 | else |
259 | nohupJavax(cmd); |
260 | } |
261 | } |
262 | |
263 | static void runCustom(S worker, S item) {
|
264 | if (item == null) ret; |
265 | int i = item.indexOf(' ');
|
266 | if (i >= 0) item = item.substring(0, i); |
267 | long id = parseSnippetID(item); |
268 | runCmd(worker + " " + id); |
269 | } |
270 | |
271 | static void runWithArguments(S item) {
|
272 | // TODO: run a dialog for that |
273 | } |
274 | |
275 | static void search(final boolean requestFocus) {
|
276 | submittedInput = getInput(); |
277 | lastSearch = now(); |
278 | final String cmd = submittedInput; |
279 | actionHistory.add(format3("*: Searching *", now(), cmd));
|
280 | thread {
|
281 | search(cmd, requestFocus); |
282 | } |
283 | } |
284 | |
285 | answer {
|
286 | if "very quick java *" |
287 | ret format("ok *", structure(callCalc(veryQuickJava(m.unq(0)))));
|
288 | } |
289 | |
290 | static void run() {
|
291 | S item = cast list.getModel().getElementAt(list.getSelectedIndex()); |
292 | runCustom("", item);
|
293 | } |
294 | |
295 | static void bringUpFrame() {
|
296 | makeFrameVisible(frame); |
297 | } |
Began life as a copy of #1000825
download show line numbers debug dex old transpilations
Travelled to 14 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1003873 |
| Snippet name: | Test New #759 (with JavaX Starter) |
| Eternal ID of this version: | #1003873/1 |
| Text MD5: | 82f43baf6f53c7be32ee9a26e5d083df |
| Transpilation MD5: | f13db804c536b3d74928b2219531a47f |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX source code |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2016-07-29 15:31:54 |
| Source code size: | 8087 bytes / 297 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 699 / 803 |
| Referenced in: | [show references] |