GWT建议TextArea小部件

时间:2011-06-07 13:52:20

标签: java gwt autocomplete textarea autosuggest

有没有人看到Suggest或AutoComplete TextArea GWT Widget?它不必与SuggestBox完全相同。在我自己开发它之前,我只是想知道那里有什么东西。

7 个答案:

答案 0 :(得分:2)

有一个GWT库here还有一个演示here

答案 1 :(得分:1)

http://www.zackgrossbart.com/hackito/gwt-rest-auto/可能就是你要找的东西。

答案 2 :(得分:1)

您还可以查看Spiffy UI中的多值自动完成符。这是z00bs提到的auto-completer的更新版本,也是这个可重用框架的一部分。

答案 3 :(得分:0)

您是否尝试将TextArea传递给SuggestBox的构造函数? (鉴于TextArea延伸TextBoxBase

答案 4 :(得分:0)

这是我目前最喜欢的解决方案:http://jdramaix.github.com/gwtchosen/

答案 5 :(得分:0)

我想你可以使用“comboBox”。隐藏箭头并使字段可编辑..

答案 6 :(得分:0)

很久以前,在一个遥远的项目中,我写了一篇可能有用的课程:

public class SuggestTextArea extends TextArea {

private SuggestingPopupPanel suggestingPanel;
private SuggestTextArea textArea = this;

public SuggestTextArea(List<String> keywords) {
    super();
    suggestingPanel = new SuggestingPopupPanel(keywords, "suggestion");
    this.getElement().setAttribute("spellcheck", "false");

    this.addKeyPressHandler(new KeyPressHandler() {
        public void onKeyPress(KeyPressEvent event) {

            int charCode = event.getNativeEvent().getKeyCode();
            if (suggestingPanel.suggestingNow) {
                if (charCode == KeyCodes.KEY_ENTER || charCode == KeyCodes.KEY_TAB || event.getCharCode() == ' ') {
                    event.preventDefault();
                    suggestingPanel.insertCurrentKeyword();
                    return;
                }
                if (charCode == KeyCodes.KEY_DOWN) {
                    event.preventDefault();
                    suggestingPanel.panel.next();
                    return;
                }
                if (charCode == KeyCodes.KEY_UP) {
                    event.preventDefault();
                    suggestingPanel.panel.prev();
                    return;
                }
            } else {
                // Позиции естественно посчитаны не совсем верно
                int posX = textArea.getAbsoluteLeft();
                int posY = textArea.getAbsoluteTop() + 20 * getCurrentLines();
                suggestingPanel.setPopupPosition(posX, posY);
            }
            // Не предполагаем при удалении или смещении курсора
            if (charCode == KeyCodes.KEY_BACKSPACE || charCode == KeyCodes.KEY_LEFT || charCode == KeyCodes.KEY_RIGHT) {
                suggestingPanel.stopSuggesting();
                return;
            }
            // События с нажатым Ctrl не обрабатываем (ну почти)
            if(event.isControlKeyDown()){
                if(event.getCharCode() == 'v' || event.getCharCode() == 'V'){
                    suggestingPanel.stopSuggesting();
                }
                return;
            }
            suggest(event.getCharCode());
        }
    });
}

private int getCurrentLines() {
    // считает неверно если изменить размеры text area
    return (this.getText().length() / this.getCharacterWidth()) + 1;
}

// Добавляет указаные символы после курсора
private void insertCharacters(String insertion) {
    String text = this.getText();
    int cursorPos = this.getCursorPos();
    String res = text.substring(0, cursorPos) + insertion + text.substring(cursorPos);

    setText(res);
    setCursorPos(cursorPos + insertion.length());
    suggestingPanel.stopSuggesting();
}

private void suggest(char c) {
    // Отсекаем текст за курсором
    int cursorPos = this.getCursorPos();
    String text;
    text = this.getText().substring(0, cursorPos) + (c == 0 ? "" : c);

    if (text.length() == 0) {
        this.suggestingPanel.setVisible(false);
        return;
    }

    // получем вводимые символы
    String keys = "";
    RegExp pattern = RegExp.compile("\\b(\\w+)$", "gmi");
    for (MatchResult result = pattern.exec(text); result != null; result = pattern.exec(text)) {
        keys = result.getGroup(1);
    }
    if (!keys.equals("")) {
        suggestingPanel.showMatches(keys);
    }
}

// Панель для отображения предположений
class SuggestingPopupPanel extends PopupPanel {

    private boolean suggestingNow = false;
    private String suggestStyleName;
    private List<String> keywords;
    private Suggestions panel;
    private List<String> currentSuggestions;
    private String lastKeys;

    public SuggestingPopupPanel(List<String> keywords, String suggestStyleName) {
        super(true, false); // autohide, not modal
        this.keywords = keywords;
        this.suggestStyleName = suggestStyleName;

        setVisible(false);
    }

    public void insertCurrentKeyword() {
        insertCharacters(this.getKeywordEnd() + " ");
    }

    public String getKeywordEnd() {
        return currentSuggestions.get(panel.current).substring(lastKeys.length());
    }

    public String getKeywordEnd(int index) {
        return currentSuggestions.get(index).substring(lastKeys.length());
    }

    public void showMatches(String keys) {
        lastKeys = keys;
        // Получаем совпадения
        List<String> suggestions = new LinkedList<String>();
        RegExp pattern = RegExp.compile("\\b(" + keys + ")", "gmi");
        for (String keyword : keywords) {
            for (MatchResult result = pattern.exec(keyword); result != null; result = pattern.exec(keyword)) {
                suggestions.add(keyword);
            }
        }

        currentSuggestions = suggestions;

        if (suggestions.isEmpty()) {
            this.setVisible(false);
            suggestingNow = false;
        } else {
            suggestingNow = true;
            ArrayList<HTML> htmlList = new ArrayList<HTML>();
            for (String suggestion : suggestions) {
                String htmlText = HtmlHelper.getHtmlText(suggestion + "\n");
                htmlText = applyStyle(htmlText, keys);

                htmlList.add(new HTML(htmlText));
            }

            panel = new Suggestions(htmlList);
            this.setWidget(panel);

            this.setVisible(true);
            this.show();
        }
    }

    public void stopSuggesting(){
        suggestingNow = false;
        this.setVisible(false);
    }

    private String applyStyle(String text, String keys) {
        String regex = "\\b" + keys.toLowerCase();

        return text.replaceAll(regex, "<span class=\"" + suggestStyleName + "\">" + keys + "</span>");
    }

    // Отображает варианты
    class Suggestions extends VerticalPanel {

        String choosingName = "htmlFocus";
        List<HTML> variants;
        int current;

        public Suggestions(final ArrayList<HTML> variants) {
            if (variants.isEmpty()) {
                return;
            }

            this.variants = variants;
            current = 0;
            variants.get(current).addStyleName(choosingName);

            for (final HTML html : variants) {
                html.addStyleName("suggestVariant");

                // При нажатии дополняем соответсвующие символы
                html.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        textArea.insertCharacters(getKeywordEnd(variants.indexOf(html)) + " ");
                        stopSuggesting();
                    }
                });

                this.add(html);
            }
        }

        public void prev() {
            int prev = current - 1;
            if (prev < 0) {
                prev = variants.size() - 1;
            }
            variants.get(current).removeStyleName(choosingName);
            variants.get(prev).addStyleName(choosingName);
            current = prev;
        }

        public void next() {
            int next = current + 1;
            if (next == variants.size()) {
                next = 0;
            }
            variants.get(current).removeStyleName(choosingName);
            variants.get(next).addStyleName(choosingName);
            current = next;
        }
    }
}
}

请原谅我的格式错误和俄语评论,但你应该得到主要的想法。