当前位置: 首页 > 知识库问答 >
问题:

输入某些字符时完成单词

张晨朗
2023-03-14

我想在我的java代码时,字符co是输入在一个文本区域对象的单独行。为mputer拼出单词computer,然后转到下面的下一行。你可以在下面的gif中看到我正在寻找的东西。我在下面的关键监听器类中添加了一些我已经尝试过的代码。

static JFrame f; 

// text area 
static JTextArea jt;


class CustomKeyListener implements KeyListener{

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            String txt = text11.jt.getText();
            boolean hasText = false;


            for (int i = txt.length() - 1; i >= 0; i--) {

                if (txt.charAt(i) == '\n') break;

                if (Character.isWhitespace(txt.charAt(i))) continue;

                hasText = true;
                break;
            }

            if (hasText) {
               text11.jt.setText(text11.jt.getText() + "     computer");
           } 
        }
    }

共有1个答案

漆雕亮
2023-03-14

下面是我自己的实现以及我是如何实现的:

AutoCompleteExtarea:

import java.awt.BorderLayout;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;

public class AutoCompleteTextArea extends JTextArea implements FocusListener, DocumentListener {
    private static final long serialVersionUID = 1L;
    private AutoCompleteRecommendationsWindow autoCompleteWindow;
    private List<String> words;

    public AutoCompleteTextArea(List<String> words) {
        super();
        init(words);
    }

    public AutoCompleteTextArea(List<String> words, int rows, int columns) {
        super(rows, columns);
        init(words);
    }

    public AutoCompleteTextArea(List<String> words, String text, int rows, int columns) {
        super(text, rows, columns);
        init(words);
    }

    public AutoCompleteTextArea(List<String> words, String text) {
        super(text);
        init(words);
    }

    private void init(List<String> words) {
        this.words = words;
        autoCompleteWindow = new AutoCompleteRecommendationsWindow(this);
        getDocument().addDocumentListener(this);
        addFocusListener(this);
    }

    private void attemptAutoCompleteFromRemoval(DocumentEvent e) throws BadLocationException {
        if (e.getLength() != 1)
            return;

        int pos = e.getOffset();
        String content = getText(0, pos + 1);
        int startPosition = getStartingPositionOfTheWord(pos - 1, content);

        if (pos - startPosition < 3) {
            autoCompleteWindow.setVisible(false);
            return;
        }
        String prefix = content.substring(startPosition + 1);
        showRecommendations(prefix.trim());
    }

    private int getStartingPositionOfTheWord(int offset, String content) {
        int index;
        for (index = offset; index >= 0; index--) {
            if (!Character.isLetter(content.charAt(index))) {
                break;
            }
        }
        return index;
    }

    private void showRecommendations(String prefix) {
        List<String> recommendations = getAutoCompleteRecommendationsForPrefix(prefix);
        if (!recommendations.isEmpty()) {
            autoCompleteWindow.showRecommendations(prefix, recommendations);
            SwingUtilities.invokeLater(() -> autoCompleteWindow.setVisible(true));
        } else {
            autoCompleteWindow.setVisible(false);
        }
    }

    private List<String> getAutoCompleteRecommendationsForPrefix(String prefix) {
        int n = Collections.binarySearch(words, prefix);
        List<String> result = new ArrayList<>();
        if (n < 0 && -n <= words.size()) {
            int indexOfMatchedWord = -n - 1;
            String match = words.get(indexOfMatchedWord);
            if (!match.startsWith(prefix))
                return result;
            result.add(match);
            for (int i = indexOfMatchedWord + 1; i < words.size(); i++) {
                match = words.get(i);
                if (match.startsWith(prefix)) {
                    result.add(match);
                } else
                    break;
            }
            for (int i = indexOfMatchedWord - 1; i >= 0; i--) {
                match = words.get(i);
                if (match.startsWith(prefix)) {
                    result.add(match);
                } else
                    break;
            }
        }
        return result.stream().sorted(Comparator.naturalOrder()).distinct().collect(Collectors.toList());
    }

    private void attemptAutoComplete(DocumentEvent ev) throws BadLocationException {
        if (ev.getLength() != 1) {
            return;
        }

        int pos = ev.getOffset();
        String content = getText(0, pos + 1);
        int startPosition = getStartingPositionOfTheWord(pos, content);

        if (pos - startPosition < 2) {
            autoCompleteWindow.setVisible(false);
            return;
        }

        String prefix = content.substring(startPosition + 1);
        showRecommendations(prefix);
    }

    @Override
    public void focusGained(FocusEvent e) {
    }

    @Override
    public void focusLost(FocusEvent e) {
        autoCompleteWindow.setVisible(false);
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        try {
            attemptAutoComplete(e);
        } catch (BadLocationException e1) {
        }
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        try {
            attemptAutoCompleteFromRemoval(e);
        } catch (BadLocationException e1) {
        }
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
    }

    private class AutoCompleteRecommendationsWindow extends JWindow implements KeyListener, MouseListener {
        private static final long serialVersionUID = 2646960455879045456L;
        private JTextArea area;
        private JList<String> wordList;
        private String prefix;

        private AutoCompleteRecommendationsWindow(JTextArea area) {
            super();
            this.area = area;
            setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
            wordList = new JList<>();
            wordList.addMouseListener(this);
            wordList.setModel(new DefaultListModel<>());

            area.addKeyListener(this);
            getContentPane().setLayout(new BorderLayout());
            JScrollPane sp = new JScrollPane(wordList);
            getContentPane().add(sp, BorderLayout.CENTER);
            pack();
        }

