sclass TableSearcher { JTable table; JTextField tfInput; JComponent searchPanel, panel; F2 rowTester; L rowIndices; S input() { ret gtt(tfInput); } } static TableSearcher tableWithSearcher2(final JTable t, O... _) { final new TableSearcher s; final bool precise = true; s.table = t; s.tfInput = jtextfield(); s.rowTester = func(S pat, Map row) -> bool { anyValueContainsIgnoreCase(row, pat) }; onUpdate(s.tfInput, new Runnable { L lastFiltered, lastOriginal; public void run() { S pat = s.input(); L> data = rawTableData(t); if (eq(lastFiltered, data)) data = lastOriginal; //print("Searching " + n(l(data), "entry")); new L data2; new L rowIndices; for i over data: { Map map = data.get(i); if (isTrue(callF(s.rowTester, pat, map))) { data2.add(map); rowIndices.add(i); } } //print("Found " + n(l(data2), "entry")); lastFiltered = data2; lastOriginal = data; dataToTable(t, data2); if (precise) lastFiltered = rawTableData(t); s.rowIndices = rowIndices; } }); s.searchPanel = withLabel("Search:", s.tfInput); JComponent top = s.searchPanel; s.panel = boolOptPar(_, 'withMargin) ? northAndCenterWithMargin(top, t) : northAndCenter(top, t); ret s; }