-
Notifications
You must be signed in to change notification settings - Fork 123
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
GraxCode
committed
Apr 25, 2020
1 parent
5371f11
commit 1d50ba8
Showing
12 changed files
with
228 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package me.nov.threadtear.swing.frame; | ||
|
||
import java.awt.BorderLayout; | ||
import java.awt.FlowLayout; | ||
|
||
import javax.swing.BorderFactory; | ||
import javax.swing.JButton; | ||
import javax.swing.JFrame; | ||
import javax.swing.JPanel; | ||
import javax.swing.WindowConstants; | ||
|
||
import org.objectweb.asm.tree.ClassNode; | ||
|
||
import com.github.weisj.darklaf.icons.IconLoader; | ||
|
||
import me.nov.threadtear.swing.Utils; | ||
import me.nov.threadtear.swing.panel.BytecodePanel; | ||
|
||
public class BytecodeFrame extends JFrame { | ||
private static final long serialVersionUID = 1L; | ||
|
||
public BytecodeFrame(ClassNode cn) { | ||
setTitle("Bytecode: " + cn.name); | ||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | ||
setBounds(100, 100, 1000, 600); | ||
setLayout(new BorderLayout()); | ||
setIconImage(Utils.iconToImage(IconLoader.get().loadSVGIcon("res/bytecode.svg", 64, 64, false))); | ||
setAlwaysOnTop(true); | ||
JPanel cp = new JPanel(new BorderLayout()); | ||
cp.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); | ||
cp.add(new BytecodePanel(cn), BorderLayout.CENTER); | ||
this.add(cp, BorderLayout.CENTER); | ||
JPanel buttons = new JPanel(); | ||
buttons.setLayout(new FlowLayout(FlowLayout.RIGHT)); | ||
JButton close = new JButton("Close"); | ||
close.addActionListener(e -> { | ||
dispose(); | ||
}); | ||
buttons.add(close); | ||
getContentPane().add(buttons, BorderLayout.SOUTH); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package me.nov.threadtear.swing.panel; | ||
|
||
import java.awt.BorderLayout; | ||
import java.awt.Color; | ||
import java.awt.Dimension; | ||
import java.awt.GridBagConstraints; | ||
import java.awt.GridBagLayout; | ||
import java.util.Objects; | ||
|
||
import javax.swing.BorderFactory; | ||
import javax.swing.JButton; | ||
import javax.swing.JLabel; | ||
import javax.swing.JPanel; | ||
import javax.swing.JScrollPane; | ||
import javax.swing.JTextField; | ||
import javax.swing.border.EmptyBorder; | ||
import javax.swing.text.BadLocationException; | ||
import javax.swing.text.DefaultHighlighter; | ||
import javax.swing.text.Document; | ||
import javax.swing.text.Highlighter; | ||
|
||
import org.fife.ui.rtextarea.RTextScrollPane; | ||
import org.objectweb.asm.tree.ClassNode; | ||
|
||
import com.github.weisj.darklaf.icons.IconLoader; | ||
|
||
import me.nov.threadtear.io.Conversion; | ||
import me.nov.threadtear.swing.textarea.BytecodeTextArea; | ||
|
||
public class BytecodePanel extends JPanel { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private BytecodeTextArea textArea; | ||
|
||
private int searchIndex = -1; | ||
private String lastSearchText = null; | ||
|
||
public BytecodePanel(ClassNode cn) { | ||
this.setLayout(new BorderLayout(4, 4)); | ||
JPanel actionPanel = new JPanel(); | ||
actionPanel.setLayout(new GridBagLayout()); | ||
JButton reload = new JButton(IconLoader.get().loadSVGIcon("res/refresh.svg", false)); | ||
reload.addActionListener(l -> { | ||
textArea.setText(Conversion.textify(cn)); | ||
}); | ||
JTextField search = new JTextField(); | ||
// search.putClientProperty(DarkTextUI.KEY_DEFAULT_TEXT, "Search..."); | ||
search.setPreferredSize(new Dimension(200, reload.getPreferredSize().height)); | ||
search.addActionListener(l -> { | ||
try { | ||
String text = search.getText(); | ||
if (text.isEmpty()) { | ||
textArea.getHighlighter().removeAllHighlights(); | ||
return; | ||
} | ||
String searchText = text.toLowerCase(); | ||
if (!Objects.equals(searchText, lastSearchText)) { | ||
searchIndex = -1; | ||
lastSearchText = searchText; | ||
} | ||
String[] split = textArea.getText().split("\\r?\\n"); | ||
int firstIndex = -1; | ||
boolean first = false; | ||
Label: { | ||
for (int i = 0; i < split.length; i++) { | ||
String line = split[i]; | ||
if (line.toLowerCase().contains(searchText)) { | ||
if (i > searchIndex) { | ||
textArea.setCaretPosition(textArea.getDocument().getDefaultRootElement().getElement(i).getStartOffset()); | ||
searchIndex = i; | ||
break Label; | ||
} else if (!first) { | ||
firstIndex = i; | ||
first = true; | ||
} | ||
} | ||
} | ||
if (first) { | ||
// go back to first line | ||
textArea.setCaretPosition(textArea.getDocument().getDefaultRootElement().getElement(firstIndex).getStartOffset()); | ||
searchIndex = firstIndex; | ||
} | ||
} | ||
hightlightText(searchText); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
}); | ||
|
||
actionPanel.add(search); | ||
GridBagConstraints gbc = new GridBagConstraints(); | ||
gbc.anchor = GridBagConstraints.EAST; | ||
actionPanel.add(reload, gbc); | ||
JPanel topPanel = new JPanel(); | ||
topPanel.setBorder(new EmptyBorder(1, 5, 0, 1)); | ||
topPanel.setLayout(new BorderLayout()); | ||
topPanel.add(new JLabel("<html>Bytecode of <tt>" + cn.name.replace('/', '.') + "</tt>"), BorderLayout.WEST); | ||
topPanel.add(actionPanel, BorderLayout.EAST); | ||
this.add(topPanel, BorderLayout.NORTH); | ||
this.textArea = new BytecodeTextArea(); | ||
textArea.setText(Conversion.textify(cn)); | ||
JScrollPane scp = new RTextScrollPane(textArea); | ||
scp.getVerticalScrollBar().setUnitIncrement(16); | ||
scp.setBorder(BorderFactory.createLoweredSoftBevelBorder()); | ||
this.add(scp, BorderLayout.CENTER); | ||
} | ||
|
||
private void hightlightText(String searchText) throws BadLocationException { | ||
Highlighter highlighter = textArea.getHighlighter(); | ||
highlighter.removeAllHighlights(); | ||
Document document = textArea.getDocument(); | ||
String text = document.getText(0, document.getLength()).toLowerCase(); | ||
int pos = text.indexOf(searchText); | ||
while (pos >= 0) { | ||
highlighter.addHighlight(pos, pos + searchText.length(), (Highlighter.HighlightPainter) new DefaultHighlighter.DefaultHighlightPainter(new Color(0x0078d7))); | ||
pos = text.indexOf(searchText, pos + searchText.length()); | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/me/nov/threadtear/swing/textarea/BytecodeTextArea.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package me.nov.threadtear.swing.textarea; | ||
|
||
import java.awt.Font; | ||
import java.io.IOException; | ||
|
||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; | ||
import org.fife.ui.rsyntaxtextarea.Theme; | ||
|
||
public class BytecodeTextArea extends RSyntaxTextArea { | ||
private static final long serialVersionUID = 1L; | ||
|
||
public BytecodeTextArea() { | ||
this.setSyntaxEditingStyle(SYNTAX_STYLE_CPLUSPLUS); | ||
this.setCodeFoldingEnabled(true); | ||
this.setAntiAliasingEnabled(true); | ||
this.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); | ||
this.setEditable(false); | ||
|
||
try { | ||
Theme theme = Theme.load(getClass().getResourceAsStream("/res/rsta-theme.xml")); | ||
theme.apply(this); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.