我有一个eclipse插件RCP应用程序,我想在SWT浏览器小部件上使用拼写检查器。只是检查是否有人知道如何实现这个或者是否有内置的东西。
答案 0 :(得分:0)
@ tm.sauron这是很久以前所以我不得不看一个旧项目。如果我没记错的话,我最终创造了自己的。我创建了一个Dialog,当我在富文本编辑器中单击拼写检查图标时会打开该对话框。我将代码粘贴到对话框和实际的拼写检查器类中。希望你能看到我在做什么并想出来。
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.regex.Pattern;
import org.eclipse.epf.richtext.IRichText;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class SpellCheckerDialog extends BaseDialog {
private SpellChecker spellChecker;
private Queue<String> misspelledWords = new LinkedList<String>();
private Text wrongWord;
private List suggestedWords;
private Button ignoreButton;
private Button changeButton;
private IgnoreButtonListener ignoreButtonListener = new IgnoreButtonListener();
private ChangeButtonListener changeButtonListener = new ChangeButtonListener();
private ModifiedChangeButtonListener modifiedChangeButtonListener = new ModifiedChangeButtonListener();
private ModifiedIgnoreButtonListener modifiedIgnoreButtonListener = new ModifiedIgnoreButtonListener();
private String oldWrongWord;
private int currentWord = 1;
private int totalWords;
private IRichText richText;
private String noHTMLString;
public SpellCheckerDialog(Shell parent, IRichText richText) {
super(parent);
setShellStyle(SWT.DIALOG_TRIM | SWT.MODELESS | getDefaultOrientation());
this.richText = richText;
if (richText != null) {
/* Instantiate spell checker */
try {
spellChecker = new SpellChecker();
findMisspelledWords();
} catch (URISyntaxException e) {
MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Dictionary file for rich text editor not found", e.getMessage());
e.printStackTrace();
} catch (IOException e) {
MessageDialog.openInformation(Display.getDefault().getActiveShell(), "Dictionary file for rich text editor not found", e.getMessage());
e.printStackTrace();
}
}
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
composite.setLayout(new GridLayout(2, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
/* Not in dictionary label */
new Label(composite, SWT.NONE).setText("Not in Dictionary:");
new Label(composite, SWT.NONE);
/* Current Misspelled Word */
wrongWord = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.WRAP | SWT.V_SCROLL);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.heightHint = 75;
gd.minimumHeight = 75;
wrongWord.setLayoutData(gd);
wrongWord.addKeyListener(new WrongWordKeyListener());
wrongWord.addFocusListener(new WrongWordFocusListener());
/* Ignore Button Actions */
GridData buttonCompositeGridData = new GridData(SWT.FILL, SWT.FILL, false, true);
buttonCompositeGridData.widthHint = 125;
Composite topButtonActionsComposite = new Composite(composite, SWT.NONE);
topButtonActionsComposite.setLayout(new GridLayout());
topButtonActionsComposite.setLayoutData(buttonCompositeGridData);
ignoreButton = new Button(topButtonActionsComposite, SWT.PUSH);
ignoreButton.setText("Ignore");
ignoreButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
ignoreButton.addSelectionListener(ignoreButtonListener);
/* Suggestions label */
new Label(composite, SWT.NONE).setText("Suggestions:");
new Label(composite, SWT.NONE);
/* Suggested Words */
suggestedWords = new List(composite, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE);
suggestedWords.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
/* Change Button Actions */
Composite bottomButtonActionsComposite = new Composite(composite, SWT.NONE);
bottomButtonActionsComposite.setLayout(new GridLayout());
bottomButtonActionsComposite.setLayoutData(buttonCompositeGridData);
changeButton = new Button(bottomButtonActionsComposite, SWT.PUSH);
changeButton.setText("Change");
changeButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
changeButton.addSelectionListener(changeButtonListener);
startSpellChecking();
return composite;
}
private void startSpellChecking() {
if (!misspelledWords.isEmpty()) {
super.getShell().setText("Spell Checker (" + currentWord + "/" + totalWords + ")");
String firstWord = misspelledWords.poll();
HashMap<Integer, String> suggestions = spellChecker.suggestions(firstWord);
/* get order of suggestions */
java.util.List<Integer> sortedKeys = asSortedList(suggestions.keySet());
wrongWord.setText(firstWord);
suggestedWords.removeAll();
for (Integer i : sortedKeys) {
suggestedWords.add(suggestions.get(i));
}
/* if there are no suggestions */
if (suggestions.size() == 0) {
suggestedWords.add("No Suggestions");
changeButton.setEnabled(false);
} else {
changeButton.setEnabled(true);
}
suggestedWords.select(0);
currentWord++;
} else {
MessageDialog.openInformation(Display.getDefault().getActiveShell(), "No Misspellings", "There were no more misspelled words found.");
super.close();
}
}
private void findMisspelledWords() {
misspelledWords.clear();
/* Get all words in textfield */
String[] cleanWords = cleanText(richText.getText());
for(String w:cleanWords){
System.out.println(w);
}
for (String word : cleanWords) {
if (!word.equals(" ") && !word.isEmpty()) {
if (!spellChecker.isInDictionary(word)) {
misspelledWords.add(word);
}
}
}
totalWords = misspelledWords.size();
}
/**
* removes html content, new line characters, white spaces at the beginning
* or end of words, punctuation or non-letters, makes lowercase because that
* is what the dictionary works with
*
* @param text
* @return
*/
private String[] cleanText(String text) {
/* Remove html */
noHTMLString = text.replaceAll("\\<.*?>", "");
noHTMLString = noHTMLString.replaceAll("&.*?;", "");
if (noHTMLString.contains("<")) {
int length = 0;
while (noHTMLString.length() != length) {
length = htmlTagRemoval(noHTMLString);
}
System.out.println("after manual removal noHTMLString: " + noHTMLString);
}
/* Remove New Lines */
noHTMLString = noHTMLString.replaceAll("[\\t\\n\\r]", " ");
String[] allWords = noHTMLString.split(" ");
java.util.List<String> cleanedAllWords = new ArrayList<String>();
for (String word : allWords) {
/* remove white spaces */
word = word.trim();
/* remove non letters */
if (!containsOnlyLetters(word)) {
word = removeNonLetters(word);
}
cleanedAllWords.add(word);
}
/* Make all lowercase */
for (int i = 0; i < cleanedAllWords.size(); i++) {
cleanedAllWords.set(i, cleanedAllWords.get(i).toLowerCase());
}
return cleanedAllWords.toArray(new String[cleanedAllWords.size()]);
}
private int htmlTagRemoval(String string) {
int i = 0;
Integer start = null, end = null;
for (i = 0; i < string.length(); i++) {
if (string.toCharArray()[i] == '<') {
start = i;
}
if (start != null && string.toCharArray()[i] == '>') {
end = i;
noHTMLString = string.replace(string.subSequence(start, end + 1), "");
break;
}
}
return i;
}
private boolean containsOnlyLetters(String s) {
if (Pattern.matches("[a-zA-Z]+", s)) {
return true;
} else {
return false;
}
}
private String removeNonLetters(String s) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i)) || s.charAt(i) == '\'') {
sb = sb.append(s.charAt(i));
}
}
return sb.toString();
}
private class WrongWordKeyListener extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
/*
* Disable suggested words and change ignore button to undo button
* and the change button listener
*/
suggestedWords.setEnabled(false);
ignoreButton.setEnabled(true);
ignoreButton.setText("Undo Edit");
ignoreButton.removeSelectionListener(ignoreButtonListener);
ignoreButton.addSelectionListener(modifiedIgnoreButtonListener);
changeButton.setEnabled(true);
changeButton.removeSelectionListener(changeButtonListener);
changeButton.addSelectionListener(modifiedChangeButtonListener);
wrongWord.removeKeyListener(this);
}
}
/**
* This stors the old word incase the user wants to undo the edit later.
*
* @author Will
*
*/
private class WrongWordFocusListener extends FocusAdapter {
@Override
public void focusGained(FocusEvent e) {
oldWrongWord = wrongWord.getText();
super.focusGained(e);
}
}
private class IgnoreButtonListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
// go to next word
startSpellChecking();
}
}
private class ChangeButtonListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
String newWord = suggestedWords.getSelection()[0];
// change old word
String correctedChanges = richText.getText().replace(wrongWord.getText(), newWord);
richText.setText(correctedChanges);
// next word
startSpellChecking();
}
}
/**
* This is used when the user manually edits the misspelled word and changes
* it
*
* @author Will
*
*/
private class ModifiedChangeButtonListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
String newWord = wrongWord.getText();
// change old word
String correctedChanges = richText.getText().replace(oldWrongWord, newWord);
richText.setText(correctedChanges);
ignoreButton.setText("Ignore");
ignoreButton.removeSelectionListener(modifiedIgnoreButtonListener);
ignoreButton.addSelectionListener(ignoreButtonListener);
changeButton.removeSelectionListener(modifiedChangeButtonListener);
changeButton.addSelectionListener(changeButtonListener);
suggestedWords.setEnabled(true);
wrongWord.addKeyListener(new WrongWordKeyListener());
// next word
startSpellChecking();
}
}
/**
* This is used when the user manually edits the misspelled word and wants
* to undo changes
*
* @author Will
*
*/
private class ModifiedIgnoreButtonListener extends SelectionAdapter {
@Override
public void widgetSelected(SelectionEvent e) {
/*
* rename ignore button, fix listeners on both buttons, enable
* suggested words, undo edit, add modify listener back
*/
ignoreButton.setText("Ignore");
ignoreButton.removeSelectionListener(modifiedIgnoreButtonListener);
ignoreButton.addSelectionListener(ignoreButtonListener);
changeButton.removeSelectionListener(modifiedChangeButtonListener);
changeButton.addSelectionListener(changeButtonListener);
suggestedWords.setEnabled(true);
wrongWord.setText(oldWrongWord);
wrongWord.addKeyListener(new WrongWordKeyListener());
if (suggestedWords.getItem(0).equals("No Suggestions")) {
changeButton.setEnabled(false);
}
}
}
private static <T extends Comparable<? super T>> java.util.List<T> asSortedList(Collection<T> c) {
java.util.List<T> list = new ArrayList<T>(c);
java.util.Collections.sort(list);
java.util.Collections.reverse(list);
return list;
}
@Override
protected Control createButtonBar(Composite parent) {
return null;
}
@Override
protected Point getInitialSize() {
Point size = super.getInitialSize();
size.x = 500;
size.y = 350;
return size;
}
}
这是SpellChecker类:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.epf.richtext.RichTextPlugin;
import org.osgi.framework.Bundle;
class SpellChecker {
private final HashMap<String, Integer> nWords = new HashMap<String, Integer>();
public SpellChecker() throws URISyntaxException, IOException {
Bundle bundle = RichTextPlugin.getDefault().getBundle();
URL fileURL = bundle.getEntry("files/dictionary.txt");
File file = null;
file = new File(FileLocator.resolve(fileURL).toURI());
BufferedReader in = new BufferedReader(new FileReader(file));
Pattern p = Pattern.compile("\\w+");
for (String temp = ""; temp != null; temp = in.readLine()) {
Matcher m = p.matcher(temp.toLowerCase());
while (m.find())
nWords.put((temp = m.group()), nWords.containsKey(temp) ? nWords.get(temp) + 1 : 1);
}
in.close();
}
public boolean isInDictionary(String word){
return nWords.containsKey(word) ? true : false;
}
private final ArrayList<String> edits(String word) {
ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i < word.length(); ++i)
result.add(word.substring(0, i) + word.substring(i + 1));
for (int i = 0; i < word.length() - 1; ++i)
result.add(word.substring(0, i) + word.substring(i + 1, i + 2) + word.substring(i, i + 1) + word.substring(i + 2));
for (int i = 0; i < word.length(); ++i)
for (char c = 'a'; c <= 'z'; ++c)
result.add(word.substring(0, i) + String.valueOf(c) + word.substring(i + 1));
for (int i = 0; i <= word.length(); ++i)
for (char c = 'a'; c <= 'z'; ++c)
result.add(word.substring(0, i) + String.valueOf(c) + word.substring(i));
return result;
}
public final String correct(String word) {
if (nWords.containsKey(word))
return word;
ArrayList<String> list = edits(word);
HashMap<Integer, String> candidates = new HashMap<Integer, String>();
for (String s : list)
if (nWords.containsKey(s))
candidates.put(nWords.get(s), s);
if (candidates.size() > 0)
return candidates.get(Collections.max(candidates.keySet()));
for (String s : list)
for (String w : edits(s))
if (nWords.containsKey(w))
candidates.put(nWords.get(w), w);
return candidates.size() > 0 ? candidates.get(Collections.max(candidates.keySet())) : word;
}
public final HashMap<Integer, String> suggestions(String word) {
if (nWords.containsKey(word)) {
HashMap<Integer, String> wordMap = new HashMap<Integer, String>();
wordMap.put(1, word);
return wordMap;
}
ArrayList<String> list = edits(word);
HashMap<Integer, String> candidates = new HashMap<Integer, String>();
for (String s : list)
if (nWords.containsKey(s))
candidates.put(nWords.get(s), s);
if (candidates.size() > 0)
return candidates;
for (String s : list)
for (String w : edits(s))
if (nWords.containsKey(w))
candidates.put(nWords.get(w), w);
return candidates;
}
}