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 extends Number> 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 extends Boolean> observable, Boolean hadFocus, Boolean hasFocus)
{
if (hasFocus && !hadFocus)
{
scrollPane.requestFocus();
}
}
});
scrollPane.focusedProperty().addListener(new ChangeListener()
{
@Override
public void changed(ObservableValue extends Boolean> 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