Package jadx.gui.ui

Source Code of jadx.gui.ui.SearchDialog$ResultsModel

package jadx.gui.ui;

import jadx.api.JavaClass;
import jadx.api.JavaField;
import jadx.api.JavaMethod;
import jadx.api.JavaNode;
import jadx.gui.JadxWrapper;
import jadx.gui.treemodel.JNode;
import jadx.gui.utils.NLS;
import jadx.gui.utils.NameIndex;
import jadx.gui.utils.Position;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

public class SearchDialog extends JDialog {
  private static final long serialVersionUID = -5105405456969134105L;

  private static final int MAX_RESULTS_COUNT = 100;

  private static enum SearchOptions {
    CLASS,
    METHOD,
    FIELD,
    CODE
  }

  private static final Set<SearchOptions> OPTIONS =
      EnumSet.of(SearchOptions.CLASS, SearchOptions.METHOD, SearchOptions.FIELD);

  private final TabbedPane tabbedPane;
  private final JadxWrapper wrapper;
  private NameIndex<JavaNode> index;

  private JTextField searchField;
  private ResultsModel resultsModel;
  private JList resultsList;
  private JProgressBar busyBar;

  public SearchDialog(Frame owner, TabbedPane tabbedPane, JadxWrapper wrapper) {
    super(owner);
    this.tabbedPane = tabbedPane;
    this.wrapper = wrapper;

    initUI();
  }

  public void prepare() {
    LoadTask task = new LoadTask();
    task.init();
    task.execute();
  }

  private void loadData() {
    index = new NameIndex<JavaNode>();
    for (JavaClass cls : wrapper.getClasses()) {
      indexClass(cls);
    }
  }

  private synchronized void performSearch() {
    String text = searchField.getText();
    List<JavaNode> results;
    if (text == null || text.isEmpty() || index == null) {
      results = Collections.emptyList();
    } else {
      results = index.search(text);
    }
    resultsModel.setResults(results);
  }

  private void openSelectedItem() {
    int selectedId = resultsList.getSelectedIndex();
    if (selectedId == -1) {
      return;
    }
    JNode node = (JNode) resultsModel.get(selectedId);
    tabbedPane.showCode(new Position(node.getRootClass(), node.getLine()));

    dispose();
  }

  private void indexClass(JavaClass cls) {
    if (OPTIONS.contains(SearchOptions.CLASS)) {
      index.add(cls.getFullName(), cls);
    }
    if (OPTIONS.contains(SearchOptions.METHOD)) {
      for (JavaMethod mth : cls.getMethods()) {
        index.add(mth.getFullName(), mth);
      }
    }
    if (OPTIONS.contains(SearchOptions.FIELD)) {
      for (JavaField fld : cls.getFields()) {
        index.add(fld.getFullName(), fld);
      }
    }
    if (OPTIONS.contains(SearchOptions.CODE)) {
      String code = cls.getCode();
      index.add(code, cls);
    }
    for (JavaClass innerCls : cls.getInnerClasses()) {
      indexClass(innerCls);
    }
  }

