// The Runner! !7 static JFrame frame; static JList list; static JTextField tfCmd; static JLabel status; static JButton btnReload, btnRun, btnClear; static S submittedInput; static JCheckBox cbPrograms; static TrayIcon trayIcon; static volatile boolean searching; static long lastSearch; // time of last search static bool first; // first of its kind static JTable lastRunTable; static ReliableSingleThread thread_lastRun; static S menuSnippet = "#1000880"; static S menuScript; static int searchDelay = 100; static int maxResults = 100; static int autoResearchInterval = 30000; // 30 secs static int topTenLookBack = 100; // look at last 100 program runs static L actionHistory = synchroList(); !include #1001372 // direct nohupJavax p { try { new JFrame().dispose(); } catch { System.out.println("We're headless..."); // TODO: Something useful. System.exit(0); } awt { awtMain(); } } svoid awtMain { becomeBotVMIfFirst(); //mistAqua(); //magellan(); //gemini(); //emeraldDusk(); //mistSilver(); //substanceLAF("Raven"); //substanceLAF("OfficeSilver2007"); //substanceLAF("OfficeBlue2007"); //substanceLAF("OfficeBlack2007"); substanceLAF("Sahara"); first = empty(sendToAll("JavaX Starter.", "activate")); frame = showFrame(); moveFrameAround(frame); updateTitle(); makeAndroid3("JavaX Starter."); setFrameIconLater(frame, "#1003596"); // Show the rays disposeWindowOnClick(showAnimation("#1003828", 3.5)); list = new JList; new PopupMenuHelper { void fillMenu() { try { if (menuScript == null) menuScript = loadSnippet(menuSnippet); JMenuItem mi; int idx = list.locationToIndex(point); final String item = cast list.getModel().getElementAt(idx); list.setSelectedIndex(idx); L tok = javaTok(menuScript); for (int i = 1; i+6 < tok.size(); i += 2) if (tok.get(i+2).equals("=") && tok.get(i+4).equals("#")) { final S snip = unquote(tok.get(i+6)); S text = unquote(tok.get(i)); mi = new JMenuItem(text); mi.addActionListener(actionListener { runCustom(snip, item); }); menu.add(mi); } } catch (Throwable e) { popup(e); } } }.install(list); // install double click listener on list onDoubleClick(list, voidfunc(S item) { if (nempty(item)) runCustom("", item); }); // install enter key listener on list onEnter(list, f runSelected); ActionListener go = actionListener { tfCmd.selectAll(); search(true); }; btnReload = new JButton(isWindows() ? "Reload" : "\u27F3"); btnReload.setToolTipText("Search again (if our " + autoResearchInterval/1000 + "s update interval is not enough for you)"); btnReload.addActionListener(go); btnClear = new JButton("X"); btnClear.setToolTipText("Show latest"); btnClear.addActionListener(actionListener { tfCmd.setText(""); }); tfCmd = new JTextField; cbPrograms = new JCheckBox("Programs", true); cbPrograms.setToolTipText("Show only runnable programs (not random text snippets)"); cbPrograms.addActionListener(go); JPanel controls = jflow(btnClear, cbPrograms, btnReload); JPanel north = centerAndEast( withLabel("Search term:", tfCmd), controls); btnRun = jbutton("Run", r { main.runSelected() }); listDependButton(list, btnRun); status = new JLabel(" "); JPanel searchPanel = northCenterAndSouth(north, list, centerAndEast(status, btnRun)); tfCmd.addActionListener(go); frame.addWindowListener(new WindowAdapter() { public void windowOpened(WindowEvent e) { tfCmd.requestFocus(); } public void windowClosing(WindowEvent e) { frame.setVisible(false); } public void windowActivated(WindowEvent e) { search(false); } }); installTimer(tfCmd, new Runnable() { String lastContents; boolean autoSearchOn = true; public void run() { updateTitle(); String text = getInput(); if (text.equals(lastContents)) { if ( isFocusedWindow(frame) && now() > lastSearch + autoResearchInterval || (!text.equals(submittedInput) && autoSearchOn && !searching)) search(false); } else lastContents = text; } }, searchDelay); lastRunTable = sexyTableWithoutDrag(); onDoubleClickOrEnter(lastRunTable, voidfunc(Int row) { Map map = getTableLineAsMap(lastRunTable, row); S id = getString(map, "Program ID"); S args = getString(map, "Arguments"); runCustom("", id + " " + args); }); thread_lastRun = new ReliableSingleThread(f updateLastRun); thread_lastRun.go(); JTable injectionsTable = jInjectionsTable(); frame.add(jRightTabs("Search", searchPanel, "Last Run Programs", tableWithSearcher(lastRunTable), "Running", injectionsTable)); frame.setBounds(100, 100, 500, 400); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); hideFrameOnMinimize(frame); addMenu(frame, "Starter", "Show Talk Program [Eleutheria]", r { talkProgram() }, "Your Computer ID: " + computerID(), r {}, "Update JavaX", r { nohupJavax(#1001639) }, "Log in", r { nohupJavax(#1000896) }, "Exit", r { cleanKill() }); thread { addAISuiteMenu(frame, "AI"); } if (first) trayIcon = installTrayIcon("JavaX!", "#1003596", popupItems()); thread "Updating Menu every 10 minutes" { sleepMinutes(10); while (licensed()) { pcall { print("Updating menu."); updateMenu(); } sleepMinutes(10); } } if (myVMPort() == 5000) if (isStefansPC()) // isMultiCore() thread "Warming Up Java" { loading "Warming Up Java" { warmUpJavaCompiler(20); } } hideConsole(); thread "Start Bots" { startInternetTrafficCountBot(); startVMLister_onChange = r { int hidden = startVMLister_numHiddenVMs(); trayIcon.setToolTip("JavaX: " + n(startVMLister_numVMs(), "VM") + (hidden == 0 ? "" : " (" + hidden + " hidden)")); }; if (startVMLister()) doEvery(60000, f startVMLister_scan); startBotHere("Compiler Bot", #1007916); // TODO: restart these bots if multiple runners are started // and exited in unfortunate order } search(false); } svoid updateTitle { S title = "JavaX Starter v3"; if (isOfflineMode()) title += " [OFFLINE MODE]"; setFrameTitle(frame, title); } svoid updateMenu { updateTitle(); trayIcon.setPopupMenu(makePopupMenu(dropFirst(popupItems()))); } static O[] popupItems() { new L topTenItems; pcall { L calls = programTopTenWithArgs(topTenLookBack).getTopTen(); new HashSet ids; for (S s : calls) ids.add(onlyUntilSpace(s)); Map titles = getSnippetTitles(asList(ids)); for (final S call : calls) { S id = onlyUntilSpace(call); topTenItems.add(menuItem(id + " [" + lookupSnippetID(titles, id) + "]" + (eq(id, call) ? "" : " " + trim(dropPrefix(id, call))), r { runProgram(call); })); } } ret flattenArray( r { bringUpFrame(); }, // on left click toObjectArray(topTenItems), "***", menuItem("Show Runner", r { bringUpFrame(); }), menuItem("Show Console", r { showConsole(); }), menuItem("Restart Runner", r { restart(); }), menuItem("Show Talk Program [Eleutheria]", r { talkProgram(); }), //menuItem("Hide Console", r { hideConsole(); }), isOfflineMode() ? menuItem("Switch to online mode", r { goOnlineMode(); updateMenu(); }) : menuItem("Switch to offline mode", r { goOfflineMode(); updateMenu(); }), menuItem("Update JavaX", r { nohupJavax(#1001639) }), menuItem("Exit", r { System.exit(0); })); } static S getInput() { ret tfCmd.getText().trim(); } static void search(String cmd, final boolean requestFocus) ctex { searching = true; try { status("Searching " + quote(cmd) + "..."); if (empty(cmd)) cmd = "_"; if (cbPrograms.isSelected()) cmd += " type:runnable-desktop"; L snippets = tbSearch_url(tb_mainServer() + "/tb/search.php?q=" + urlencode(cmd) + "&limit=" + maxResults + "&sort=modified&quick=1" + standardCredentials()); final new DefaultListModel model; for (Snippet s : snippets) model.addElement(fsI(s.id) + " - " + s.title); awt { list.setModel(model); status("Found " + model.size() + (model.size() == maxResults ? "+" : "") + (cbPrograms.isSelected() ? " runnable(s)." : " snippet(s).")); if (requestFocus) tfCmd.requestFocus(); } } finally { searching = false; } } static void status(final S s) { awt { status.setText(s); } } static void runProgram(final S cmd) { print("Running " + cmd); S msg = format3("*: Running *", now(), cmd); actionHistory.add(msg); logQuoted("run.log", msg); awtLater(1000, r { thread_lastRun.go() }); thread { // new thread so we can see progress messages, e.g. for loading the JavaX jar nohupJavax(cmd); } } static void runHotwired(final S worker, final long id) { print("Hotwiring " + worker + " on " + id); S msg = format3("*: Hotwiring * on *", now(), worker, id); actionHistory.add(msg); logQuoted("run.log", msg); thread { _run(worker, new S[] {str(id)}); // TODO: cache code? } } static void runCustom(S worker, S item) { if (item == null) ret; int i = item.indexOf(' '); if (i >= 0) item = item.substring(0, i); long id = parseSnippetID(item); print("runCustom: " + id + " [" + worker + "]"); if (empty(worker)) runProgram(str(id)); else runHotwired(worker, id); } static void runWithArguments(S item) { // TODO: run a dialog for that } static void search(final boolean requestFocus) { submittedInput = getInput(); lastSearch = now(); final String cmd = submittedInput; actionHistory.add(format3("*: Searching *", now(), cmd)); thread { search(cmd, requestFocus); } } answer { if "very quick java *" ret format("ok *", structure(callCalc(veryQuickJava(m.unq(0))))); if "restart" { restart(); ret "OK"; } if "activate" { activateFrame(frame); ret "OK"; } } static void runSelected() { S item = cast list.getModel().getElementAt(list.getSelectedIndex()); runCustom("", item); } static void bringUpFrame() { makeFrameVisible(frame); } svoid updateLastRun { print("Updating last run list..."); new L l; for (S s : uniquifyList(reversedList(scanRunLog(programID())))) { S progID = s; int i = s.indexOf(' '); if (i >= 0) { progID = substring(s, 0, i); s = trim(substring(s, i+1)); } else s = ""; // no arguments //S title = getSnippetTitle_cached(progID); l.add(litorderedmap("Program ID" := fsI(progID), "Title" := "?", "Arguments" := s)); } addProgramTitles(l); dataToTable_uneditable(l, lastRunTable); } // TODO: cache them more? svoid addProgramTitles(L l) { new HashSet needed; for (Map m : l) { if (eq(m.get("Title"), "?")) { S id = getString(m, "Program ID"); S title = getSnippetTitle_cached_probe(id); if (title != null) m.put("Title", title); else needed.add(id); } } //print("Need " + n(needed, "snippet title") + ": " + struct(needed)); if (empty(needed)) ret; getSnippetTitles_verbose = true; SS titles = getSnippetTitles(needed); print("Done!"); for (Map m : l) { S id = getString(m, "Program ID"); if (eq(m.get("Title"), "?") && titles.containsKey(id)) { S title = titles.get(id); getSnippetTitle_cached_put(id, title); m.put("Title", title); } } }