        public void showRecommendations(String prefix, List<String> recommendations) {
            this.prefix = prefix;
            wordList.setVisibleRowCount(Math.min(10, recommendations.size()));

            String longestWord = recommendations.stream().max(Comparator.comparingInt(String::length)).get();
            wordList.setPrototypeCellValue(longestWord + "S"); // Some extra space

            showRecommendationsInWordList(recommendations);
            wordList.setSelectedIndex(0);
            revalidate();
            pack();
        }

        private void showRecommendationsInWordList(List<String> recommendations) {
            DefaultListModel<String> model = (DefaultListModel<String>) wordList.getModel();
            model.removeAllElements();
            recommendations.forEach(model::addElement);
        }

        @Override
        public void setVisible(boolean b) {
            try {
                setLocation(getCursorLocation());
            } catch (BadLocationException e) {
                return;
            }
            super.setVisible(b);
        }

        private Point getCursorLocation() throws BadLocationException {
            Rectangle rect = area.modelToView(Math.max(0, area.getCaretPosition() - 1));
            if (rect == null) // In a test environment is null
                throw new BadLocationException("", 0);

            Point coordinates = rect.getLocation();
            coordinates.x += 10;
            coordinates.y += area.getFontMetrics(area.getFont()).getHeight();
            SwingUtilities.convertPointToScreen(coordinates, area);
            return coordinates;
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (!isVisible())
                return;
            if (isDownArrowKey(e) || isUpArrowKey(e)) {
                String value = wordList.getSelectedValue();

                if (isDownArrowKey(e) && wordList.getSelectedIndex() < wordList.getModel().getSize() - 1) {
                    value = wordList.getModel().getElementAt((wordList.getSelectedIndex() + 1));
                } else if (isUpArrowKey(e) && wordList.getSelectedIndex() > 0) {
                    value = wordList.getModel().getElementAt((wordList.getSelectedIndex() - 1));
                }
                wordList.setSelectedValue(value, true);
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                addSelectedWordAndClose();
                e.consume();
            } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                setVisible(false);
            }
        }

        private void addSelectedWordAndClose() {
            int position = area.getCaretPosition();
            area.insert((wordList.getSelectedValue() + " ").substring(prefix.length()), position);
            setVisible(false);
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }

        private boolean isDownArrowKey(KeyEvent e) {
            return e.getKeyCode() == KeyEvent.VK_DOWN;
        }

        private boolean isUpArrowKey(KeyEvent e) {
            return e.getKeyCode() == KeyEvent.VK_UP;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            addSelectedWordAndClose();
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }
    }
}
  • 它接受构造函数中的列表 ,该构造函数表示您的字典。请注意,词典必须进行排序,因为它使用二进制搜索来查找自动完成的推荐词。
  • 它允许您使用箭头键
  • 导航推荐的单词
import java.awt.BorderLayout;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class Demo {
    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Auto complete Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());

            List<String> dictionary = Arrays.asList("computer", "canada", "controversial", "conversation", "construct");
            Collections.sort(dictionary);

            AutoCompleteTextArea autoCompleteTextArea = new AutoCompleteTextArea(dictionary, 20, 50);
            autoCompleteTextArea.setFont(new JLabel().getFont()); // Windows laf text area font does not look good
            frame.add(autoCompleteTextArea);

            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        });
    }
}
else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
    addSelectedWordAndClose();
    e.consume();
}

consume正是这样做的。它使用键事件,所以行不会改变。如果删除它,当按下vk_enter时,光标将移动到下一行。

 类似资料:
  • 问题内容: 我想创建JTextField,输入字符限于“ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYWZZ0123456789 +&@#/%?=〜_- |!:,。;”之类的输入字符。所以我尝试覆盖 但这不是我想要的,因为用户无法再按ctrl-c ctrl-v ctrl-x …所以我添加了 到if条件,但现在用户可以粘贴不适当的输入,即’(’

  • 问题内容: 我刚刚开始学习我的第一种真正的编程语言Python。我想知道如何将用户输入限制为特定字符和特定长度。例如,如果用户输入的字符串包含除字母以外的任何内容,我想显示一条错误消息,并且我想显示其中一个用户输入的字符超过15个。 第一个似乎是我可以使用正则表达式做的事情,由于我已经在Java语言中使用过它们,所以我对此有所了解,但是我不确定如何在Python中使用它们。第二个,我不确定该如何处

  • 当我尝试对输入进行限制时,我在java中遇到了很多麻烦。在此示例中,我需要字符串代码仅接受和等符号。我如何检查以确保没有数字、字母或其他符号?谢谢

  • 问题内容: 我正在考虑使用删除字符串中的某些字符。目前尚不清楚将要删除哪些字符(即我想删除哪些字符),但是我会假定任何字符都是有效的(例如和之类的东西,等等)。 我遇到了http://www.java-tips.org/java-se-tips/java.lang/strip-certain-characters- from-a-string.html, 但是肯定有比遍历每个字符更好的方法… 有什

  • 问题内容: 给定以下字符串 这是所需的输出:( 每个长号,无论长度如何,都应替换为姓氏) 这里的问题是,可能有很多可变长度(最大长度可以<20)… 我尝试了 多种 方法,并采用了以下方法。 有没有办法有效地做到这一点..任何建议将是最欢迎的 问题答案: 首先删除多个下划线,然后进行替换。 这是一种方法:

  • 问题内容: 这可能是一个愚蠢的问题,但是由于找不到答案,我不得不提出这个问题。 在交互式python中,我想处理一条消息: 一切正常,但是…如何阻止它获取输入并将其保存到message变量中?使用ctrl + c停止将停止整个过程,因此没有输入要保存在任何地方。我想我找不到一个简单的答案… 问题答案: 对于基于Unix的系统: 您好,您可以录音: 通过发送EOF关闭标准输入(stdin)。 范例: