/*
* Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC
* All rights reserved.
*
* The source code of this document is proprietary work, and is not licensed for
* distribution. For information about licensing, contact Sam Harwell at:
* sam@tunnelvisionlabs.com
*/
package org.antlr.works.editor.grammar.debugger;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.TextUI;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.Document;
import javax.swing.text.EditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.Vocabulary;
import org.antlr.v4.runtime.VocabularyImpl;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.api.settings.ConvertAsProperties;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.text.Line;
import org.openide.text.NbDocument;
import org.openide.util.NbBundle.Messages;
import org.openide.util.WeakListeners;
import org.openide.windows.TopComponent;
/**
* Top component which displays something.
*/
@ConvertAsProperties(dtd = "-//org.antlr.works.editor.grammar.debugger//LexerDebuggerController//EN",
autostore = false)
@TopComponent.Description(preferredID = "LexerDebuggerControllerTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE",
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "rightSlidingSide", openAtStartup = false)
@ActionID(category = "Window", id = "org.antlr.works.editor.grammar.debugger.LexerDebuggerControllerTopComponent")
@ActionReference(path = "Menu/Window" /*
* , position = 333
*/)
@TopComponent.OpenActionRegistration(displayName = "#CTL_LexerDebuggerControllerAction",
preferredID = "LexerDebuggerControllerTopComponent")
@Messages({
"CTL_LexerDebuggerControllerAction=Lexer Debugger Controller",
"CTL_LexerDebuggerControllerTopComponent=Lexer",
"HINT_LexerDebuggerControllerTopComponent=This is a lexer debugger controller window"
})
public final class LexerDebuggerControllerTopComponent extends TopComponent {
private final PropertyChangeListener editorRegistryListener = new EditorRegistryListener();
private static final String defaultChannelText = String.format("DEFAULT (%d)", Lexer.DEFAULT_TOKEN_CHANNEL);
private static final String hiddenChannelText = String.format("HIDDEN (%d)", Lexer.HIDDEN);
public LexerDebuggerControllerTopComponent() {
initComponents();
setName(Bundle.CTL_LexerDebuggerControllerTopComponent());
setToolTipText(Bundle.HINT_LexerDebuggerControllerTopComponent());
jSplitPane1.setDividerLocation(0.8);
EditorRegistry.addPropertyChangeListener(WeakListeners.propertyChange(editorRegistryListener, EditorRegistry.class));
lstChannels.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
JList<?> list = (JList<?>)e.getSource();
List<Integer> selectedChannels = new ArrayList<>();
for (Object item : list.getSelectedValuesList()) {
if (item instanceof String) {
if (defaultChannelText.equals(item)) {
selectedChannels.add(Lexer.DEFAULT_TOKEN_CHANNEL);
} else if (hiddenChannelText.equals(item)) {
selectedChannels.add(Lexer.HIDDEN);
} else {
throw new UnsupportedOperationException("unrecognized channel");
}
} else if (item instanceof Integer) {
selectedChannels.add((Integer)item);
} else {
throw new UnsupportedOperationException("unrecognized channel");
}
}
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
if (editor == null || !(editor.getDocument() instanceof StyledDocument)) {
return;
}
StyledDocument document = (StyledDocument)editor.getDocument();
for (TraceToken token : tokens) {
if (selectedChannels.contains(token.getChannel())) {
int index = token.getStartIndex();
if (index >= 0 && index <= document.getLength()) {
int column = NbDocument.findLineColumn(document, index);
NbEditorUtilities.getLine(document, index, true).show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS, column);
return;
}
}
}
}
}
});
lstChannels.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
JList<?> list = (JList<?>)e.getSource();
List<Integer> selectedChannels = new ArrayList<>();
for (Object item : list.getSelectedValuesList()) {
if (item instanceof String) {
if (defaultChannelText.equals(item)) {
selectedChannels.add(Lexer.DEFAULT_TOKEN_CHANNEL);
} else if (hiddenChannelText.equals(item)) {
selectedChannels.add(Lexer.HIDDEN);
} else {
throw new UnsupportedOperationException("unrecognized channel");
}
} else if (item instanceof Integer) {
selectedChannels.add((Integer)item);
} else {
throw new UnsupportedOperationException("unrecognized channel");
}
}
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
List<TraceToken> selectedTokens = new ArrayList<>();
for (TraceToken token : tokens) {
if (selectedChannels.contains(token.getChannel())) {
selectedTokens.add(token);
}
}
if (tokens.length > 0) {
editor.getDocument().putProperty(LexerDebuggerEditorKit.PROP_SELECTED_TOKENS, selectedTokens);
}
}
});
tblTokenTypes.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
int[] selectedRows = tblTokenTypes.getSelectedRows();
BitSet selectedTypes = new BitSet();
for (int i : selectedRows) {
selectedTypes.set((Integer)tblTokenTypes.getValueAt(i, 2));
}
JTextComponent editor = EditorRegistry.lastFocusedComponent();
if (editor == null || !(editor.getDocument() instanceof StyledDocument)) {
return;
}
StyledDocument document = (StyledDocument)editor.getDocument();
TraceToken[] tokens = getEditorTokens(editor);
for (TraceToken token : tokens) {
if (token.getType() < 0) {
continue;
}
if (selectedTypes.get(token.getType())) {
int index = token.getStartIndex();
if (index >= 0 && index <= document.getLength()) {
int column = NbDocument.findLineColumn(document, index);
NbEditorUtilities.getLine(document, index, true).show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS, column);
return;
}
}
}
}
}
});
tblTokenTypes.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
int[] selectedRows = tblTokenTypes.getSelectedRows();
BitSet selectedTypes = new BitSet();
for (int i : selectedRows) {
selectedTypes.set((Integer)tblTokenTypes.getValueAt(i, 2));
}
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
List<TraceToken> selectedTokens = new ArrayList<>();
for (TraceToken token : tokens) {
if (token.getType() < 0) {
continue;
}
if (selectedTypes.get(token.getType())) {
selectedTokens.add(token);
}
}
if (tokens.length > 0) {
editor.getDocument().putProperty(LexerDebuggerEditorKit.PROP_SELECTED_TOKENS, selectedTokens);
}
}
});
lstTokens.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
JList<?> list = (JList<?>)e.getSource();
JTextComponent editor = EditorRegistry.lastFocusedComponent();
if (editor == null || !(editor.getDocument() instanceof StyledDocument)) {
return;
}
StyledDocument document = (StyledDocument)editor.getDocument();
for (Object value : list.getSelectedValuesList()) {
if (value instanceof TraceToken) {
TraceToken token = (TraceToken)value;
int index = token.getStartIndex();
if (index >= 0 && index <= document.getLength()) {
int column = NbDocument.findLineColumn(document, index);
NbEditorUtilities.getLine(document, index, true).show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS, column);
return;
}
}
}
}
}
});
lstTokens.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
JList<?> list = (JList<?>)e.getSource();
List<TraceToken> selectedTokens = new ArrayList<>();
for (Object value : list.getSelectedValuesList()) {
if (value instanceof TraceToken) {
selectedTokens.add((TraceToken)value);
}
}
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
if (tokens.length > 0) {
editor.getDocument().putProperty(LexerDebuggerEditorKit.PROP_SELECTED_TOKENS, selectedTokens);
}
}
});
lstModes.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
JList<?> list = (JList<?>)e.getSource();
int[] selectedModes = list.getSelectedIndices();
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
if (editor == null || !(editor.getDocument() instanceof StyledDocument)) {
return;
}
StyledDocument document = (StyledDocument)editor.getDocument();
for (TraceToken token : tokens) {
if (Arrays.binarySearch(selectedModes, token.getMode()) >= 0) {
int index = token.getStartIndex();
if (index >= 0 && index <= document.getLength()) {
int column = NbDocument.findLineColumn(document, index);
NbEditorUtilities.getLine(document, index, true).show(Line.ShowOpenType.OPEN, Line.ShowVisibilityType.FOCUS, column);
return;
}
}
}
}
}
});
lstModes.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
JList<?> list = (JList<?>)e.getSource();
int[] selectedModes = list.getSelectedIndices();
JTextComponent editor = EditorRegistry.lastFocusedComponent();
TraceToken[] tokens = getEditorTokens(editor);
List<TraceToken> selectedTokens = new ArrayList<>();
for (TraceToken token : tokens) {
if (Arrays.binarySearch(selectedModes, token.getMode()) >= 0) {
selectedTokens.add(token);
}
}
if (tokens.length > 0) {
editor.getDocument().putProperty(LexerDebuggerEditorKit.PROP_SELECTED_TOKENS, selectedTokens);
}
}
});
lstLookahead.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
JList<?> list = (JList<?>)e.getSource();
JTextComponent editor = EditorRegistry.lastFocusedComponent();
boolean showAtnTmp = false;
boolean showDfaTmp = false;
for (Object value : list.getSelectedValuesList()) {
if ("ATN".equals(value)) {
showAtnTmp = true;
} else if ("DFA".equals(value)) {
showDfaTmp = true;
}
}
final boolean showAtn = showAtnTmp;
final boolean showDfa = showDfaTmp;
TupleIntInt[] highlightedCharacters;
if (showAtn) {
TupleIntInt[] atnCharacters = getEditorAtnCharacters(editor);
highlightedCharacters = atnCharacters;
} else if (showDfa) {
TupleIntInt[] dfaCharacters = getEditorDfaCharacters(editor);
highlightedCharacters = dfaCharacters;
} else {
highlightedCharacters = new TupleIntInt[0];
}
editor.getDocument().putProperty(LexerDebuggerEditorKit.PROP_SELECTED_CHARACTERS, highlightedCharacters);
}
});
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings({"rawtypes", "unchecked", "Convert2Diamond"})
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jSplitPane1 = new javax.swing.JSplitPane();
javax.swing.JTabbedPane jTabbedPane1 = new javax.swing.JTabbedPane();
javax.swing.JPanel jPanel3 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
tblTokenTypes = new javax.swing.JTable();
javax.swing.JPanel jPanel2 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane3 = new javax.swing.JScrollPane();
lstTokens = new javax.swing.JList<TraceToken>();
javax.swing.JPanel jPanel4 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane2 = new javax.swing.JScrollPane();
lstChannels = new javax.swing.JList<Object>();
javax.swing.JPanel jPanel6 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane5 = new javax.swing.JScrollPane();
lstModes = new javax.swing.JList<String>();
javax.swing.JPanel jPanel5 = new javax.swing.JPanel();
javax.swing.JScrollPane jScrollPane4 = new javax.swing.JScrollPane();
lstLookahead = new javax.swing.JList<String>();
javax.swing.JPanel jPanel1 = new javax.swing.JPanel();
setLayout(new java.awt.GridLayout(1, 0));
jSplitPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
jSplitPane1.setDividerLocation(120);
jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
jSplitPane1.setResizeWeight(1.0);
jSplitPane1.setContinuousLayout(true);
tblTokenTypes.setAutoCreateRowSorter(true);
tblTokenTypes.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null},
{null, null, null},
{null, null, null},
{null, null, null}
},
new String [] {
"Name", "Literal", "Value"
}
) {
boolean[] canEdit = new boolean [] {
false, false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(tblTokenTypes);
if (tblTokenTypes.getColumnModel().getColumnCount() > 0) {
tblTokenTypes.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.tblTokenTypes.columnModel.title0")); // NOI18N
tblTokenTypes.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.tblTokenTypes.columnModel.title1")); // NOI18N
tblTokenTypes.getColumnModel().getColumn(2).setHeaderValue(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.tblTokenTypes.columnModel.title2")); // NOI18N
}
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
.addGap(0, 0, 0))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.jPanel3.TabConstraints.tabTitle"), jPanel3); // NOI18N
jScrollPane3.setViewportView(lstTokens);
javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 310, Short.MAX_VALUE)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 505, Short.MAX_VALUE)
.addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N
jScrollPane2.setViewportView(lstChannels);
javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
jPanel4.setLayout(jPanel4Layout);
jPanel4Layout.setHorizontalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 310, Short.MAX_VALUE)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jPanel4Layout.setVerticalGroup(
jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 505, Short.MAX_VALUE)
.addGroup(jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel4Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.jPanel4.TabConstraints.tabTitle"), jPanel4); // NOI18N
lstModes.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jScrollPane5.setViewportView(lstModes);
javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
jPanel6.setLayout(jPanel6Layout);
jPanel6Layout.setHorizontalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 310, Short.MAX_VALUE)
.addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jPanel6Layout.setVerticalGroup(
jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 505, Short.MAX_VALUE)
.addGroup(jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel6Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.jPanel6.TabConstraints.tabTitle"), jPanel6); // NOI18N
jScrollPane4.setViewportView(lstLookahead);
javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
jPanel5.setLayout(jPanel5Layout);
jPanel5Layout.setHorizontalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 310, Short.MAX_VALUE)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jPanel5Layout.setVerticalGroup(
jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 505, Short.MAX_VALUE)
.addGroup(jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel5Layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 505, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
jTabbedPane1.addTab(org.openide.util.NbBundle.getMessage(LexerDebuggerControllerTopComponent.class, "LexerDebuggerControllerTopComponent.jPanel5.TabConstraints.tabTitle"), jPanel5); // NOI18N
jSplitPane1.setLeftComponent(jTabbedPane1);
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 315, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
jSplitPane1.setRightComponent(jPanel1);
add(jSplitPane1);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JList<Object> lstChannels;
private javax.swing.JList<String> lstLookahead;
private javax.swing.JList<String> lstModes;
private javax.swing.JList<TraceToken> lstTokens;
private javax.swing.JTable tblTokenTypes;
// End of variables declaration//GEN-END:variables
@Override
public void componentOpened() {
// TODO add custom code on component opening
}
@Override
public void componentClosed() {
// TODO add custom code on component closing
}
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
// TODO store your settings
}
void readProperties(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
}
private class EditorRegistryListener implements PropertyChangeListener {
private JTextComponent currentComponent;
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (EditorRegistry.FOCUS_GAINED_PROPERTY.equals(evt.getPropertyName())) {
JTextComponent component = EditorRegistry.focusedComponent();
if (component == currentComponent) {
return;
}
Document document = component.getDocument();
Vocabulary vocabulary = (Vocabulary)document.getProperty(LexerDebuggerEditorKit.PROP_VOCABULARY);
String[] modeNamesArray = (String[])document.getProperty(LexerDebuggerEditorKit.PROP_MODE_NAMES);
List<String> modeNames = modeNamesArray != null ? Arrays.asList(modeNamesArray) : Collections.<String>emptyList();
if (vocabulary == null) {
LexerInterpreterData lexerInterpreterData = (LexerInterpreterData)document.getProperty(LexerDebuggerEditorKit.PROP_LEXER_INTERP_DATA);
if (lexerInterpreterData != null) {
vocabulary = lexerInterpreterData.vocabulary;
modeNames = lexerInterpreterData.modeNames;
}
}
final Vocabulary finalVocabulary = vocabulary != null ? vocabulary : VocabularyImpl.EMPTY_VOCABULARY;
final List<String> finalModeNames = modeNames;
currentComponent = component;
tblTokenTypes.setModel(new AbstractTableModel() {
private final List<String> literalNames = new ArrayList<>();
private final List<String> symbolicNames = new ArrayList<>();
private final List<Integer> values = new ArrayList<>();
{
// TODO: Find a better way to communicate this value
int maxTokenType = 1024;
for (int i = 0; i <= maxTokenType; i++) {
String literalName = finalVocabulary.getLiteralName(i);
String symbolicName = finalVocabulary.getSymbolicName(i);
if (literalName == null && symbolicName == null) {
continue;
}
literalNames.add(literalName != null ? literalName : "");
symbolicNames.add(symbolicName != null ? symbolicName : literalName);
values.add(i);
}
}
@Override
public int getRowCount() {
return literalNames.size();
}
@Override
public int getColumnCount() {
return 3;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Name";
case 1:
return "Literal";
case 2:
return "Value";
default:
throw new IllegalArgumentException();
}
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
case 1:
return String.class;
case 2:
return Integer.class;
default:
throw new IllegalArgumentException();
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return symbolicNames.get(rowIndex);
case 1:
return literalNames.get(rowIndex);
case 2:
return values.get(rowIndex);
default:
throw new IllegalArgumentException();
}
}
});
lstTokens.setModel(new AbstractListModel<TraceToken>() {
private final TraceToken[] elements = getFocusedEditorTokens();
@Override
public int getSize() {
return elements.length;
}
@Override
public TraceToken getElementAt(int index) {
return elements[index];
}
});
List<String> tokenNames = new ArrayList<>();
for (int i = Token.EOF; i < 1024; i++) {
if (finalVocabulary.getLiteralName(i) == null && finalVocabulary.getSymbolicName(i) == null) {
continue;
}
tokenNames.add(finalVocabulary.getDisplayName(i));
}
lstTokens.setCellRenderer(new TraceTokenListCellRenderer(tokenNames));
lstChannels.setModel(new AbstractListModel<Object>() {
private final Object[] elements = { defaultChannelText, hiddenChannelText };
@Override
public int getSize() {
return elements.length;
}
@Override
public Object getElementAt(int index) {
return elements[index];
}
});
lstModes.setModel(new AbstractListModel<String>() {
private final List<String> elements = finalModeNames;
@Override
public int getSize() {
return elements.size();
}
@Override
public String getElementAt(int index) {
return elements.get(index);
}
});
lstLookahead.setModel(new AbstractListModel<String>() {
private final String[] elements = { "ATN", "DFA" };
@Override
public int getSize() {
return elements.length;
}
@Override
public String getElementAt(int index) {
return elements[index];
}
});
}
}
}
private static TraceToken[] getFocusedEditorTokens() {
JTextComponent component = EditorRegistry.lastFocusedComponent();
if (component == null) {
return new TraceToken[0];
}
return getEditorTokens(component);
}
private static TraceToken[] getEditorTokens(@NonNull JTextComponent component) {
TextUI ui = component.getUI();
if (ui == null) {
return new TraceToken[0];
}
EditorKit kit = ui.getEditorKit(component);
if (!(kit instanceof LexerDebuggerEditorKit)) {
return new TraceToken[0];
}
Document document = component.getDocument();
if (document == null) {
return new TraceToken[0];
}
return ((LexerDebuggerEditorKit)kit).getTokens(document);
}
private static TupleIntInt[] getEditorAtnCharacters(@NonNull JTextComponent component) {
return getEditorTransitions(component, true);
}
private static TupleIntInt[] getEditorDfaCharacters(@NonNull JTextComponent component) {
return getEditorTransitions(component, false);
}
private static TupleIntInt[] getEditorTransitions(@NonNull JTextComponent component, boolean atn) {
TextUI ui = component.getUI();
if (ui == null) {
return new TupleIntInt[0];
}
EditorKit kit = ui.getEditorKit(component);
if (!(kit instanceof LexerDebuggerEditorKit)) {
return new TupleIntInt[0];
}
Document document = component.getDocument();
if (document == null) {
return new TupleIntInt[0];
}
if (atn) {
return ((LexerDebuggerEditorKit)kit).getAtnTransitions(document);
} else {
return ((LexerDebuggerEditorKit)kit).getDfaTransitions(document);
}
}
private static class TraceTokenListCellRenderer extends DefaultListCellRenderer {
private final List<String> tokenNames;
public TraceTokenListCellRenderer(List<String> tokenNames) {
this.tokenNames = tokenNames;
}
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component component = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (tokenNames != null && component instanceof JLabel && value instanceof TraceToken) {
JLabel label = (JLabel)component;
TraceToken token = (TraceToken)value;
label.setText(token.toString(tokenNames));
}
return component;
}
}
}