diff --git a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java index 2d540ec90..9a3646610 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java @@ -53,7 +53,6 @@ import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rtextarea.SearchContext; import org.fife.ui.rtextarea.SearchEngine; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -246,7 +245,7 @@ public abstract class CommonSearchDialog extends JDialog { column.setPreferredWidth(colWidth); } if (codeComp != null) { - setRowHeight(codeComp.getPreferredSize().height + 4); + setRowHeight(Math.max(20, codeComp.getPreferredSize().height + 4)); } updateUI(); } @@ -320,6 +319,8 @@ public abstract class CommonSearchDialog extends JDialog { private final Color selectedForeground; private final Color foreground; + private final JLabel emptyLabel = new JLabel(); + private Map componentCache = new HashMap(); public ResultsTableCellRenderer() { @@ -332,15 +333,17 @@ public abstract class CommonSearchDialog extends JDialog { @Override public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) { - int id = (row << 2) | column; + int id = row << 2 | column; Component comp = componentCache.get(id); - if (comp == null && (obj instanceof JNode)) { - comp = makeCell((JNode) obj, column); - componentCache.put(id, comp); - } - if (comp != null) { - updateSelection(comp, isSelected); + if (comp == null) { + if (obj instanceof JNode) { + comp = makeCell((JNode) obj, column); + componentCache.put(id, comp); + } else { + comp = emptyLabel; + } } + updateSelection(comp, isSelected); return comp; } @@ -354,31 +357,30 @@ public abstract class CommonSearchDialog extends JDialog { } } - @Nullable - protected Component makeCell(JNode node, int column) { + private Component makeCell(JNode node, int column) { if (column == 0) { JLabel label = new JLabel(node.makeLongString() + " ", node.getIcon(), SwingConstants.LEFT); label.setOpaque(true); label.setToolTipText(label.getText()); return label; } - if (node.hasDescString()) { - RSyntaxTextArea textArea = new RSyntaxTextArea(); - textArea.setFont(codeFont); - textArea.setEditable(false); - textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); - textArea.setText(" " + node.makeDescString()); - textArea.setRows(1); - textArea.setColumns(textArea.getText().length()); - if (highlightText != null) { - SearchContext searchContext = new SearchContext(highlightText); - searchContext.setMatchCase(true); - searchContext.setMarkAll(true); - SearchEngine.markAll(textArea, searchContext); - } - return textArea; + if (!node.hasDescString()) { + return emptyLabel; } - return null; + RSyntaxTextArea textArea = new RSyntaxTextArea(); + textArea.setFont(codeFont); + textArea.setEditable(false); + textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA); + textArea.setText(" " + node.makeDescString()); + textArea.setRows(1); + textArea.setColumns(textArea.getText().length()); + if (highlightText != null) { + SearchContext searchContext = new SearchContext(highlightText); + searchContext.setMatchCase(true); + searchContext.setMarkAll(true); + SearchEngine.markAll(textArea, searchContext); + } + return textArea; } public void clear() { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java index 1f25e9f58..2751c0e35 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java @@ -1,8 +1,8 @@ package jadx.gui.ui; import jadx.gui.utils.NLS; -import jadx.gui.utils.search.TextSearchIndex; import jadx.gui.utils.TextStandardActions; +import jadx.gui.utils.search.TextSearchIndex; import javax.swing.BorderFactory; import javax.swing.Box; @@ -12,6 +12,7 @@ import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingUtilities; +import javax.swing.Timer; import javax.swing.WindowConstants; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -19,6 +20,8 @@ import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyAdapter; @@ -105,18 +108,35 @@ public class SearchDialog extends CommonSearchDialog { highlightText = text; resultsTable.updateTable(); } - private class SearchFieldListener implements DocumentListener { + + private class SearchFieldListener implements DocumentListener, ActionListener { + + private Timer timer; + + private synchronized void change() { + if (timer != null) { + timer.restart(); + } else { + timer = new Timer(300, this); + timer.start(); + } + } + + @Override + public void actionPerformed(ActionEvent e) { + performSearch(); + } public void changedUpdate(DocumentEvent e) { - performSearch(); + change(); } public void removeUpdate(DocumentEvent e) { - performSearch(); + change(); } public void insertUpdate(DocumentEvent e) { - performSearch(); + change(); } }