mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-24 00:25:38 +00:00
Issue #302 better Ctrl+Click handling - underline and cursor hand only when can go through
This commit is contained in:
@@ -109,8 +109,10 @@ import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableColumn;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.tree.TreePath;
|
||||
import jsyntaxpane.DefaultSyntaxKit;
|
||||
import jsyntaxpane.Token;
|
||||
|
||||
public class ABCPanel extends JPanel implements ItemListener, ActionListener, SearchListener<ABCPanelSearchResult>, Freed {
|
||||
|
||||
@@ -362,6 +364,24 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
decompiledTextArea = new DecompiledEditorPane(this);
|
||||
|
||||
decompiledTextArea.setLinkHandler(new LinkHandler() {
|
||||
|
||||
@Override
|
||||
public boolean isLink(Token token) {
|
||||
return isDeclaration(token.start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLink(Token token) {
|
||||
gotoDeclaration(token.start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Highlighter.HighlightPainter linkPainter() {
|
||||
return decompiledTextArea.linkPainter();
|
||||
}
|
||||
});
|
||||
|
||||
searchPanel = new SearchPanel<>(new FlowLayout(), this);
|
||||
|
||||
@@ -439,7 +459,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
View.addEditorAction(decompiledTextArea, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int multinameIndex = decompiledTextArea.getMultinameUnderCursor();
|
||||
int multinameIndex = decompiledTextArea.getMultinameUnderCaret();
|
||||
if (multinameIndex > -1) {
|
||||
UsageFrame usageFrame = new UsageFrame(swf.abcList, abc, multinameIndex, ABCPanel.this, false);
|
||||
usageFrame.setVisible(true);
|
||||
@@ -450,7 +470,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
View.addEditorAction(decompiledTextArea, new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
gotoDeclaration();
|
||||
gotoDeclaration(decompiledTextArea.getCaretPosition());
|
||||
}
|
||||
}, "find-declaration", AppStrings.translate("abc.action.find-declaration"), "control B");
|
||||
|
||||
@@ -518,8 +538,36 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
tabbedPane.addTab(AppStrings.translate("constants"), panConstants);
|
||||
}
|
||||
|
||||
private void gotoDeclaration() {
|
||||
int multinameIndex = decompiledTextArea.getMultinameUnderCursor();
|
||||
private boolean isDeclaration(int pos) {
|
||||
int multinameIndex = decompiledTextArea.getMultinameAtPos(pos);
|
||||
if (multinameIndex > -1) {
|
||||
List<MultinameUsage> usages = abc.findMultinameDefinition(swf.abcList, multinameIndex);
|
||||
|
||||
Multiname m = abc.constants.constant_multiname.get(multinameIndex);
|
||||
//search other ABC tags if this is not private multiname
|
||||
if (m.namespace_index > 0 && abc.constants.constant_namespace.get(m.namespace_index).kind != Namespace.KIND_PRIVATE) {
|
||||
for (ABCContainerTag at : swf.abcList) {
|
||||
ABC a = at.getABC();
|
||||
if (a == abc) {
|
||||
continue;
|
||||
}
|
||||
int mid = a.constants.getMultinameId(m, false);
|
||||
if (mid > 0) {
|
||||
usages.addAll(a.findMultinameDefinition(swf.abcList, mid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//more than one? display list
|
||||
if (!usages.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void gotoDeclaration(int pos) {
|
||||
int multinameIndex = decompiledTextArea.getMultinameAtPos(pos);
|
||||
if (multinameIndex > -1) {
|
||||
List<MultinameUsage> usages = abc.findMultinameDefinition(swf.abcList, multinameIndex);
|
||||
|
||||
@@ -556,7 +604,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == 17 && !decompiledTextArea.isEditable()) {
|
||||
ctrlDown = true;
|
||||
decompiledTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
//decompiledTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,7 +612,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == 17) {
|
||||
ctrlDown = false;
|
||||
decompiledTextArea.setCursor(Cursor.getDefaultCursor());
|
||||
//decompiledTextArea.setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,8 +620,8 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (ctrlDown && e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1 && !decompiledTextArea.isEditable()) {
|
||||
ctrlDown = false;
|
||||
decompiledTextArea.setCursor(Cursor.getDefaultCursor());
|
||||
gotoDeclaration();
|
||||
//decompiledTextArea.setCursor(Cursor.getDefaultCursor());
|
||||
//gotoDeclaration();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
@@ -220,12 +221,24 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
caretUpdate(null);
|
||||
reset = false;
|
||||
}
|
||||
|
||||
public int getMultinameUnderCursor() {
|
||||
int pos = getCaretPosition();
|
||||
public int getMultinameUnderMouseCursor(Point pt) {
|
||||
return getMultinameAtPos(viewToModel(pt));
|
||||
}
|
||||
|
||||
public int getMultinameUnderCaret() {
|
||||
return getMultinameAtPos(getCaretPosition());
|
||||
}
|
||||
|
||||
public int getMultinameAtPos(int pos) {
|
||||
Highlighting tm = Highlighting.search(methodHighlights, pos);
|
||||
if (tm == null) {
|
||||
return -1;
|
||||
}
|
||||
int mi = (int)(long)tm.getPropertyLong("index");
|
||||
int bi = abc.findBodyIndex(mi);
|
||||
Highlighting h = Highlighting.search(highlights, pos);
|
||||
if (h != null) {
|
||||
List<AVM2Instruction> list = abc.bodies.get(abcPanel.detailPanel.methodTraitPanel.methodCodePanel.getBodyIndex()).getCode().code;
|
||||
List<AVM2Instruction> list = abc.bodies.get(bi).getCode().code;
|
||||
AVM2Instruction lastIns = null;
|
||||
long inspos = 0;
|
||||
AVM2Instruction selIns = null;
|
||||
|
||||
@@ -19,20 +19,45 @@ package com.jpexs.decompiler.flash.gui.abc;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.KeyEventPostProcessor;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
import javax.swing.plaf.TextUI;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.DefaultHighlighter;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.Element;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.Highlighter.HighlightPainter;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Position;
|
||||
import javax.swing.text.View;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import jsyntaxpane.SyntaxDocument;
|
||||
import jsyntaxpane.SyntaxStyle;
|
||||
import jsyntaxpane.SyntaxStyles;
|
||||
import jsyntaxpane.Token;
|
||||
import jsyntaxpane.actions.ActionUtils;
|
||||
import jsyntaxpane.components.Markers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LineMarkedEditorPane extends UndoFixedEditorPane {
|
||||
public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHandler {
|
||||
|
||||
private static final int truncateLimit = 8192;
|
||||
private int lastLine = -1;
|
||||
@@ -96,8 +121,154 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane {
|
||||
error = false;
|
||||
repaint();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
final LinkAdapter la = new LinkAdapter();
|
||||
addMouseMotionListener(la);
|
||||
addMouseListener(la);
|
||||
|
||||
//No standard AddKeyListener as we want to catch Ctrl globally no matter of focus
|
||||
KeyboardFocusManager.getCurrentKeyboardFocusManager()
|
||||
.addKeyEventPostProcessor(new KeyEventPostProcessor() {
|
||||
|
||||
@Override
|
||||
public boolean postProcessKeyEvent(KeyEvent e) {
|
||||
if (e.getID() == KeyEvent.KEY_PRESSED) {
|
||||
la.keyPressed(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_RELEASED) {
|
||||
la.keyReleased(e);
|
||||
}
|
||||
if (e.getID() == KeyEvent.KEY_TYPED) {
|
||||
la.keyTyped(e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
private Token lastUnderlined = null;
|
||||
private static final HighlightPainter underLinePainter = new UnderLinePainter(new Color(0, 0, 255));
|
||||
private LinkHandler linkHandler = this;
|
||||
|
||||
private class LinkAdapter extends MouseAdapter implements KeyListener {
|
||||
|
||||
private Point lastPos = new Point(0, 0);
|
||||
private boolean ctrlDown = false;
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
|
||||
ctrlDown = false;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (ctrlDown) {
|
||||
Document d = getDocument();
|
||||
if (d instanceof SyntaxDocument) {
|
||||
SyntaxDocument sd = (SyntaxDocument) d;
|
||||
int pos = viewToModel(lastPos);
|
||||
if (pos < 0) {
|
||||
return;
|
||||
}
|
||||
Token t = sd.getTokenAt(pos);
|
||||
if (t != lastUnderlined) {
|
||||
if (t == null || lastUnderlined == null || !t.equals(lastUnderlined)) {
|
||||
MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter);
|
||||
|
||||
if (t != null && linkHandler.isLink(t)) {
|
||||
lastUnderlined = t;
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
}
|
||||
} else {
|
||||
lastUnderlined = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastUnderlined != null) {
|
||||
MyMarkers.markToken(LineMarkedEditorPane.this, lastUnderlined, underLinePainter);
|
||||
} else {
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
}else {
|
||||
lastUnderlined = null;
|
||||
MyMarkers.removeMarkers(LineMarkedEditorPane.this, underLinePainter);
|
||||
setCursor(Cursor.getDefaultCursor());
|
||||
repaint();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (ctrlDown) {
|
||||
SyntaxDocument sd = (SyntaxDocument) getDocument();
|
||||
int pos = viewToModel(e.getPoint());
|
||||
if (pos < 0) {
|
||||
return;
|
||||
}
|
||||
Token t = sd.getTokenAt(pos);
|
||||
if (t != null && linkHandler.isLink(t)) {
|
||||
linkHandler.handleLink(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
|
||||
ctrlDown = (e.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) > 0;
|
||||
lastPos = e.getPoint();
|
||||
update();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void setLinkHandler(LinkHandler linkHandler) {
|
||||
if (linkHandler == null) {
|
||||
linkHandler = this;
|
||||
}
|
||||
this.linkHandler = linkHandler;
|
||||
}
|
||||
|
||||
public LinkHandler getLinkHandler() {
|
||||
return linkHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HighlightPainter linkPainter() {
|
||||
return underLinePainter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLink(Token token) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLink(Token token) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,7 +287,80 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane {
|
||||
lastLine = -1;
|
||||
error = true;
|
||||
super.setText(t, contentType);
|
||||
setCaretPosition(0); //scroll to top
|
||||
setCaretPosition(0); //scroll to top
|
||||
}
|
||||
|
||||
public static class UnderLinePainter extends DefaultHighlighter.DefaultHighlightPainter {
|
||||
|
||||
public UnderLinePainter(Color color) {
|
||||
super(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
|
||||
try {
|
||||
// --- determine locations ---
|
||||
TextUI mapper = c.getUI();
|
||||
|
||||
Color col = getColor();
|
||||
if (col == null) {
|
||||
col = Color.black;
|
||||
}
|
||||
g.setColor(col);
|
||||
for (int i = offs0; i < offs1; i++) {
|
||||
|
||||
Rectangle r = mapper.modelToView(c, i, Position.Bias.Forward);
|
||||
Rectangle r1 = mapper.modelToView(c, i + 1, Position.Bias.Forward);
|
||||
if (r1.y == r.y) {
|
||||
g.drawLine(r.x, r.y + r.height - 3, r1.x, r.y + r.height - 3);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Shape paintLayer(Graphics g, int offs0, int offs1,
|
||||
Shape bounds, JTextComponent c, View view) {
|
||||
|
||||
g.setColor(c.getSelectionColor());
|
||||
|
||||
Rectangle r;
|
||||
|
||||
if (offs0 == view.getStartOffset()
|
||||
&& offs1 == view.getEndOffset()) {
|
||||
// Contained in view, can just use bounds.
|
||||
if (bounds instanceof Rectangle) {
|
||||
r = (Rectangle) bounds;
|
||||
} else {
|
||||
r = bounds.getBounds();
|
||||
}
|
||||
} else {
|
||||
// Should only render part of View.
|
||||
try {
|
||||
// --- determine locations ---
|
||||
Shape shape = view.modelToView(offs0, Position.Bias.Forward,
|
||||
offs1, Position.Bias.Backward,
|
||||
bounds);
|
||||
r = (shape instanceof Rectangle)
|
||||
? (Rectangle) shape : shape.getBounds();
|
||||
} catch (BadLocationException e) {
|
||||
// can't render
|
||||
r = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (r != null) {
|
||||
r.width = Math.max(r.width, 1);
|
||||
|
||||
paint(g, offs0, offs1, r, c);
|
||||
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,16 +370,13 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane {
|
||||
if (lastLine > 0) {
|
||||
FontMetrics fontMetrics = g.getFontMetrics();
|
||||
int lh = fontMetrics.getHeight();
|
||||
int a = fontMetrics.getAscent();
|
||||
int d = fontMetrics.getDescent();
|
||||
int h = a + d;
|
||||
int rH = h;
|
||||
if (error) {
|
||||
g.setColor(new Color(255, 200, 200));
|
||||
} else {
|
||||
g.setColor(new Color(0xee, 0xee, 0xee));
|
||||
}
|
||||
g.fillRect(0, d + lh * lastLine - 1, getWidth(), lh);
|
||||
g.fillRect(0, d + lh * lastLine - 1, getWidth(), lh);
|
||||
}
|
||||
super.paint(g);
|
||||
}
|
||||
|
||||
30
src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java
Normal file
30
src/com/jpexs/decompiler/flash/gui/abc/LinkHandler.java
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2014 jindr_000
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import javax.swing.text.Highlighter;
|
||||
import jsyntaxpane.Token;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface LinkHandler {
|
||||
public boolean isLink(Token token);
|
||||
public void handleLink(Token token);
|
||||
public Highlighter.HighlightPainter linkPainter();
|
||||
}
|
||||
126
src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java
Normal file
126
src/com/jpexs/decompiler/flash/gui/abc/MyMarkers.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2014 jindr_000
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Highlighter;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import jsyntaxpane.SyntaxDocument;
|
||||
import jsyntaxpane.Token;
|
||||
import jsyntaxpane.actions.ActionUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class MyMarkers {
|
||||
|
||||
/**
|
||||
* Removes only our private highlights
|
||||
* This is public so that we can remove the highlights when the editorKit
|
||||
* is unregistered. SimpleMarker can be null, in which case all instances of
|
||||
* our Markers are removed.
|
||||
* @param component the text component whose markers are to be removed
|
||||
* @param marker the SimpleMarker to remove
|
||||
*/
|
||||
public static void removeMarkers(JTextComponent component, Highlighter.HighlightPainter marker) {
|
||||
Highlighter hilite = component.getHighlighter();
|
||||
Highlighter.Highlight[] hilites = hilite.getHighlights();
|
||||
|
||||
for (int i = 0; i < hilites.length; i++) {
|
||||
Highlighter.HighlightPainter hMarker = hilites[i].getPainter();
|
||||
if (marker == null || hMarker.equals(marker)) {
|
||||
hilite.removeHighlight(hilites[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all the markers from an JEditorPane
|
||||
* @param editorPane
|
||||
*/
|
||||
public static void removeMarkers(JTextComponent editorPane) {
|
||||
removeMarkers(editorPane, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* add highlights for the given Token on the given pane
|
||||
* @param pane
|
||||
* @param token
|
||||
* @param marker
|
||||
*/
|
||||
public static void markToken(JTextComponent pane, Token token, Highlighter.HighlightPainter marker) {
|
||||
markText(pane, token.start, token.end(), marker);
|
||||
}
|
||||
|
||||
/**
|
||||
* add highlights for the given region on the given pane
|
||||
* @param pane
|
||||
* @param start
|
||||
* @param end
|
||||
* @param marker
|
||||
*/
|
||||
public static void markText(JTextComponent pane, int start, int end, Highlighter.HighlightPainter marker) {
|
||||
try {
|
||||
Highlighter hiliter = pane.getHighlighter();
|
||||
int selStart = pane.getSelectionStart();
|
||||
int selEnd = pane.getSelectionEnd();
|
||||
// if there is no selection or selection does not overlap
|
||||
if(selStart == selEnd || end < selStart || start > selStart) {
|
||||
hiliter.addHighlight(start, end, marker);
|
||||
return;
|
||||
}
|
||||
// selection starts within the highlight, highlight before slection
|
||||
if(selStart > start && selStart < end ) {
|
||||
hiliter.addHighlight(start, selStart, marker);
|
||||
}
|
||||
// selection ends within the highlight, highlight remaining
|
||||
if(selEnd > start && selEnd < end ) {
|
||||
hiliter.addHighlight(selEnd, end, marker);
|
||||
}
|
||||
|
||||
} catch (BadLocationException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark all text in the document that matches the given pattern
|
||||
* @param pane control to use
|
||||
* @param pattern pattern to match
|
||||
* @param marker marker to use for highlighting
|
||||
*/
|
||||
public static void markAll(JTextComponent pane, Pattern pattern, Highlighter.HighlightPainter marker) {
|
||||
SyntaxDocument sDoc = ActionUtils.getSyntaxDocument(pane);
|
||||
if(sDoc == null || pattern == null) {
|
||||
return;
|
||||
}
|
||||
Matcher matcher = sDoc.getMatcher(pattern);
|
||||
// we may not have any matcher (due to undo or something, so don't do anything.
|
||||
if(matcher==null) {
|
||||
return;
|
||||
}
|
||||
while(matcher.find()) {
|
||||
markText(pane, matcher.start(), matcher.end(), marker);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user