All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.adoptopenjdk.jitwatch.ui.triview.Viewer Maven / Gradle / Ivy

/*
 * Copyright (c) 2013-2016 Chris Newland.
 * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
 * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
 */
package org.adoptopenjdk.jitwatch.ui.triview;

import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.DEBUG_LOGGING;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DOUBLE_SPACE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_EMPTY;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_NEWLINE;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_NEWLINE_CR;
import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_TAB;
import static org.adoptopenjdk.jitwatch.util.UserInterfaceUtil.FONT_MONOSPACE_FAMILY;
import static org.adoptopenjdk.jitwatch.util.UserInterfaceUtil.FONT_MONOSPACE_SIZE;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;

import org.adoptopenjdk.jitwatch.core.JITWatchConfig;
import org.adoptopenjdk.jitwatch.model.IMetaMember;
import org.adoptopenjdk.jitwatch.model.bytecode.LineAnnotation;
import org.adoptopenjdk.jitwatch.ui.main.IStageAccessProxy;
import org.adoptopenjdk.jitwatch.ui.triview.ILineListener.LineType;
import org.adoptopenjdk.jitwatch.ui.triview.assembly.AssemblyLabel;
import org.adoptopenjdk.jitwatch.ui.triview.bytecode.BytecodeLabel;
import org.adoptopenjdk.jitwatch.util.ParseUtil;
import org.adoptopenjdk.jitwatch.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Viewer extends VBox
{
	private ScrollPane scrollPane;
	protected VBox vBoxRows;

	public static final String COLOUR_BLACK = "black";
	public static final String COLOUR_RED = "red";
	public static final String COLOUR_GREEN = "green";
	public static final String COLOUR_BLUE = "blue";

	private int scrollIndex = 0;
	protected int lastScrollIndex = -1;
	protected String originalSource;
	
	private double lastKnownGoodLineHeight = 15;

	private static final String FONT_STYLE = "-fx-font-family:" + FONT_MONOSPACE_FAMILY + "; -fx-font-size:" + FONT_MONOSPACE_SIZE
			+ "px;";

	public static final String STYLE_UNHIGHLIGHTED = FONT_STYLE + "-fx-background-color:white;";
	public static final String STYLE_HIGHLIGHTED = FONT_STYLE + "-fx-background-color:red;";
	public static final String STYLE_UNHIGHLIGHTED_SUGGESTION = FONT_STYLE + "-fx-background-color:yellow;";
	public static final String STYLE_SAFEPOINT = FONT_STYLE + "-fx-background-color:yellow;";

	protected Map lineAnnotations = new HashMap<>();

	protected static final Logger logger = LoggerFactory.getLogger(Viewer.class);

	protected IStageAccessProxy stageAccessProxy;

	protected ILineListener lineListener;
	protected LineType lineType = LineType.PLAIN;

	private boolean isHighlighting;

	public Viewer(IStageAccessProxy stageAccessProxy, boolean highlighting)
	{
		this.stageAccessProxy = stageAccessProxy;
		this.isHighlighting = highlighting;

		lineListener = new NoOpLineListener();

		setup();
	}

	public Viewer(IStageAccessProxy stageAccessProxy, ILineListener lineListener, LineType lineType, boolean highlighting)
	{
		this.stageAccessProxy = stageAccessProxy;
		this.lineListener = lineListener;
		this.lineType = lineType;
		this.isHighlighting = highlighting;

		setup();
	}
	
	public void clear()
	{
		lineAnnotations.clear();
		
		vBoxRows.getChildren().clear();
		
		lastScrollIndex = -1;
	}
	
	public LineType getLineType()
	{
		return lineType;
	}

	public JITWatchConfig getConfig()
	{
		return stageAccessProxy.getConfig();
	}

	private void setup()
	{
		vBoxRows = new VBox();

		vBoxRows.heightProperty().addListener(new ChangeListener()
		{
			@Override
			public void changed(ObservableValue arg0, Number oldValue, Number newValue)
			{
				setScrollBar();
			}
		});

		scrollPane = new ScrollPane();
		scrollPane.setContent(vBoxRows);
		scrollPane.setStyle("-fx-background:white");

		scrollPane.setFitToHeight(true);

		scrollPane.prefHeightProperty().bind(heightProperty());

		EventHandler keyHandler = new EventHandler()
		{
			@Override
			public void handle(KeyEvent event)
			{
				KeyCode code = event.getCode();

				clearAllHighlighting();

				switch (code)
				{
				case UP:
					handleKeyUp();
					break;
				case DOWN:
					handleKeyDown();
					break;
				case LEFT:
					handleKeyLeft();
					break;
				case RIGHT:
					handleKeyRight();
					break;
				case PAGE_UP:
					handleKeyPageUp();
					break;
				case PAGE_DOWN:
					handleKeyPageDown();
					break;
				default:
					return;
				}

				event.consume();
			}
		};

		focusedProperty().addListener(new ChangeListener()
		{
			@Override
			public void changed(ObservableValue observable, Boolean hadFocus, Boolean hasFocus)
			{
				if (hasFocus && !hadFocus)
				{
					scrollPane.requestFocus();
				}
			}
		});

		scrollPane.focusedProperty().addListener(new ChangeListener()
		{
			@Override
			public void changed(ObservableValue observable, Boolean hadFocus, Boolean hasFocus)
			{
				if (hasFocus && !hadFocus)
				{
					lineListener.lineHighlighted(scrollIndex, lineType);
					highlightLine(scrollIndex, false);
				}
			}
		});

		scrollPane.setOnMouseEntered(new EventHandler()
		{
			@Override
			public void handle(MouseEvent arg0)
			{

				if (getConfig().isTriViewMouseFollow())
				{
					lineListener.handleFocusSelf(lineType);
				}
			}
		});

		scrollPane.setOnMouseClicked(new EventHandler()
		{
			@Override
			public void handle(MouseEvent arg0)
			{
				lineListener.handleFocusSelf(lineType);
			}
		});

		scrollPane.setOnKeyPressed(keyHandler);

		getChildren().add(scrollPane);

		setUpContextMenu();
	}

	public void setContent(String inSource, boolean showLineNumbers, boolean canHighlight)
	{
		clear();
		
		String source = inSource;
		
		isHighlighting = canHighlight;
		
		if (source == null)
		{
			source = "Empty";
		}

		originalSource = source;

		source = source.replace(S_TAB, S_DOUBLE_SPACE);

		String[] lines = source.split(S_NEWLINE);

		int maxWidth = Integer.toString(lines.length).length();

		List




© 2015 - 2025 Weber Informatics LLC | Privacy Policy