Commit a2142b2f authored by Skylot's avatar Skylot

gui: add tabbed pane menu

parent 5ed5ec5f
...@@ -15,6 +15,8 @@ import org.fife.ui.rtextarea.RTextScrollPane; ...@@ -15,6 +15,8 @@ import org.fife.ui.rtextarea.RTextScrollPane;
class CodePanel extends JPanel { class CodePanel extends JPanel {
private static final long serialVersionUID = 5310536092010045565L;
private final TabbedPane codePanel; private final TabbedPane codePanel;
private final JClass jClass; private final JClass jClass;
private final SearchBar searchBar; private final SearchBar searchBar;
......
package jadx.gui.ui; package jadx.gui.ui;
import jadx.gui.treemodel.JClass; import jadx.gui.treemodel.JClass;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils; import jadx.gui.utils.Utils;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI; import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.Component; import java.awt.Component;
import java.awt.FlowLayout; import java.awt.FlowLayout;
...@@ -16,51 +20,98 @@ import java.awt.event.ActionEvent; ...@@ -16,51 +20,98 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.HashMap; import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
class TabbedPane extends JTabbedPane { class TabbedPane extends JTabbedPane {
private static final long serialVersionUID = -8833600618794570904L;
private static final ImageIcon ICON_CLOSE = Utils.openIcon("cross"); private static final ImageIcon ICON_CLOSE = Utils.openIcon("cross");
private static final ImageIcon ICON_CLOSE_INACTIVE = Utils.openIcon("cross_grayed"); private static final ImageIcon ICON_CLOSE_INACTIVE = Utils.openIcon("cross_grayed");
private final MainWindow mainWindow; private final MainWindow mainWindow;
private final Map<JClass, CodePanel> openTabs = new HashMap<JClass, CodePanel>(); private final Map<JClass, CodePanel> openTabs = new LinkedHashMap<JClass, CodePanel>();
TabbedPane(MainWindow window) { TabbedPane(MainWindow window) {
mainWindow = window; mainWindow = window;
setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
int direction = e.getWheelRotation();
int index = getSelectedIndex();
int maxIndex = getTabCount() - 1;
if ((index == 0 && direction < 0)
|| (index == maxIndex && direction > 0)) {
index = maxIndex - index;
} else {
index += direction;
}
setSelectedIndex(index);
}
});
}
MainWindow getMainWindow() {
return mainWindow;
}
void showCode(final JClass cls, final int line) {
final CodePanel codePanel = getCodePanel(cls);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setSelectedComponent(codePanel);
CodeArea codeArea = codePanel.getCodeArea();
codeArea.scrollToLine(line);
codeArea.requestFocus();
}
});
} }
private void addCodePanel(CodePanel codePanel) { private void addCodePanel(CodePanel codePanel) {
add(codePanel);
openTabs.put(codePanel.getCls(), codePanel); openTabs.put(codePanel.getCls(), codePanel);
add(codePanel);
} }
private void closeCodePanel(CodePanel codePanel) { private void closeCodePanel(CodePanel codePanel) {
remove(codePanel);
openTabs.remove(codePanel.getCls()); openTabs.remove(codePanel.getCls());
remove(codePanel);
} }
void showCode(JClass cls, int line) { private CodePanel getCodePanel(JClass cls) {
CodePanel panel = openTabs.get(cls); CodePanel panel = openTabs.get(cls);
if (panel == null) { if (panel == null) {
panel = new CodePanel(this, cls); panel = new CodePanel(this, cls);
addCodePanel(panel); addCodePanel(panel);
setTabComponentAt(indexOfComponent(panel), makeTabComponent(panel)); setTabComponentAt(indexOfComponent(panel), makeTabComponent(panel));
} }
return panel;
}
private CodePanel getCodePanel(int index) {
Component component = getComponent(index);
if (component instanceof CodePanel) {
return (CodePanel) component;
}
return null;
}
setSelectedComponent(panel); CodePanel getSelectedCodePanel() {
CodeArea codeArea = panel.getCodeArea(); return (CodePanel) getSelectedComponent();
codeArea.scrollToLine(line);
codeArea.requestFocus();
} }
private Component makeTabComponent(final CodePanel codePanel) { private Component makeTabComponent(final CodePanel codePanel) {
JClass cls = codePanel.getCls(); JClass cls = codePanel.getCls();
String name = cls.getCls().getFullName(); String name = cls.getCls().getFullName();
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 3, 0));
final JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 3, 0));
panel.setOpaque(false); panel.setOpaque(false);
final JLabel label = new JLabel(name); final JLabel label = new JLabel(name);
...@@ -87,8 +138,11 @@ class TabbedPane extends JTabbedPane { ...@@ -87,8 +138,11 @@ class TabbedPane extends JTabbedPane {
panel.addMouseListener(new MouseAdapter() { panel.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON2) { if (SwingUtilities.isMiddleMouseButton(e)) {
closeCodePanel(codePanel); closeCodePanel(codePanel);
} else if (SwingUtilities.isRightMouseButton(e)) {
JPopupMenu menu = createTabPopupMenu(codePanel);
menu.show(panel, e.getX(), e.getY());
} else { } else {
// TODO: make correct event delegation to tabbed pane // TODO: make correct event delegation to tabbed pane
setSelectedComponent(codePanel); setSelectedComponent(codePanel);
...@@ -102,11 +156,65 @@ class TabbedPane extends JTabbedPane { ...@@ -102,11 +156,65 @@ class TabbedPane extends JTabbedPane {
return panel; return panel;
} }
CodePanel getSelectedCodePanel() { private JPopupMenu createTabPopupMenu(final CodePanel codePanel) {
return (CodePanel) getSelectedComponent(); JPopupMenu menu = new JPopupMenu();
}
MainWindow getMainWindow() { JMenuItem closeTab = new JMenuItem(NLS.str("tabs.close"));
return mainWindow; closeTab.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
closeCodePanel(codePanel);
}
});
menu.add(closeTab);
if (openTabs.size() > 1) {
JMenuItem closeOther = new JMenuItem(NLS.str("tabs.closeOthers"));
closeOther.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
List<CodePanel> codePanels = new ArrayList<CodePanel>(openTabs.values());
for (CodePanel panel : codePanels) {
if (panel != codePanel) {
closeCodePanel(panel);
}
}
}
});
menu.add(closeOther);
JMenuItem closeAll = new JMenuItem(NLS.str("tabs.closeAll"));
closeAll.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
List<CodePanel> codePanels = new ArrayList<CodePanel>(openTabs.values());
for (CodePanel panel : codePanels) {
closeCodePanel(panel);
}
}
});
menu.add(closeAll);
menu.addSeparator();
CodePanel selectedCodePanel = getSelectedCodePanel();
for (final Map.Entry<JClass, CodePanel> entry : openTabs.entrySet()) {
final CodePanel cp = entry.getValue();
if (cp == selectedCodePanel) {
continue;
}
JClass jClass = entry.getKey();
final String clsName = jClass.getCls().getFullName();
JMenuItem item = new JMenuItem(clsName);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setSelectedComponent(cp);
}
});
item.setIcon(jClass.getIcon());
menu.add(item);
}
}
return menu;
} }
} }
...@@ -4,7 +4,7 @@ import jadx.core.dex.info.AccessInfo; ...@@ -4,7 +4,7 @@ import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.exceptions.JadxRuntimeException;
import javax.swing.AbstractAction; import javax.swing.Action;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JComponent; import javax.swing.JComponent;
...@@ -27,7 +27,7 @@ public class Utils { ...@@ -27,7 +27,7 @@ public class Utils {
return new ImageIcon(resource); return new ImageIcon(resource);
} }
public static void addKeyBinding(JComponent comp, KeyStroke key, String id, AbstractAction action) { public static void addKeyBinding(JComponent comp, KeyStroke key, String id, Action action) {
comp.getInputMap().put(key, id); comp.getInputMap().put(key, id);
comp.getActionMap().put(id, action); comp.getActionMap().put(id, action);
} }
......
...@@ -16,3 +16,7 @@ search.regex=Regex ...@@ -16,3 +16,7 @@ search.regex=Regex
search.match_case=Match Case search.match_case=Match Case
search.whole_word=Whole word search.whole_word=Whole word
search.find=Find search.find=Find
tabs.close=Close
tabs.closeOthers=Close Others
tabs.closeAll=Close All
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment