Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

402
LINES

< > TinyBrain | #1000825 - JavaX Starter - Runnables search, v3 (CURRENT)

JavaX source code (desktop) [tags: use-pretranspiled] - run with: x30.jar - homepage

Uses 1937K of libraries. Click here for Pure Java version (10586L/79K).

// 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 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 boolean useFastNohup = true; // use pre-spun VMs if available
static int topTenLookBack = 100; // look at last 100 program runs

static L<S> actionHistory = synchroList();

p-awt {
  becomeBotVMIfFirst();
  //mistAqua();
  //magellan();
  //gemini();
  //emeraldDusk();
  //mistSilver();
  //substanceLAF("Raven");
  //substanceLAF("OfficeSilver2007");
  //substanceLAF("OfficeBlue2007");
  //substanceLAF("OfficeBlack2007");
  substanceLAF("Sahara");
  
  try {
    frame = showFrame();
  } catch (HeadlessException e) {
    System.out.println("We're headless...");
    // TODO: Something useful.
    System.exit(0);
  }
  
  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<S> 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 = sexyTable();
  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) });
    
  addAISuiteMenu(frame, "AI");
  
  trayIcon = installTrayIcon("JavaX!", "#1003596", popupItems());
  
  thread "Updating Menu every 10 minutes" {
    sleepMinutes(10);
    while (licensed()) {
      pcall {
        print("Updating menu.");
        updateMenu();
      }
      sleepMinutes(10);
    }
  }
  
  hideConsole();
  
  thread "Start Compiler Bot" {
    startBotHere("Compiler Bot", #1007916);
  }
  
  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<S> calls = programTopTenWithArgs(topTenLookBack).getTopTen();
    new HashSet<S> ids;
    for (S s : calls)
      ids.add(onlyUntilSpace(s));
    Map<S, S> 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("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";
    S page = loadPage("http://tinybrain.de:8080/tb/search.php?q=" + urlencode(cmd) + "&limit=" + maxResults + "&sort=modified&quick=1" + standardCredentials());
    Matcher m = Pattern.compile(">(#\\d+)</a> - (.*?)<br>").matcher(page);
    
    final new DefaultListModel model;
    while (m.find()) {
      String title = m.group(2);
      title = join(dropAllTags(htmlcoarsetok(title)));
      model.addElement(htmldecode(m.group(1) + " - " + 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
    if (useFastNohup)
      fastNohupJavax(cmd);
    else
      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)))));
}

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<Map> 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);
}

svoid addProgramTitles(L<Map> l) {
  new HashSet<S> 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 titles") + ": " + 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);
    }
  }
}

Author comment

Began life as a copy of #1000794

download  show line numbers  debug dex   

Travelled to 43 computer(s): acumhimkfssw, afvcxyesxakz, agxbjmyenqqu, ajlfxifxfcul, bkpbhqsukdzp, cfunsshuasjs, ddnzoavkxhuk, dhtvkmknsjym, dyfxnkwhunql, etmzoiygucik, gwrvuhgaqvyk, ishmyahliavo, jlatgrcjtklg, jtubtzbbkimh, liwcxgsjrgqn, lulzaavyztxj, meaugxdlecrj, nbgitpuheiab, ngbrtomqtpjn, nysugtttblhj, omkuifhlbvuf, omzkqqnokwlv, onfqjnomoxuw, onxytkatvevr, picgnzycjide, qjimsvlqbazf, rcljlypqyydo, rsdhgwlghzqg, sawdedvomwva, sdspifkayxrz, teubizvjbppd, tvejysmllsmz, uwnvikuolobj, vaduqbtgckcl, vqftxbmjmmzu, vzpxdoxhqfnw, wglhsqxgxbdq, wltunwwkxhxr, wtqryiryparv, xhsrmoityime, xinetxnxrdbb, xprdwmaupziu, ychswryhhvyu

No comments. add comment

Snippet ID: #1000825
Snippet name: JavaX Starter - Runnables search, v3 (CURRENT)
Eternal ID of this version: #1000825/17
Text MD5: 995ca985c7c6d5e64a4f2582b59a2d5c
Transpilation MD5: ad2f16aea5cfc70fc9d61e8c5cec4106
Author: stefan
Category: javax
Type: JavaX source code (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2017-04-23 15:22:50
Source code size: 11430 bytes / 402 lines
Pitched / IR pitched: No / No
Views / Downloads: 759 / 18078
Version history: 16 change(s)
Referenced in: [show]