  private class LoadTask extends SwingWorker<Void, Void> {
    public void init() {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          busyBar.setVisible(true);
          searchField.setEnabled(false);
          resultsList.setEnabled(false);
          setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        }
      });
    }

    @Override
    public Void doInBackground() {
      loadData();
      return null;
    }

    @Override
    public void done() {
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          setCursor(null);
          searchField.setEnabled(true);
          resultsList.setEnabled(true);
          busyBar.setVisible(false);
        }
      });
    }
  }

  private static class ResultsModel extends DefaultListModel {
    private static final long serialVersionUID = -7821286846923903208L;

    private void setResults(List<JavaNode> results) {
      removeAllElements();
      if (results.isEmpty()) {
        return;
      }
      int count = Math.min(results.size(), MAX_RESULTS_COUNT);
      for (int i = 0; i < count; i++) {
        addElement(JNode.makeFrom(results.get(i)));
      }
    }
  }

  private static class ResultsCellRenderer implements ListCellRenderer {
    private final Color selectedBackground;
    private final Color selectedForeground;

    ResultsCellRenderer() {
      UIDefaults defaults = UIManager.getDefaults();
      selectedBackground = defaults.getColor("List.selectionBackground");
      selectedForeground = defaults.getColor("List.selectionForeground");
    }

    @Override
    public Component getListCellRendererComponent(JList list,
                                                  Object obj, int index, boolean isSelected, boolean cellHasFocus) {
      if (!(obj instanceof JNode)) {
        return null;
      }
      JNode value = (JNode) obj;
      JLabel label = new JLabel();
      label.setOpaque(true);
      label.setIcon(value.getIcon());
      label.setText(value.makeLongString());
      if (isSelected) {
        label.setBackground(selectedBackground);
        label.setForeground(selectedForeground);
      }
      return label;
    }
  }

  private class SearchFieldListener implements DocumentListener {

    public void changedUpdate(DocumentEvent e) {
      performSearch();
    }

    public void removeUpdate(DocumentEvent e) {
      performSearch();
    }

    public void insertUpdate(DocumentEvent e) {
      performSearch();
    }
  }

  private void initUI() {
    JLabel findLabel = new JLabel(NLS.str("search_dialog.open_by_name"));

    searchField = new JTextField();
    searchField.setAlignmentX(LEFT_ALIGNMENT);
    searchField.getDocument().addDocumentListener(new SearchFieldListener());

    JCheckBox clsChBox = makeOptionsCheckBox(NLS.str("search_dialog.class"), SearchOptions.CLASS);
    JCheckBox mthChBox = makeOptionsCheckBox(NLS.str("search_dialog.method"), SearchOptions.METHOD);
    JCheckBox fldChBox = makeOptionsCheckBox(NLS.str("search_dialog.field"), SearchOptions.FIELD);
    JCheckBox codeChBox = makeOptionsCheckBox(NLS.str("search_dialog.code"), SearchOptions.CODE);
    codeChBox.setEnabled(false);

    resultsModel = new ResultsModel();
    resultsList = new JList(resultsModel);
    resultsList.setCellRenderer(new ResultsCellRenderer());
    resultsList.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent evt) {
        if (evt.getClickCount() == 2) {
          openSelectedItem();
        }
      }
    });

    JPanel searchOptions = new JPanel(new FlowLayout(FlowLayout.LEFT));
    searchOptions.setBorder(BorderFactory.createTitledBorder(NLS.str("search_dialog.search_in")));
    searchOptions.add(clsChBox);
    searchOptions.add(mthChBox);
    searchOptions.add(fldChBox);
    searchOptions.add(codeChBox);
    searchOptions.setAlignmentX(LEFT_ALIGNMENT);

    JPanel searchPane = new JPanel();
    searchPane.setLayout(new BoxLayout(searchPane, BoxLayout.PAGE_AXIS));
    findLabel.setLabelFor(searchField);
    searchPane.add(findLabel);
    searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
    searchPane.add(searchField);
    searchPane.add(Box.createRigidArea(new Dimension(0, 5)));
    searchPane.add(searchOptions);
    searchPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

    JPanel listPane = new JPanel();
    listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
    listPane.add(new JScrollPane(resultsList));
    listPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));

    busyBar = new JProgressBar();
    busyBar.setIndeterminate(true);
    busyBar.setVisible(false);

    //Create and initialize the buttons.
    JButton cancelButton = new JButton(NLS.str("search_dialog.cancel"));
    cancelButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        dispose();
      }
    });
    JButton openBtn = new JButton(NLS.str("search_dialog.open"));
    openBtn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        openSelectedItem();
      }
    });

    JPanel buttonPane = new JPanel();
    buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
    buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
    buttonPane.add(busyBar);
    searchPane.add(Box.createRigidArea(new Dimension(5, 0)));
    buttonPane.add(Box.createHorizontalGlue());
    buttonPane.add(openBtn);
    buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
    buttonPane.add(cancelButton);

    Container contentPane = getContentPane();
    contentPane.add(searchPane, BorderLayout.PAGE_START);
    contentPane.add(listPane, BorderLayout.CENTER);
    contentPane.add(buttonPane, BorderLayout.PAGE_END);
    getRootPane().setDefaultButton(openBtn);

    setTitle(NLS.str("menu.search"));
    pack();
    setSize(700, 500);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    setModalityType(ModalityType.APPLICATION_MODAL);
  }

  private JCheckBox makeOptionsCheckBox(String name, final SearchOptions opt) {
    JCheckBox chBox = new JCheckBox(name);
    chBox.setAlignmentX(LEFT_ALIGNMENT);
    chBox.setSelected(OPTIONS.contains(opt));
    chBox.addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
          OPTIONS.add(opt);
        } else {
          OPTIONS.remove(opt);
        }
        loadData();
        performSearch();
      }
    });
    return chBox;
  }
}
TOP

Related Classes of jadx.gui.ui.SearchDialog$ResultsModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.