further work on completion panel

This commit is contained in:
Manindra Moharana
2013-04-20 10:39:29 +05:30
parent d8f50815b7
commit cdbcee6b68
5 changed files with 390 additions and 280 deletions

View File

@@ -121,121 +121,6 @@ public class ASTGenerator {
//addCompletionPopupListner();
}
private SuggestionPanel suggestion;
JEditTextArea textarea;
private void addCompletionPopupListner() {
textarea = errorCheckerService.getEditor().textArea();
textarea.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
if (suggestion != null) {
if (suggestion.insertSelection()) {
e.consume();
final int position = textarea.getCaretPosition();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
textarea.getDocument().remove(position - 1, 1);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
});
}
}
} else if (e.getKeyChar() == KeyEvent.VK_BACK_SPACE) {
System.out.println("BK Key");
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) {
suggestion.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_UP && suggestion != null) {
suggestion.moveUp();
} else if (Character.isLetterOrDigit(e.getKeyChar())
|| e.getKeyChar() == KeyEvent.VK_BACK_SPACE
|| e.getKeyChar() == KeyEvent.VK_DELETE) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showSuggestion();
}
});
} else if (Character.isWhitespace(e.getKeyChar())) {
hideSuggestion();
}
}
@Override
public void keyPressed(KeyEvent e) {
}
});
}
protected void showSuggestionLater() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showSuggestion();
}
});
}
protected void showSuggestion() {
hideSuggestion();
final int position = textarea.getCaretPosition();
Point location = new Point();
try {
location.x = textarea.offsetToX(textarea.getCaretLine(), position
- textarea.getLineStartOffset(textarea.getCaretLine()));
location.y = textarea.lineToY(textarea.getCaretLine())
+ textarea.getPainter().getFontMetrics().getHeight();
} catch (Exception e2) {
e2.printStackTrace();
return;
}
String text = textarea.getText();
int start = Math.max(0, position - 1);
while (start > 0) {
if (!Character.isWhitespace(text.charAt(start))) {
start--;
} else {
start++;
break;
}
}
if (start > position) {
return;
}
final String subWord = text.substring(start, position);
if (subWord.length() < 2) {
return;
}
suggestion = new SuggestionPanel(textarea, position, subWord, location);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textarea.requestFocusInWindow();
}
});
}
private void hideSuggestion() {
if (suggestion != null) {
suggestion.hide();
}
}
public class ASTNodeWrapper {
private ASTNode node;
@@ -308,15 +193,17 @@ public class ASTGenerator {
// return;
jtree.setModel(new DefaultTreeModel(codeTree));
((DefaultTreeModel) jtree.getModel()).reload();
if (!frame2.isVisible()) {
frame2.setVisible(true);
// if (!frame2.isVisible()) {
// frame2.setVisible(true);
// }
if (!frameAutoComp.isVisible()){
frameAutoComp.setVisible(true);
long t = System.currentTimeMillis();
loadJars();
loadJavaDoc();
addCompletionPopupListner();
//System.out.println(System.getProperty("java.home"));
System.out.println("Time taken: "
+ (System.currentTimeMillis() - t));
}
if (!frameAutoComp.isVisible())
frameAutoComp.setVisible(true);
if (!jdocWindow.isVisible())
jdocWindow.setVisible(true);
jtree.validate();
@@ -324,7 +211,7 @@ public class ASTGenerator {
}
};
worker.execute();
System.err.println("++>" + System.getProperty("java.class.path"));
// System.err.println("++>" + System.getProperty("java.class.path"));
// System.out.println(System.getProperty("java.class.path"));
// System.out.println("-------------------------------");
return codeTree;
@@ -354,22 +241,20 @@ public class ASTGenerator {
}
//String paths[] = tehPaths.split(File.separatorChar +"");
StringTokenizer st = new StringTokenizer(tehPath.toString(),
File.pathSeparatorChar + "");
while (st.hasMoreElements()) {
System.out.println("- " + st.nextToken());
}
// StringTokenizer st = new StringTokenizer(tehPath.toString(),
// File.pathSeparatorChar + "");
classPath = factory.createFromPath(tehPath.toString());
for (String packageName : classPath.listPackages("")) {
System.out.println(packageName);
}
// for (String packageName : classPath.listPackages("")) {
// System.out.println(packageName);
// }
RegExpResourceFilter regExpResourceFilter = new RegExpResourceFilter(
".*",
"Vec3D.class");
String[] resources = classPath.findResources("", regExpResourceFilter);
for (String className : resources) {
System.out.println("-> " + className);
}
// String[] resources = classPath.findResources("", regExpResourceFilter);
// for (String className : resources) {
// System.out.println("-> " + className);
// }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
@@ -402,7 +287,7 @@ public class ASTGenerator {
//System.out.println(element.text());
// if (element.nextElementSibling() != null)
// System.out.println(element.nextElementSibling().text());
System.out.println("-------------------");
//System.out.println("-------------------");
msg = "<html><body> <strong><div style=\"width: 300px; text-justification: justify;\"></strong>"
+ element.html()
+ element.nextElementSibling()
@@ -432,10 +317,10 @@ public class ASTGenerator {
// }
}
System.out.println("JDoc loaded");
for (String key : jdocMap.keySet()) {
System.out.println("Method: " + key);
System.out.println("Method: " + jdocMap.get(key));
}
// for (String key : jdocMap.keySet()) {
// System.out.println("Method: " + key);
// System.out.println("Method: " + jdocMap.get(key));
// }
} catch (Exception e) {
e.printStackTrace();
}
@@ -491,14 +376,14 @@ public class ASTGenerator {
List<VariableDeclarationFragment> vdfs = null;
switch (node.getNodeType()) {
case ASTNode.TYPE_DECLARATION:
return new String[] { getNodeAsString(node) };
return new String[] { getNodeAsString2(node) };
case ASTNode.METHOD_DECLARATION:
String[] ret1 = new String[] { getNodeAsString(node) };
String[] ret1 = new String[] { getNodeAsString2(node) };
return ret1;
case ASTNode.SINGLE_VARIABLE_DECLARATION:
return new String[] { getNodeAsString(node) };
return new String[] { getNodeAsString2(node) };
case ASTNode.FIELD_DECLARATION:
vdfs = ((FieldDeclaration) node).fragments();
@@ -517,7 +402,7 @@ public class ASTGenerator {
String ret[] = new String[vdfs.size()];
int i = 0;
for (VariableDeclarationFragment vdf : vdfs) {
ret[i++] = getNodeAsString(vdf);
ret[i++] = getNodeAsString2(vdf);
}
return ret;
}
@@ -756,19 +641,19 @@ public class ASTGenerator {
.fragments();
for (VariableDeclarationFragment vdf : vdfs) {
if (noCompare) {
candidates.add(getNodeAsString(vdf));
candidates.add(getNodeAsString2(vdf));
} else if (vdf.getName().toString()
.startsWith(child.toString()))
candidates.add(getNodeAsString(vdf));
candidates.add(getNodeAsString2(vdf));
}
}
for (int i = 0; i < td.getMethods().length; i++) {
if (noCompare) {
candidates.add(getNodeAsString(td.getMethods()[i]));
candidates.add(getNodeAsString2(td.getMethods()[i]));
} else if (td.getMethods()[i].getName().toString()
.startsWith(child.toString()))
candidates.add(getNodeAsString(td.getMethods()[i]));
candidates.add(getNodeAsString2(td.getMethods()[i]));
}
} else {
if (stp != null) {
@@ -830,6 +715,7 @@ public class ASTGenerator {
}
String[][] candi = new String[candidates.size()][1];
for (int i = 0; i < candi.length; i++) {
candi[i][0] = candidates.get(i);
}
@@ -840,6 +726,13 @@ public class ASTGenerator {
tableAuto.setModel(tm);
tableAuto.validate();
tableAuto.repaint();
//String[] items =
String[] candi2 = candidates.toArray(new String[candidates
.size()]);
errorCheckerService
.getEditor()
.textArea()
.showSuggestion(candi2);
}
};
@@ -868,9 +761,11 @@ public class ASTGenerator {
for (Method method : probableClass.getMethods()) {
StringBuffer label = new StringBuffer(method.getName() + "(");
for (Class<?> type : method.getParameterTypes()) {
label.append(type.getSimpleName() + ",");
for (int i = 0; i < method.getParameterTypes().length; i++) {
if(i < method.getParameterTypes().length - 1)
label.append(method.getParameterTypes()[i].getSimpleName() + ",");
}
label.append(")");
if (noCompare)
candidates.add(label.toString());
@@ -891,26 +786,22 @@ public class ASTGenerator {
}
if (candidates.size() > 0) {
String methodmatch = candidates.get(0);
if(methodmatch.indexOf('(') != -1){
methodmatch = methodmatch.substring(0, methodmatch.indexOf('(') - 1);
}
System.out.println("jdoc match " + methodmatch);
for (final String key : jdocMap.keySet()) {
if (methodmatch.startsWith(key) && key.length() > 4) {
if (key.startsWith(methodmatch) && key.length() > 3) {
System.out.println("Matched jdoc" + key);
jdocLabel.setText(jdocMap.get(key));
visitRecur((ASTNode) compilationUnit.types().get(0), codeTree);
SwingWorker worker = new SwingWorker() {
//visitRecur((ASTNode) compilationUnit.types().get(0), codeTree);
SwingUtilities.invokeLater(new Runnable() {
@Override
protected Object doInBackground() throws Exception {
return null;
public void run() {
jdocLabel.setText(jdocMap.get(key));
}
protected void done() {
System.out.println(jdocMap.get(key));
jdocLabel.repaint();
}
};
worker.execute();
});
break;
}
}
@@ -1851,6 +1742,58 @@ public class ASTGenerator {
.getStartPosition());
return value;
}
/**
* CompletionPanel name
* @param node
* @return
*/
static private String getNodeAsString2(ASTNode node) {
if (node == null)
return "NULL";
String className = node.getClass().getName();
int index = className.lastIndexOf(".");
if (index > 0)
className = className.substring(index + 1);
// if(node instanceof BodyDeclaration)
// return className;
String value = className;
if (node instanceof TypeDeclaration)
value = ((TypeDeclaration) node).getName().toString();
else if (node instanceof MethodDeclaration)
value = ((MethodDeclaration) node).getName().toString();
else if (node instanceof MethodInvocation)
value = ((MethodInvocation) node).getName().toString() + " | "
+ className;
else if (node instanceof FieldDeclaration)
value = ((FieldDeclaration) node).toString();
else if (node instanceof SingleVariableDeclaration)
value = ((SingleVariableDeclaration) node).getName().toString() ;
else if (node instanceof ExpressionStatement)
value = node.toString() + className;
else if (node instanceof SimpleName)
value = ((SimpleName) node).getFullyQualifiedName() + " | " + className;
else if (node instanceof QualifiedName)
value = node.toString();
else if (node instanceof VariableDeclarationFragment)
value = ((VariableDeclarationFragment)node).getName().toString();
else if (className.startsWith("Variable"))
value = node.toString() ;
else if (node instanceof VariableDeclarationStatement)
value = ((VariableDeclarationStatement)node).toString();
else if (className.endsWith("Type"))
value = node.toString() ;
// value += " [" + node.getStartPosition() + ","
// + (node.getStartPosition() + node.getLength()) + "]";
// value += " Line: "
// + ((CompilationUnit) node.getRoot()).getLineNumber(node
// .getStartPosition());
return value;
}
public static String readFile(String path) {
BufferedReader reader = null;

View File

@@ -0,0 +1,144 @@
package processing.mode.experimental;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import processing.app.syntax.JEditTextArea;
public class CompletionPanel {
private JList list;
private JPopupMenu popupMenu;
private String subWord;
private final int insertionPosition;
private JEditTextArea textarea;
public CompletionPanel(JEditTextArea textarea, int position, String subWord,
String[] items, Point location) {
this.textarea = textarea;
this.insertionPosition = position;
if (subWord.indexOf('.') != -1)
this.subWord = subWord.substring(subWord.lastIndexOf('.') + 1);
else
this.subWord = subWord;
popupMenu = new JPopupMenu();
popupMenu.removeAll();
popupMenu.setOpaque(false);
popupMenu.setBorder(null);
popupMenu.add(list = createSuggestionList(position, items),
BorderLayout.CENTER);
popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0)
+ location.y);
}
public void hide() {
popupMenu.setVisible(false);
}
public boolean isVisible() {
return popupMenu.isVisible();
}
// private JList createSuggestionList(final int position, final String subWord) {
// Object[] data = new Object[10];
// for (int i = 0; i < data.length; i++) {
// data[i] = subWord + i * 10;
// }
// JList list = new JList(data);
// list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
// list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
// list.setSelectedIndex(0);
// list.addMouseListener(new MouseAdapter() {
// @Override
// public void mouseClicked(MouseEvent e) {
// if (e.getClickCount() == 2) {
// insertSelection();
// }
// }
// });
// return list;
// }
public JList createSuggestionList(final int position, final String[] items) {
JList list = new JList(items);
list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
insertSelection();
}
}
});
return list;
}
public boolean insertSelection() {
if (list.getSelectedValue() != null) {
try {
final String selectedSuggestion = ((String) list.getSelectedValue())
.substring(subWord.length());
textarea.getDocument().insertString(insertionPosition,
selectedSuggestion, null);
textarea.setCaretPosition(insertionPosition
+ selectedSuggestion.length());
return true;
} catch (BadLocationException e1) {
e1.printStackTrace();
}
hideSuggestion();
}
return false;
}
public void hideSuggestion() {
hide();
}
public void moveUp() {
if (list.getSelectedIndex() == 0) {
selectIndex(list.getModel().getSize() - 1);
} else {
int index = Math.max(list.getSelectedIndex() - 1, 0);
selectIndex(index);
}
}
public void moveDown() {
if (list.getSelectedIndex() == list.getModel().getSize() - 1) {
selectIndex(0);
} else {
int index = Math.min(list.getSelectedIndex() + 1, list.getModel()
.getSize() - 1);
selectIndex(index);
}
}
private void selectIndex(int index) {
list.setSelectedIndex(index);
// final int position = textarea.getCaretPosition();
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// textarea.setCaretPosition(position);
// };
// });
}
}

View File

@@ -733,7 +733,7 @@ public class ErrorCheckerService implements Runnable{
// String[] lines = {};// = PApplet.split(sourceString, '\n');
int codeIndex = 0;
int x = problem.getSourceLineNumber() - mainClassOffset + 1;
int x = problem.getSourceLineNumber() - mainClassOffset;
if (x < 0) {
// System.out.println("Negative line number "
// + problem.getSourceLineNumber() + " , offset "

View File

@@ -1,111 +0,0 @@
package processing.mode.experimental;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import processing.app.syntax.JEditTextArea;
public class SuggestionPanel {
private JList list;
private JPopupMenu popupMenu;
private String subWord;
private final int insertionPosition;
private JTextArea textarea;
public SuggestionPanel(JEditTextArea textarea, int position, String subWord,
Point location) {
this.insertionPosition = position;
this.subWord = subWord;
popupMenu = new JPopupMenu();
popupMenu.removeAll();
popupMenu.setOpaque(false);
popupMenu.setBorder(null);
popupMenu.add(list = createSuggestionList(position, subWord),
BorderLayout.CENTER);
popupMenu.show(textarea, location.x, textarea.getBaseline(0, 0)
+ location.y);
}
public void hide() {
popupMenu.setVisible(false);
// if (suggestion == this) {
// suggestion = null;
// }
}
private JList createSuggestionList(final int position, final String subWord) {
Object[] data = new Object[10];
for (int i = 0; i < data.length; i++) {
data[i] = subWord + i * 10;
}
JList list = new JList(data);
list.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
insertSelection();
}
}
});
return list;
}
public boolean insertSelection() {
if (list.getSelectedValue() != null) {
try {
final String selectedSuggestion = ((String) list.getSelectedValue())
.substring(subWord.length());
textarea.getDocument().insertString(insertionPosition,
selectedSuggestion, null);
return true;
} catch (BadLocationException e1) {
e1.printStackTrace();
}
hideSuggestion();
}
return false;
}
public void hideSuggestion() {
hide();
}
public void moveUp() {
int index = Math.min(list.getSelectedIndex() - 1, 0);
selectIndex(index);
}
public void moveDown() {
int index = Math.min(list.getSelectedIndex() + 1, list.getModel()
.getSize() - 1);
selectIndex(index);
}
private void selectIndex(int index) {
final int position = textarea.getCaretPosition();
list.setSelectedIndex(index);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textarea.setCaretPosition(position);
};
});
}
}

