Package jadx.gui.ui

Source Code of jadx.gui.ui.CodeArea$CodeLinkGenerator

package jadx.gui.ui;

import jadx.api.CodePosition;
import jadx.gui.treemodel.JClass;
import jadx.gui.utils.Position;

import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
import java.awt.Color;
import java.awt.Point;
import java.awt.Rectangle;

import org.fife.ui.rsyntaxtextarea.LinkGenerator;
import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.TokenTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class CodeArea extends RSyntaxTextArea {
  private static final Logger LOG = LoggerFactory.getLogger(CodeArea.class);

  private static final long serialVersionUID = 6312736869579635796L;

  public static final Color BACKGROUND = new Color(0xFAFAFA);
  public static final Color JUMP_TOKEN_FGD = new Color(0x491BA1);

  private final CodePanel codePanel;
  private final JClass cls;

  CodeArea(CodePanel panel) {
    this.codePanel = panel;
    this.cls = panel.getCls();

    setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
    SyntaxScheme scheme = getSyntaxScheme();
    scheme.getStyle(Token.FUNCTION).foreground = Color.BLACK;

    setMarkOccurrences(true);
    setBackground(BACKGROUND);
    setAntiAliasingEnabled(true);
    setEditable(false);
    Caret caret = getCaret();
    if (caret instanceof DefaultCaret) {
      ((DefaultCaret) caret).setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
    }
    caret.setVisible(true);

    setHyperlinksEnabled(true);
    CodeLinkGenerator codeLinkProcessor = new CodeLinkGenerator(cls);
    setLinkGenerator(codeLinkProcessor);
    addHyperlinkListener(codeLinkProcessor);

    setText(cls.getCode());
  }

  private boolean isJumpToken(Token token) {
    if (token.getType() == TokenTypes.IDENTIFIER) {
      // fast skip
      if (token.length() == 1) {
        char ch = token.getTextArray()[token.getTextOffset()];
        if (ch == '.' || ch == ',' || ch == ';') {
          return false;
        }
      }
      Position pos = getPosition(cls, this, token.getOffset());
      if (pos != null) {
        return true;
      }
    }
    return false;
  }

  @Override
  public Color getForegroundForToken(Token t) {
    if (isJumpToken(t)) {
      return JUMP_TOKEN_FGD;
    }
    return super.getForegroundForToken(t);
  }

  static Position getPosition(JClass jCls, RSyntaxTextArea textArea, int offset) {
    try {
      int line = textArea.getLineOfOffset(offset);
      int lineOffset = offset - textArea.getLineStartOffset(line);
      CodePosition pos = jCls.getCls().getDefinitionPosition(line + 1, lineOffset + 1);
      if (pos != null && pos.isSet()) {
        return new Position(pos);
      }
    } catch (BadLocationException e) {
      LOG.error("Can't get line by offset", e);
    }
    return null;
  }

  Position getCurrentPosition() {
    return new Position(cls, getCaretLineNumber() + 1);
  }

  Integer getSourceLine(int line) {
    return cls.getCls().getSourceLine(line);
  }

  void scrollToLine(int line) {
    int lineNum = line - 1;
    if (lineNum < 0) {
      lineNum = 0;
    }
    setCaretAtLine(lineNum);
    centerCurrentLine();
    forceCurrentLineHighlightRepaint();
  }

  public void centerCurrentLine() {
    JViewport viewport = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, this);
    if (viewport == null) {
      return;
    }
    try {
      Rectangle r = modelToView(getCaretPosition());
      if (r == null) {
        return;
      }
      int extentHeight = viewport.getExtentSize().height;
      int viewHeight = viewport.getViewSize().height;

      int y = Math.max(0, r.y - (extentHeight / 2));
      y = Math.min(y, viewHeight - extentHeight);

      viewport.setViewPosition(new Point(0, y));
    } catch (BadLocationException e) {
      LOG.debug("Can't center current line", e);
    }
  }

  private void setCaretAtLine(int line) {
    try {
      setCaretPosition(getLineStartOffset(line));
    } catch (BadLocationException e) {
      LOG.debug("Can't scroll to " + line, e);
    }
  }

  private class CodeLinkGenerator implements LinkGenerator, HyperlinkListener {
    private final JClass jCls;

    public CodeLinkGenerator(JClass cls) {
      this.jCls = cls;
    }

    @Override
    public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, int offset) {
      try {
        Token token = textArea.modelToToken(offset);
        if (token == null) {
          return null;
        }
        final int sourceOffset = token.getOffset();
        final Position defPos = getPosition(jCls, textArea, sourceOffset);
        if (defPos == null) {
          return null;
        }
        return new LinkGeneratorResult() {
          @Override
          public HyperlinkEvent execute() {
            return new HyperlinkEvent(defPos, HyperlinkEvent.EventType.ACTIVATED, null,
                defPos.getCls().getFullName());
          }

          @Override
          public int getSourceOffset() {
            return sourceOffset;
          }
        };
      } catch (Exception e) {
        LOG.error("isLinkAtOffset error", e);
        return null;
      }
    }

    @Override
    public void hyperlinkUpdate(HyperlinkEvent e) {
      Object obj = e.getSource();
      if (obj instanceof Position) {
        Position pos = (Position) obj;
        LOG.debug("Code jump to: {}", pos);
        TabbedPane tabbedPane = codePanel.getTabbedPane();
        tabbedPane.getJumpManager().addPosition(getCurrentPosition());
        tabbedPane.getJumpManager().addPosition(pos);
        tabbedPane.showCode(pos);
      }
    }
  }
}
TOP

Related Classes of jadx.gui.ui.CodeArea$CodeLinkGenerator

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.