package com.devdaily.justwrite.view;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
/**
* Copyright 2010, Alvin Alexander, http://devdaily.com.
* This software is distributed under the terms of the
* GNU General Public License.
*
* This file is part of an application named JustWrite.
*
* JustWrite is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JustWrite is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JustWrite. If not, see <http://www.gnu.org/licenses/>.
*
* This is a very heavily-modified version of a class found in the Core
* Swing book.
*
*/
public class LookAheadTextPane extends JTextPane
{
public LookAheadTextPane()
{
this(null);
}
public LookAheadTextPane(int columns)
{
this(null);
}
public LookAheadTextPane(TextLookAhead lookAhead)
{
setLookAhead(lookAhead);
this.setPreferredSize(new Dimension(300, 200));
this.getDocument().addDocumentListener(new DocumentListener()
{
public void actionPerformed(ActionEvent evt)
{
// Remove any existing selection
setCaretPosition(getDocument().getLength());
}
public void changedUpdate(DocumentEvent e)
{
}
public void insertUpdate(DocumentEvent e)
{
}
public void removeUpdate(DocumentEvent e)
{
}
});
addFocusListener(new FocusListener()
{
public void focusGained(FocusEvent evt)
{
}
public void focusLost(FocusEvent evt)
{
if (evt.isTemporary() == false)
{
// Remove any existing selection
setCaretPosition(getDocument().getLength());
}
}
});
}
public void setLookAhead(TextLookAhead lookAhead)
{
this.lookAhead = lookAhead;
}
public TextLookAhead getLookAhead()
{
return lookAhead;
}
public String getDocumentText()
{
try
{
return getDocument().getText(0, getDocument().getLength());
}
catch (BadLocationException e)
{
e.printStackTrace();
return null;
}
}
public String getCurrentWordBeforeCursor()
{
Document doc = getDocument();
if (doc == null)
return null;
int charsToLookBack = 10;
int docLength = doc.getLength();
if (docLength < charsToLookBack)
charsToLookBack = docLength - 1;
String allTextBeforeCaretPosition = null;
String oldContent = null;
String charsSinceLastWhitespace = null;
try
{
allTextBeforeCaretPosition = doc.getText(0, getCaretPosition());
LastWhitespaceInfo info = findLastWhitespaceLocation(allTextBeforeCaretPosition);
if (info.lastWhitespaceLocation > 0 && doc.getLength() > (charsToLookBack - 1))
{
// get caret position
int caretPosition = getCaretPosition();
// look at last 10 characters
int scanBackPosition = caretPosition - charsToLookBack;
if (scanBackPosition <= 0)
return null;
String recentChars = doc.getText(scanBackPosition, charsToLookBack);
// if any characters are blanks, get the characters since the last blank
int lastWhitespacePosition = recentChars.lastIndexOf(info.lastWhitespaceString);
if (lastWhitespacePosition <= 0)
return null;
charsSinceLastWhitespace = recentChars.substring(lastWhitespacePosition + 1, charsToLookBack);
return charsSinceLastWhitespace;
}
else
{
return null;
}
}
catch (BadLocationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
/**
* Just use this to pass information back from the findLastWhitespaceLocation method.
*/
class LastWhitespaceInfo
{
int lastWhitespaceLocation;
String lastWhitespaceString;
}
private LastWhitespaceInfo findLastWhitespaceLocation(String string)
{
// find last whitespace character, and make sure I keep looking for that
// same character throughout the rest of the code
// REFACTOR THIS SECTION
int lastBlank = string.lastIndexOf(" ");
int lastTab = string.lastIndexOf("\t");
int lastNewline = string.lastIndexOf("\n");
int lastFF = string.lastIndexOf("\f");
int lastR = string.lastIndexOf("\r");
// get the last whitespace location
int lastWhitespaceLoc = 0;
String lastWhitespaceString = "";
if (lastBlank > lastTab && lastBlank > lastNewline)
{
lastWhitespaceLoc = lastBlank;
lastWhitespaceString = " ";
}
else if (lastTab > lastBlank && lastTab > lastNewline)
{
lastWhitespaceLoc = lastTab;
lastWhitespaceString = "\t";
}
else if (lastNewline > lastBlank && lastNewline > lastTab)
{
lastWhitespaceLoc = lastNewline;
lastWhitespaceString = "\n";
}
LastWhitespaceInfo info = new LastWhitespaceInfo();
info.lastWhitespaceLocation = lastWhitespaceLoc;
info.lastWhitespaceString = lastWhitespaceString;
return info;
}
public void replaceSelection(String content)
{
super.replaceSelection(content);
// TODO delete this commented-out block once i'm sure i don't need it any more.
// if (isEditable() == false || isEnabled() == false)
// {
// return;
// }
//
// Document doc = getDocument();
//
// int charsToLookBack = 10;
// if (doc != null && lookAhead != null)
// {
// try
// {
// // go back to previous whitespace
// int docLength = doc.getLength();
// if (docLength < charsToLookBack)
// charsToLookBack = docLength - 1;
// String recentDocText = null;
// String oldContent = null;
//
// recentDocText = doc.getText(0, getCaretPosition());
//
// // pass the look-ahead algorithm all of the doc except the
// // partial word you're currently working on
// // this may be a bad approach; need to look for whitespace at beginning
// // and
// // end of words, periods, etc.
// if (doc.getLength() > charsToLookBack)
// {
// lookAhead.setText(doc.getText(0, doc.getLength() - charsToLookBack));
// }
//
// // find last whitespace character, and make sure I keep looking for that
// // same character throughout the rest of the code
// // REFACTOR THIS SECTION
// int lastBlank = recentDocText.lastIndexOf(" ");
// int lastTab = recentDocText.lastIndexOf("\t");
// int lastNewline = recentDocText.lastIndexOf("\n");
// int lastFF = recentDocText.lastIndexOf("\f");
// int lastR = recentDocText.lastIndexOf("\r");
//
// int lastWhitespaceLoc = 0;
// String lastWhitespaceString = "";
// if (lastBlank > lastTab && lastBlank > lastNewline)
// {
// lastWhitespaceLoc = lastBlank;
// lastWhitespaceString = " ";
// }
// else if (lastTab > lastBlank && lastTab > lastNewline)
// {
// lastWhitespaceLoc = lastTab;
// lastWhitespaceString = "\t";
// }
// else if (lastNewline > lastBlank && lastNewline > lastTab)
// {
// lastWhitespaceLoc = lastNewline;
// lastWhitespaceString = "\n";
// }
//
// if (lastWhitespaceLoc > 0 && doc.getLength() > (charsToLookBack - 1))
// {
// // get caret position
// int caretPosition = getCaretPosition();
// // look at last 10 characters
// int scanBackPosition = caretPosition - charsToLookBack;
// if (scanBackPosition <= 0)
// return;
// String recentChars = doc.getText(scanBackPosition, charsToLookBack);
// // if any characters are blanks, get the characters since the last
// // blank
// int lastWhitespacePosition = recentChars.lastIndexOf(lastWhitespaceString);
// if (lastWhitespacePosition <= 0)
// return;
// String charsSinceLastBlank = recentChars.substring(lastWhitespacePosition + 1, charsToLookBack);
//
// String newContent = lookAhead.doLookAhead(charsSinceLastBlank);
// if (newContent != null)
// {
// int lengthOfAddedContent = newContent.length() - charsSinceLastBlank.length();
// String newContentSubstring = newContent.substring(charsSinceLastBlank.length(), newContent.length());
// doc.insertString(getCaretPosition(), newContentSubstring, null);
//
// // Highlight the added text
// setCaretPosition(caretPosition + lengthOfAddedContent);
// moveCaretPosition(caretPosition);
// }
// }
// else
// {
// oldContent = recentDocText;
// String newContent = lookAhead.doLookAhead(oldContent);
// if (newContent != null)
// {
// int lengthOld = oldContent.length();
// String newContentSubstring = newContent.substring(lengthOld);
// doc.insertString(getCaretPosition(), newContentSubstring, null);
//
// // Highlight the added text
// setCaretPosition(newContent.length());
// moveCaretPosition(oldContent.length());
// }
// }
//
// }
// catch (BadLocationException e)
// {
// System.err.println(e.getMessage());
// }
// }
}
protected TextLookAhead lookAhead;
// Move this out of here.
// The TextLookAhead interface
public interface TextLookAhead
{
public String doLookAhead(String key);
public void setText(String text);
public void addWord(String word);
}
}