View File

@@ -20,14 +20,19 @@ package processing.mode.experimental;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.FontMetrics;
import java.awt.Point;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import processing.app.syntax.JEditTextArea;
import processing.app.syntax.TextAreaDefaults;
@@ -94,7 +99,7 @@ public class TextArea extends JEditTextArea {
MouseHandler mouseHandler = new MouseHandler();
painter.addMouseListener(mouseHandler);
painter.addMouseMotionListener(mouseHandler);
addCompletionPopupListner();
add(CENTER, painter);
// load settings from theme.txt
@@ -121,6 +126,44 @@ public class TextArea extends JEditTextArea {
}
public void processKeyEvent(KeyEvent evt) {
if (evt.getID() == KeyEvent.KEY_PRESSED) {
if (evt.getKeyCode() == KeyEvent.VK_DOWN && suggestion != null) {
if (suggestion.isVisible()) {
//System.out.println("KeyDown");
suggestion.moveDown();
return;
}
} else if (evt.getKeyCode() == KeyEvent.VK_UP && suggestion != null) {
if (suggestion.isVisible()) {
//System.out.println("KeyUp");
suggestion.moveUp();
return;
}
}
if (evt.getKeyChar() == KeyEvent.VK_ENTER) {
if (suggestion != null) {
if (suggestion.isVisible()){
if (suggestion.insertSelection()) {
final int position = getCaretPosition();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
//getDocument().remove(position - 1, 1);
} catch (Exception e) {
e.printStackTrace();
}
}
});
return;
}
}
}
} else if (evt.getKeyChar() == KeyEvent.VK_BACK_SPACE) {
System.out.println("BK Key");
}
}
super.processKeyEvent(evt);
if (evt.getID() == KeyEvent.KEY_TYPED) {
errorCheckerService.textModified.incrementAndGet();
@@ -181,9 +224,8 @@ public class TextArea extends JEditTextArea {
//TODO: currently works on single line only. "a. <new line> b()" won't be detected
if (x1 >= 0) {
// if (s.charAt(x1) != ';' && s.charAt(x1) != ',' && s.charAt(x1) != '(')
if (Character.isLetterOrDigit(s.charAt(x1)) || s.charAt(x1) == '_'
|| s.charAt(x1) == '.' || s.charAt(x1) == ')')
{
if (Character.isLetterOrDigit(s.charAt(x1)) || s.charAt(x1) == '_'
|| s.charAt(x1) == '.' || s.charAt(x1) == ')') {
if (s.charAt(x1) == ')') {
word = s.charAt(x1--) + word;
@@ -232,6 +274,7 @@ public class TextArea extends JEditTextArea {
// word = word.substring(0, word.length() - 1);
errorCheckerService.astGenerator.updatePredictions(word, line
+ errorCheckerService.mainClassOffset);
//showSuggestionLater();
return word;
//}
@@ -491,4 +534,95 @@ public class TextArea extends JEditTextArea {
}
}
private CompletionPanel suggestion;
//JEditTextArea textarea;
private void addCompletionPopupListner() {
this.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
if (Character.isLetterOrDigit(e.getKeyChar())
|| e.getKeyChar() == KeyEvent.VK_BACK_SPACE
|| e.getKeyChar() == KeyEvent.VK_DELETE) {
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// showSuggestion();
// }
//
// });
} else if (Character.isWhitespace(e.getKeyChar())) {
hideSuggestion();
}
}
@Override
public void keyPressed(KeyEvent e) {
}
});
}
public void showSuggestionLater(final String[] items) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showSuggestion(items);
}
});
}
protected void showSuggestion(String[] items) {
hideSuggestion();
final int position = getCaretPosition();
Point location = new Point();
try {
location.x = offsetToX(getCaretLine(), position
- getLineStartOffset(getCaretLine()));
location.y = lineToY(getCaretLine())
+ getPainter().getFontMetrics().getHeight();
} catch (Exception e2) {
e2.printStackTrace();
return;
}
String text = getText();
int start = Math.max(0, position - 1);
while (start > 0) {
if (!Character.isWhitespace(text.charAt(start))) {
start--;
} else {
start++;
break;
}
}
if (start > position) {
return;
}
final String subWord = text.substring(start, position);
if (subWord.length() < 2) {
return;
}
suggestion = new CompletionPanel(this, position, subWord, items, location);
requestFocusInWindow();
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
// requestFocusInWindow();
// }
// });
}
private void hideSuggestion() {
if (suggestion != null) {
suggestion.hide();
}
}
}