package simplejavatexteditor;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
/**
* <h1>Auto complete functionality multiple programming languages, including brackets
and
* parentheses</h1>
*
* <p>
* An ArrayList is created for the keywords and the brackets.
* Logic for setting the content of the ArrayList is
* found in UI.java. If the word currently being typed
* matches a word in the list, a Runnable inner class is
* implemented to handle the word completion.
*
* Two other inner classes are also used. The second one handles when the enter
* key is pressed in response to an auto complete suggestion. The third one
* performs additional logic on brackets.
* </p>
*
*
* @author Patrick Slagle
* @since 2016-12-03
*/
public class AutoComplete
implements DocumentListener {
private ArrayList<String> brackets = new ArrayList<>();
private ArrayList<String> bracketCompletions = new ArrayList<>();
private ArrayList<String> words = new ArrayList<>();
SupportedKeywords kw;
//Keep track of when code completion
//has been activated
private enum Mode {
INSERT, COMPLETION
};
private final UI ui;
private Mode mode = Mode.INSERT;
private final JTextArea textArea;
private static final String COMMIT_ACTION = "commit";
private boolean isKeyword;
private int pos;
private String content;
public AutoComplete(UI ui, ArrayList<String> al) {
//Set the keywords
words = al;
kw = new SupportedKeywords();
brackets = kw.getbrackets();
bracketCompletions = kw.getbracketCompletions();
//Access the editor
this.ui = ui;
textArea = ui.getEditor();
//Set the handler for the enter key
InputMap im = textArea.getInputMap();
ActionMap am = textArea.getActionMap();
im.put(KeyStroke.getKeyStroke("ENTER "), COMMIT_ACTION);
am.put(COMMIT_ACTION, new CommitAction());
Collections.sort(words);
}
/**
* A character has been typed into the document.
* This method performs the primary
* check to find a keyword completion.
*
* @param e
*/
@Override
public void insertUpdate(DocumentEvent e) {
pos = e.getOffset();
content = null;
try {
content = textArea.getText(0, pos + 1);
} catch (BadLocationException ex) {
ex.printStackTrace();
}
if (e.getLength() != 1) {
return;
}
//Before checking for a keyword
checkForBracket();
//Get the beginning of the word being typed
int start;
for (start = pos; start >= 0; start--) {
if (!Character.isLetter(content.charAt(start))) {
break;
}
}
//Auto complete will start
//after two characters are typed
if (pos - start < 2) {
return;
}
//Search for a match on the word being typed
//in the keywords ArrayList
String prefix = content.substring(start + 1);
int n = Collections.binarySearch(words, prefix);
if (n < 0 && -n < words.size()) {
String match = words.get(-n - 1);
if (match.startsWith(prefix)) {
String completion = match.substring(pos - start);
isKeyword = true;
SwingUtilities.invokeLater(
new CompletionTask(completion, pos + 1));
} else {
mode = Mode.INSERT;
}
}
}
/**
* Performs a check to see if the last
* key typed was one of the supported
* bracket characters
*/
private void checkForBracket() {
//String of the last typed character
char c = content.charAt(pos);
String s = String.valueOf(c);
for (int i = 0; i < brackets.size(); i++) {
if (brackets.get(i).equals(s)) {
isKeyword = false;
SwingUtilities.invokeLater(
new CompletionTask(bracketCompletions.get(i), pos + 1));
}
}
}
/**
* So that future classes can view the keyword list in the future.
*
* @return the keywords
*/
private ArrayList<String> getKeywords() {
return words;
}
/**
* So that these keywords can be modified or added to in the future.
*
* @param keyword the keyword to set
*/
private void setKeywords(String keyword) {
words.add(keyword);
}
/**
* Handles the auto complete suggestion
* generated when the user is typing a
* word that matches a keyword.
*/
private class CompletionTask
implements Runnable {
private final String completion;
private final int position;
public CompletionTask(String completion, int position) {
this.completion = completion;
this.position = position;
}
@Override
public void run() {
textArea.insert(completion, position);
textArea.setCaretPosition(position + completion.length());
textArea.moveCaretPosition(position);
mode = Mode.COMPLETION;
if (!isKeyword) {
textArea.addKeyListener(new HandleBracketEvent());
}
}
}
/**
* Enter key is pressed in response to an
* auto complete suggestion. Respond
* appropriately.
*/
private class CommitAction
extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
if (mode == Mode.COMPLETION) {
int pos = textArea.getSelectionEnd();
if (isKeyword) {
textArea.insert(" ", pos);
textArea.setCaretPosition(pos + 1);
mode = Mode.INSERT;
}
} else {
mode = Mode.INSERT;
textArea.replaceSelection("n");
}
}
}
/**
* Additional logic for bracket auto complete
*/
private class HandleBracketEvent
implements KeyListener {
@Override
public void keyTyped(KeyEvent e) {
//Bracket auto complete needs special attention.
//Multiple possible responses are needed.
String keyEvent = String.valueOf(e.getKeyChar());
for (String bracketCompletion : bracketCompletions) {
if (keyEvent.equals(bracketCompletion)) {
textArea.replaceRange("", pos, pos + 1);
mode = Mode.INSERT;
textArea.removeKeyListener(this);
}
}
int currentPosition = textArea.getCaretPosition();
switch (e.getKeyChar()) {
case 'n':
textArea.insert("nn", currentPosition);
textArea.setCaretPosition(currentPosition + 1);
mode = Mode.INSERT;
textArea.removeKeyListener(this);
break;
default:
textArea.setCaretPosition(pos);
mode = Mode.INSERT;
textArea.removeKeyListener(this);
break;
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
@Override
public void removeUpdate(DocumentEvent e) {
}
@Override
public void changedUpdate(DocumentEvent e) {
}
mode = Mode.INSERT;
textArea.removeKeyListener(this);
break;
}
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
@Override
public void removeUpdate(DocumentEvent e) {
}
@Override
public void changedUpdate(DocumentEvent e) {
}

More Related Content

PDF
Martin Anderson - threads v actors
PPTX
React hooks
PPTX
Typescript barcelona
PPT
Krazykoder struts2 interceptors
PDF
Software Development Lab test 3
PPTX
4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)
Martin Anderson - threads v actors
React hooks
Typescript barcelona
Krazykoder struts2 interceptors
Software Development Lab test 3
4.Spring IoC&DI(Spring Ioc실습_어노테이션 기반)

What's hot (20)

PDF
Works Applications Test - Chinmay Chauhan
PPTX
Reactive programming with RxAndroid
PDF
Workshop 19: ReactJS Introduction
PPT
Swiss army knife Spring
PPT
Unit Testing in iOS - Ninjava Talk
PPTX
Angular2 + rxjs
PPTX
Java scriptfunction
PDF
Intro to Asynchronous Javascript
PDF
KEY
Gwt and Xtend
PDF
Auto-GWT : Better GWT Programming with Xtend
ODP
Android training day 4
PPT
Executing Sql Commands
PDF
Completable future
PPT
Call Back
PPTX
React Hooks
PDF
PLSQL Note
PDF
Saving lives with rx java
DOCX
Parallel Programming With Dot Net
Works Applications Test - Chinmay Chauhan
Reactive programming with RxAndroid
Workshop 19: ReactJS Introduction
Swiss army knife Spring
Unit Testing in iOS - Ninjava Talk
Angular2 + rxjs
Java scriptfunction
Intro to Asynchronous Javascript
Gwt and Xtend
Auto-GWT : Better GWT Programming with Xtend
Android training day 4
Executing Sql Commands
Completable future
Call Back
React Hooks
PLSQL Note
Saving lives with rx java
Parallel Programming With Dot Net
Ad

Viewers also liked (16)

PPT
"Il web in classe" Seminario StudioLingua - 1 febbraio 2014
PPTX
Respect_SRZ
PPTX
Respect_SRZ
PDF
Trade-Watch - Issue 66 - November 2016
PDF
An Assessment of Image Matching Algorithms in Depth Estimation
PDF
Little Book of Stresscipes, by KFB Law
PDF
LSE_Article_Michelangelo_Ambrosini
PDF
Posibn vybory 2015
PDF
Distributed, not Disconnected: Employee Engagement for Remote Companies
PDF
Openday2016 avviare un'impresa nel food
PDF
Openday2016 Ca De Memi
PPT
ANDROID FDP PPT
PDF
Impact of Technical Performance on Pilotage & Port Operations - By Ali Asad Ali
PDF
Bahiru Tefera updated CV;2016
PDF
Tesi di laurea di Josip Mihovilović
PDF
resume (6)
"Il web in classe" Seminario StudioLingua - 1 febbraio 2014
Respect_SRZ
Respect_SRZ
Trade-Watch - Issue 66 - November 2016
An Assessment of Image Matching Algorithms in Depth Estimation
Little Book of Stresscipes, by KFB Law
LSE_Article_Michelangelo_Ambrosini
Posibn vybory 2015
Distributed, not Disconnected: Employee Engagement for Remote Companies
Openday2016 avviare un'impresa nel food
Openday2016 Ca De Memi
ANDROID FDP PPT
Impact of Technical Performance on Pilotage & Port Operations - By Ali Asad Ali
Bahiru Tefera updated CV;2016
Tesi di laurea di Josip Mihovilović
resume (6)
Ad

AutoComplete

  • 1. package simplejavatexteditor; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Collections; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; /** * <h1>Auto complete functionality multiple programming languages, including brackets and * parentheses</h1> * * <p> * An ArrayList is created for the keywords and the brackets. * Logic for setting the content of the ArrayList is * found in UI.java. If the word currently being typed * matches a word in the list, a Runnable inner class is * implemented to handle the word completion. * * Two other inner classes are also used. The second one handles when the enter * key is pressed in response to an auto complete suggestion. The third one * performs additional logic on brackets. * </p> * * * @author Patrick Slagle * @since 2016-12-03 */ public class AutoComplete implements DocumentListener { private ArrayList<String> brackets = new ArrayList<>(); private ArrayList<String> bracketCompletions = new ArrayList<>(); private ArrayList<String> words = new ArrayList<>(); SupportedKeywords kw; //Keep track of when code completion //has been activated private enum Mode {
  • 2. INSERT, COMPLETION }; private final UI ui; private Mode mode = Mode.INSERT; private final JTextArea textArea; private static final String COMMIT_ACTION = "commit"; private boolean isKeyword; private int pos; private String content; public AutoComplete(UI ui, ArrayList<String> al) { //Set the keywords words = al; kw = new SupportedKeywords(); brackets = kw.getbrackets(); bracketCompletions = kw.getbracketCompletions(); //Access the editor this.ui = ui; textArea = ui.getEditor(); //Set the handler for the enter key InputMap im = textArea.getInputMap(); ActionMap am = textArea.getActionMap(); im.put(KeyStroke.getKeyStroke("ENTER "), COMMIT_ACTION); am.put(COMMIT_ACTION, new CommitAction()); Collections.sort(words); } /** * A character has been typed into the document. * This method performs the primary * check to find a keyword completion. * * @param e */ @Override public void insertUpdate(DocumentEvent e) { pos = e.getOffset(); content = null; try { content = textArea.getText(0, pos + 1); } catch (BadLocationException ex) { ex.printStackTrace(); } if (e.getLength() != 1) { return; }
  • 3. //Before checking for a keyword checkForBracket(); //Get the beginning of the word being typed int start; for (start = pos; start >= 0; start--) { if (!Character.isLetter(content.charAt(start))) { break; } } //Auto complete will start //after two characters are typed if (pos - start < 2) { return; } //Search for a match on the word being typed //in the keywords ArrayList String prefix = content.substring(start + 1); int n = Collections.binarySearch(words, prefix); if (n < 0 && -n < words.size()) { String match = words.get(-n - 1); if (match.startsWith(prefix)) { String completion = match.substring(pos - start); isKeyword = true; SwingUtilities.invokeLater( new CompletionTask(completion, pos + 1)); } else { mode = Mode.INSERT; } } } /** * Performs a check to see if the last * key typed was one of the supported * bracket characters */ private void checkForBracket() { //String of the last typed character char c = content.charAt(pos); String s = String.valueOf(c); for (int i = 0; i < brackets.size(); i++) { if (brackets.get(i).equals(s)) { isKeyword = false; SwingUtilities.invokeLater( new CompletionTask(bracketCompletions.get(i), pos + 1));
  • 4. } } } /** * So that future classes can view the keyword list in the future. * * @return the keywords */ private ArrayList<String> getKeywords() { return words; } /** * So that these keywords can be modified or added to in the future. * * @param keyword the keyword to set */ private void setKeywords(String keyword) { words.add(keyword); } /** * Handles the auto complete suggestion * generated when the user is typing a * word that matches a keyword. */ private class CompletionTask implements Runnable { private final String completion; private final int position; public CompletionTask(String completion, int position) { this.completion = completion; this.position = position; } @Override public void run() { textArea.insert(completion, position); textArea.setCaretPosition(position + completion.length()); textArea.moveCaretPosition(position); mode = Mode.COMPLETION; if (!isKeyword) { textArea.addKeyListener(new HandleBracketEvent()); } } } /**
  • 5. * Enter key is pressed in response to an * auto complete suggestion. Respond * appropriately. */ private class CommitAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { if (mode == Mode.COMPLETION) { int pos = textArea.getSelectionEnd(); if (isKeyword) { textArea.insert(" ", pos); textArea.setCaretPosition(pos + 1); mode = Mode.INSERT; } } else { mode = Mode.INSERT; textArea.replaceSelection("n"); } } } /** * Additional logic for bracket auto complete */ private class HandleBracketEvent implements KeyListener { @Override public void keyTyped(KeyEvent e) { //Bracket auto complete needs special attention. //Multiple possible responses are needed. String keyEvent = String.valueOf(e.getKeyChar()); for (String bracketCompletion : bracketCompletions) { if (keyEvent.equals(bracketCompletion)) { textArea.replaceRange("", pos, pos + 1); mode = Mode.INSERT; textArea.removeKeyListener(this); } } int currentPosition = textArea.getCaretPosition(); switch (e.getKeyChar()) { case 'n': textArea.insert("nn", currentPosition); textArea.setCaretPosition(currentPosition + 1); mode = Mode.INSERT; textArea.removeKeyListener(this); break; default: textArea.setCaretPosition(pos);
  • 6. mode = Mode.INSERT; textArea.removeKeyListener(this); break; } } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } } @Override public void removeUpdate(DocumentEvent e) { } @Override public void changedUpdate(DocumentEvent e) { }
  • 7. mode = Mode.INSERT; textArea.removeKeyListener(this); break; } } @Override public void keyPressed(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } } @Override public void removeUpdate(DocumentEvent e) { } @Override public void changedUpdate(DocumentEvent e) { }