how would be implements autosugesion in JTextArea swing

前端 未结 2 445
南旧
南旧 2020-12-10 09:42

let me if have you anyone answer, this ans. basically required like as google search engine , when we press any key then it would be display suggestion related pressed key.<

2条回答
  •  臣服心动
    2020-12-10 10:11

    I can propose my own implementation. It is based on JList shown in JWindow. As I wanted to use this code for a combo box, I've disabled UP and DOWN keys with keyEvent.consume() call.

    import javax.swing.*;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.JTextComponent;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    public class GAutoCompletionDecorator {
    
        private final JTextComponent textComponent;
        private final JWindow suggestionsPopup;
        private final JList completionList;
        private final DefaultListModel completionListModel;
    
        public static void decorate(JComboBox comboBox, JFrame parent) {
            comboBox.setEditable(true);
            final JTextComponent textComponent = (JTextComponent) comboBox.getEditor().getEditorComponent();
            decorate(textComponent, parent);
        }
    
        private static void decorate(JTextComponent textComponent, JFrame parent) {
            final GAutoCompletionDecorator autoCompletionDecorator = new GAutoCompletionDecorator(textComponent, parent);
            autoCompletionDecorator.decorate();
        }
    
        private GAutoCompletionDecorator(final JTextComponent textComponent, JFrame parent) {
            this.textComponent = textComponent;
            this.suggestionsPopup = new JWindow(parent);
            this.completionListModel = new DefaultListModel();
            this.completionList = new JList();
            this.completionList.setModel(completionListModel);
    
            this.suggestionsPopup.getContentPane().add(this.completionList);
        }
    
        private void decorate() {
            textComponent.getDocument().addDocumentListener(new DocumentListener() {
                public void insertUpdate(DocumentEvent documentEvent) {
                    updateSuggestions();
                }
    
                public void removeUpdate(DocumentEvent documentEvent) {
                    updateSuggestions();
                }
    
                public void changedUpdate(DocumentEvent documentEvent) {
                    updateSuggestions();
                }
            });
    
    
            this.textComponent.addKeyListener(new KeyAdapter() {
                public void keyPressed(KeyEvent keyEvent) {
                    if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN || keyEvent.getKeyCode() == KeyEvent.VK_UP) {
                        updateSuggestions();
                        completionList.requestFocus();
                        completionList.dispatchEvent(keyEvent);
                        keyEvent.consume();
                    }
                }
    
                public void keyReleased(KeyEvent keyEvent) {
                    if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN || keyEvent.getKeyCode() == KeyEvent.VK_UP) {
                        keyEvent.consume();
                    }
                }
            });
    
            this.completionList.addKeyListener(new KeyAdapter() {
                public void keyPressed(KeyEvent keyEvent) {
                    if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) {
                        textComponent.requestFocus();
                        hideSuggestionsPopup();
                    } else if (keyEvent.getKeyCode() == KeyEvent.VK_UP) {
                        if (completionList.getSelectedIndex() == 0) {
                            completionList.setSelectedIndex(completionListModel.size() - 1);
                            keyEvent.consume();
                        }
                    } else if (keyEvent.getKeyCode() == KeyEvent.VK_DOWN) {
                        if (completionList.getSelectedIndex() == completionListModel.size() - 1) {
                            completionList.setSelectedIndex(0);
                            keyEvent.consume();
                        }
                    } else if (keyEvent.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
                        textComponent.requestFocus();
                        hideSuggestionsPopup();
                        textComponent.dispatchEvent(keyEvent);
                    } else if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) {
                        textComponent.requestFocus();
                        hideSuggestionsPopup();
                        final String selectedSuggestion = (String) completionList.getSelectedValue();
                        if (selectedSuggestion != null) {
                            try {
                                final int caretPosition = textComponent.getCaretPosition();
                                textComponent.getDocument().insertString(caretPosition, getCompletionString(selectedSuggestion, textComponent.getText(), caretPosition), null);
                            } catch (BadLocationException e) {
                                //ignore
                            }
                        }
                    }
                }
            });
        }
    
        private String getCompletionString(String selectedSuggestion, String text, int caretPosition) {
            //we may insert selectedSuggestion fully of some part of it
            return selectedSuggestion;
        }
    
        private void updateSuggestions() {
            final String text = textComponent.getText();
            final int caretPosition = textComponent.getCaretPosition();
            final List suggestions = getSuggestions(text, caretPosition);
            if (suggestions == null || suggestions.size() == 0) {
                //hide suggestions window
                hideSuggestionsPopup();
            } else {
                //show suggestions window
                showSuggestionsPopup(suggestions);
            }
        }
    
        private void hideSuggestionsPopup() {
            suggestionsPopup.setVisible(false);
        }
    
        private void showSuggestionsPopup(List suggestions) {
            completionListModel.clear();
            for (String suggestion : suggestions) {
                completionListModel.addElement(suggestion);
            }
    
            final Point textComponentLocation = new Point(textComponent.getLocation());
            SwingUtilities.convertPointToScreen(textComponentLocation, textComponent);
    
            Point caretLocation = textComponent.getCaret().getMagicCaretPosition();
            if (caretLocation != null) {
                caretLocation = new Point(caretLocation);
                SwingUtilities.convertPointToScreen(caretLocation, textComponent);
            }
            suggestionsPopup.pack();
            suggestionsPopup.setLocation(caretLocation == null ? textComponentLocation.x : caretLocation.x,
                    textComponentLocation.y + textComponent.getHeight());
            suggestionsPopup.setVisible(true);
        }
    
        private List getSuggestions(String text, int caretPosition) {
            final List words = new ArrayList();
            words.add("suggestion 1");
            words.add("suggestion 2");
            words.add("suggestion 3");
            words.add("suggestion 4");
            words.add("suggestion 5");
            //make suggestions funny
            return text.length() < words.size() ? words.subList(0, words.size() - text.length()) : Collections.emptyList();
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    final JFrame frame = new JFrame();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
                    final JComboBox comboBox = new JComboBox(new String[] {"Choice1", "Choice2"});
                    comboBox.setEditable(true);
                    GAutoCompletionDecorator.decorate(comboBox, frame);
    
                    frame.add(comboBox);
                    frame.pack();
                    frame.setVisible(true);
                }
            });
    
        }
    }
    

提交回复
热议问题