gpt4 book ai didi

java - 键入时,从存储的现有文本中将单词(文本)插入到 JTextArea 中

转载 作者:行者123 更新时间:2023-12-02 08:48:33 25 4
gpt4 key购买 nike

我正在寻求您的帮助来解决我目前正在解决的问题。

有没有办法在文本区域中键入内容时,从存储的现有文本(如字典)中逐字(文本)插入到 JTextArea 中?

应该使用KeyTyped或其他一些技术......

最佳答案

基于 @GuillaumePolet 提供的可运行代码,位于此 SO Post .

我对这段代码进行了一点修改,以便它可以从单词列表文件中提取 10 个特定单词,并将它们显示在编辑插入符当前位置附近的弹出列表中。您可以完成输入或使用鼠标从显示的弹出列表中双击所需的单词,也可以使用光标和 Enter 键执行相同的操作。

enter image description here

您使用的单词列表由您决定。我只是从网上抄了一篇,共124390字。只需向 dictionaryFilePath String 成员变量提供要使用的字典文本文件的路径和文件名即可。该变量位于 SuggestionPanel 内部类中。这是完整的可运行代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextArea;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.BadLocationException;


public class WordAssist {

public class SuggestionPanel {

private final JList<String> list;
private final JPopupMenu popupMenu;
private final String subWord;
private final int insertionPosition;

private String dictionaryFilePath = "French_Dictionary.txt";
private int numberOfWordsInList = 10;
private Color colorOfList = Color.decode("#FBFEC3"); // Light-Yellow (default)
private Color colorOfListText = Color.decode("#000000"); // Black (default)
private String listFontName = Font.SANS_SERIF;
private int listFontStyle = Font.PLAIN;
private int listFontSize = 11;
private Font listFont = new Font(listFontName, listFontStyle, listFontSize);
private Locale locale = Locale.FRANCE;
public String characterEncoding = "UTF-8";

public SuggestionPanel(JTextArea 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<String> createSuggestionList(final int position, final String subWord) {
String[] data = searchForWord(dictionaryFilePath, subWord + "*", numberOfWordsInList);
if (data.length == 0) {
data = new String[2];
data[0] = " : Unknown Word : ";
data[1] = "Add To Dictionary";
}
JList<String> assistList = new JList<>(data);
assistList.setFont(new Font(listFontName, listFontStyle, listFontSize));
assistList.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
assistList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
assistList.setBackground(colorOfList);
assistList.setForeground(colorOfListText);
if (data.length == 2 && data[0].equalsIgnoreCase("unknown word:")) {
assistList.setSelectedIndex(1);
}
else {
assistList.setSelectedIndex(0);
}
assistList.addMouseListener(new MouseAdapter() {
@Override
@SuppressWarnings("Convert2Lambda")
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 1 && list.getSelectedValue().equalsIgnoreCase("add to dictionary")) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
addToDictionary(dictionaryFilePath, subWord, characterEncoding, locale);
}
});
hideSuggestion();
textarea.requestFocus();
}
if (e.getClickCount() == 2) {
insertSelection();
hideSuggestion();
textarea.requestFocus();
}
}
});
return assistList;
}

/**
* Adds the supplied word to the supplied Dictionary text file but only
* if it doesn't already exist. The dictionary text file must be
* formated in such a manner that each line of that file must contain
* only one word.
*
* @param dictionaryPath (String) The path and file name to the
* Dictionary text file.<br>
*
* @param wordToAdd (String) The word to add to dictionary.<br>
*
* @param characterEncoding (String) The Character encoding to use for Dictionary:<pre>
*
* Example: "UTF-8"</pre><br>
*
* See:
* <b>https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html</b>
* for all the supported Encodings.<br>
*
* @param locale (Locale) The Locale of the dictionary file.
* This is also important for sorting so that
* it too is done according to the proper locale.<pre>
* Example: Locale.FRANCE or Locale.US;</pre>
*
*/
public void addToDictionary(String dictionaryPath, String wordToAdd, String characterEncoding, Locale locale) {
if (dictionaryPath.trim().equals("") || wordToAdd.trim().equals("")) {
return;
}
wordToAdd = wordToAdd.trim();

String savePath = new File(dictionaryPath).getAbsolutePath();
savePath = savePath.substring(0, savePath.lastIndexOf(File.separator))
+ File.separator + "tmpDictFile.txt";

try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(dictionaryPath), characterEncoding))) {
OutputStream os = new FileOutputStream(savePath);
// PrintWriter writer = new PrintWriter(savePath)) {
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(os, characterEncoding))) {
// PrintWriter writer = new PrintWriter(savePath)) {
String addwordFirstChar = wordToAdd.substring(0, 1);

Collator collator = Collator.getInstance(locale);
collator.setStrength(Collator.PRIMARY);

List<String> wordList = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.equals("")) {
continue;
}
String firstChar = line.substring(0, 1);
if (firstChar.equals(firstChar.toUpperCase())
&& addwordFirstChar.equals(addwordFirstChar.toUpperCase())
&& collator.equals(firstChar, addwordFirstChar)) {
wordList.clear();
wordList.add(wordToAdd);
wordList.add(line);
// Add to uppercase section of file...
while ((line = reader.readLine()) != null || !firstChar.equals(firstChar.toUpperCase())) {
firstChar = line.substring(0, 1);
if (firstChar.equals(firstChar.toUpperCase())
&& !collator.equals(firstChar, addwordFirstChar)) {
break;
}
wordList.add(line);
}
Set<String> strSet = new HashSet<>(wordList);
wordList.clear();
wordList.addAll(strSet);

Collections.sort(wordList, collator);

for (String wrds : wordList) {
writer.println(wrds);
}
writer.println(line);
}
else if (firstChar.equals(firstChar.toLowerCase())
&& addwordFirstChar.equals(addwordFirstChar.toUpperCase())
&& collator.equals(firstChar, addwordFirstChar.toLowerCase())) {
wordList.clear();
if (!wordList.contains(wordToAdd.toLowerCase())) {
wordList.add(wordToAdd.toLowerCase());
}
wordList.add(line.toLowerCase());
// Add to lowercase section of file...
while ((line = reader.readLine()) != null) {
firstChar = line.substring(0, 1);
if (collator.equals(firstChar, addwordFirstChar.toLowerCase())) {
break;
}
wordList.add(line);
}
Set<String> strSet = new HashSet<>(wordList);
wordList.clear();
wordList.addAll(strSet);

Collections.sort(wordList, collator);

for (String wrds : wordList) {
writer.println(wrds);
}
writer.println(line);
}
else if (firstChar.equals(firstChar.toLowerCase())
&& addwordFirstChar.equals(addwordFirstChar.toLowerCase())
&& collator.equals(firstChar, addwordFirstChar)) {
wordList.clear();
if (!wordList.contains(wordToAdd)) {
wordList.add(wordToAdd);
}
wordList.add(line);
// Add to dictionary file...
while ((line = reader.readLine()) != null || !firstChar.equals(firstChar.toUpperCase())) {
firstChar = line.substring(0, 1);
if (!collator.equals(firstChar, addwordFirstChar)) {
break;
}
wordList.add(line);
}
Set<String> strSet = new HashSet<>(wordList);
wordList.clear();
wordList.addAll(strSet);

Collections.sort(wordList, collator);

for (String wrds : wordList) {
writer.println(wrds);
}
writer.println(line);
}
else {
writer.println(line);
}
}
}
}
catch (FileNotFoundException ex) {
System.err.println(ex);
}
catch (UnsupportedEncodingException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}

if (new File(savePath).exists()) {
if (new File(dictionaryPath).delete()) {
if (!new File(savePath).renameTo(new File(dictionaryPath))) {
System.err.println("Could not add the word: " + wordToAdd
+ " to Dictionary!");
}
}
}
}

@SuppressWarnings({"CallToPrintStackTrace", "Convert2Lambda"})
public boolean insertSelection() {
if (list.getSelectedValue() != null) {
try {
if (list.getSelectedValue().equalsIgnoreCase("add to dictionary")) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
addToDictionary(dictionaryFilePath, subWord, characterEncoding, locale);
}
});
hideSuggestion();
textarea.requestFocus();
return true;
}
else {
final String selectedSuggestion = list.getSelectedValue().substring(subWord.length());
textarea.getDocument().insertString(insertionPosition, selectedSuggestion, null);
return true;
}
}
catch (BadLocationException e1) {
e1.printStackTrace();
}
hideSuggestion();
}
return false;
}

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);
}

@SuppressWarnings("Convert2Lambda")
private void selectIndex(int index) {
final int position = textarea.getCaretPosition();
list.setSelectedIndex(index);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
textarea.setCaretPosition(position);
}
});
}

public String[] searchForWord(String dictionaryFilePath, String searchCriteria, int numberOfWordsToReturn) {
// This method ignores letter case!
List<String> foundList = new ArrayList<>(); // To hold all found words.

// Convert the supplied criteria string to a Regular Expression
// for the String#matches() method located in the 'while' loop.
String regEx = searchCriteria.replace("?", ".").replace("-", ".").replace("*", ".*?").toLowerCase();

// 'Try With Resources' use here to auto-close the reader.
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(dictionaryFilePath), characterEncoding))) {
String line = "";
int counter = 0;
while ((line = reader.readLine()) != null) {
line = line.trim().toLowerCase();
if (line.matches(regEx)) {
counter++;
foundList.add(line); // There's a match...add to the List.
if (counter == numberOfWordsToReturn) {
break;
}
}
}
}
// catch Exceptions (if any).
catch (FileNotFoundException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
return foundList.toArray(new String[0]); // Return the Array.
}

public String getDictionaryFilePath() {
return dictionaryFilePath;
}

public void setDictionaryFilePath(String dictionaryFilePath) {
this.dictionaryFilePath = dictionaryFilePath;
}

public int getNumberOfWordsInList() {
return numberOfWordsInList;
}

public void setNumberOfWordsInList(int numberOfWordsInList) {
this.numberOfWordsInList = numberOfWordsInList;
}

public Color getColorOfList() {
return colorOfList;
}

public void setColorOfList(Color colorOfList) {
this.colorOfList = colorOfList;
}

public Color getColorOfListText() {
return colorOfListText;
}

public void setColorOfListText(Color colorOfListText) {
this.colorOfListText = colorOfListText;
}

public String getListFontName() {
return listFontName;
}

public Font getListFont() {
return listFont;
}

public void setListFont(Font listFont) {
this.listFont = listFont;
this.listFontName = listFont.getName();
this.listFontStyle = listFont.getStyle();
this.listFontSize = listFont.getSize();
}

public void setListFontName(String listFontName) {
this.listFontName = listFontName;
}

public int getListFontStyle() {
return listFontStyle;
}

public void setListFontStyle(int listFontStyle) {
this.listFontStyle = listFontStyle;
}

public int getListFontSize() {
return listFontSize;
}

public void setListFontSize(int listFontSize) {
this.listFontSize = listFontSize;
}

public String getCharacterEncoding() {
return characterEncoding;
}

public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}

public Locale getLocale() {
return locale;
}

public void setLocale(Locale locale) {
this.locale = locale;
}

}

private SuggestionPanel suggestion;
private JTextArea textarea;

@SuppressWarnings("Convert2Lambda")
protected void showSuggestionLater() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
showSuggestion();
}

});
}

@SuppressWarnings({"CallToPrintStackTrace", "Convert2Lambda"})
protected void showSuggestion() {
hideSuggestion();
final int position = textarea.getCaretPosition();
Point location;
try {
location = textarea.modelToView(position).getLocation();
}
catch (BadLocationException 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();
}
}

protected void initUI() {
final JFrame frame = new JFrame();
frame.setTitle("Word Assist");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
textarea = new JTextArea(24, 80);
textarea.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
textarea.addKeyListener(new KeyListener() {

@Override
@SuppressWarnings("Convert2Lambda")
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
@SuppressWarnings("CallToPrintStackTrace")
public void run() {
try {
textarea.getDocument().remove(position - 1, 1);
}
catch (BadLocationException e) {
e.printStackTrace();
}
}
});
}
}
}
}

@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())) {
showSuggestionLater();
}
else if (Character.isWhitespace(e.getKeyChar())) {
hideSuggestion();
}
}

@Override
public void keyPressed(KeyEvent e) {

}
});
panel.add(textarea, BorderLayout.CENTER);
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}

@SuppressWarnings({"CallToPrintStackTrace", "Convert2Lambda"})
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new WordAssist().initUI();
}
});
}

}

只需启动一个名为 WordAssist 的新 Java 应用程序项目并将此代码粘贴到其中即可。它可能不完全是您想要的,但应该可以让您很好地了解如何实现您想要的。

EDIT - Based on the comment regarding the use of UTF-8 (Java7+ required):

我再次修改了上面的代码,以便您可以使用您喜欢的任何字符编码。只需将要使用的编码字符串提供给位于 SuggestionPanel 内部类中的 characterEncoding String 成员变量即可。现在默认编码为“UTF-8”。读取器和写入器已更改,以适应您决定使用的任何编码。

确保您的文本文件可以容纳您选择的字符编码。如果您想使用法语词典,那么您应该下载这样的词典文本文件,并将其完整路径提供给位于 SuggestionPanel 内部类中的 dictionaryFilePath String 成员变量。

SuggestionPanel 内部类中还提供了多个 Getter 和 Setter 方法。这些 setter 允许您更改:

  • Word 辅助列表的字体;
  • 只是文字辅助列表的字体名称;
  • 仅用于文字辅助列表的字体样式(纯色、粗体、斜体等);
  • 只是文字辅助列表的字体大小;
  • 单词辅助列表背景颜色;
  • 单词辅助列表文本颜色;
  • 要放置在单词辅助列表中的单词数;
  • 字典文件路径;
  • 要使用的所需字符编码。

还可以将未知单词添加到您提供的词典文件中。在 JTextArea 中键入时,在键入过程中无法确定单词,因此无法提供建议,然后将显示以下内容,让您可以选择将该单词添加到当前词典文件中:

enter image description here

添加到词典文件中的单词将被插入到文件中,以保持正确的升序。许多词典(或单词列表)文本文件包含大写部分(通常在文件的开头),如果要添加的单词以全大写形式或该单词的第一个字母大写,则该单词将插入到两者中该文件的大写和小写部分。否则,该单词仅添加到所提供的词典文件的小写部分。当单词添加到词典文件时,该词典文件将修改为您设置的字符编码(默认为 UTF-8)。

所提供的代码只是您可能希望如何完成任务的足迹。现在,您需要自行执行任何进一步的要求,或者开始一个新的 SO 帖子,指出您遇到的具体问题,当然,除非它与上面提供的修改代码的任何具体问题直接相关.

关于java - 键入时,从存储的现有文本中将单词(文本)插入到 JTextArea 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60924850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com