/* * Copyright 2004 - 2009 Christian Sprajc. All rights reserved. * * This file is part of PowerFolder. * * PowerFolder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * PowerFolder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PowerFolder. If not, see <http://www.gnu.org/licenses/>. * * $Id: AutoTextField.java 8099 2009-05-27 15:09:23Z harry $ */ package de.dal33t.powerfolder.ui.widget; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.swing.JTextField; import javax.swing.text.*; /** * Text field class that tries to match entered text against a list of values. * If it matches, it highlights the remaining matching text. */ public class AutoTextField extends JTextField { /** List of candidate values. */ private final List<String> dataList = new CopyOnWriteArrayList<String>(); /** * Constructor */ public AutoTextField() { this(null); } /** * Constructor * * @param list */ public AutoTextField(List<String> list) { if (list != null) { dataList.addAll(list); } setDocument(new AutoDocument()); } /** * Try to match against an item in the list. * * @param text * @return */ private String getMatch(String text) { for (String dataItem : dataList) { if (dataItem != null) { if (dataItem.toLowerCase().startsWith(text.toLowerCase())) { return dataItem; } } } return ""; } /** * Replace the items in the value list. * * @param list */ public void setDataList(List<String> list) { if (list != null) { dataList.clear(); dataList.addAll(list); } } /** * Replace a section in the text. * * @param content */ public void replaceSelection(String content) { AutoDocument autoDocument = (AutoDocument) getDocument(); try { int i = Math.min(getCaret().getDot(), getCaret().getMark()); int j = Math.max(getCaret().getDot(), getCaret().getMark()); autoDocument.replace(i, j - i, content, null); } catch (Exception exception) { } } public String getText() { try { String text = getDocument().getText(0, getDocument().getLength()); // Try to get correct case match from list. for (String item : dataList) { if (item != null && item.equalsIgnoreCase(text)) { return item; } } return text; } catch (Exception e) { return ""; } } public void clear() { try { getDocument().remove(0, getDocument().getLength()); } catch (BadLocationException e) { // Ignore } } /** * Autodocument extension that highlights the best match. */ private class AutoDocument extends PlainDocument { public void replace(int offset, int length, String text, AttributeSet attrs) throws BadLocationException { super.remove(offset, length); insertString(offset, text, attrs); } public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (str == null || str.length() == 0) { return; } String startText = getText(0, offs); String match = getMatch(startText + str); // No match? Just enter text. if (match.length() == 0) { super.insertString(offs, str, a); return; } // Enter match and highlight the guessed part. super.remove(0, getLength()); // Enter the inserted text, then the remaining match text. // Must do this to preserve entered upper/lower case. super.insertString(0, startText, a); super.insertString(offs, str, a); super.insertString(offs + str.length(), match.substring(offs + str.length(), match.length()), a); // Select the guessed bit. setSelectionStart(offs + str.length()); setSelectionEnd(getLength()); } public void remove(int offs, int len) throws BadLocationException { // Do not match if everything is deleted. if (offs == 0 && len == getLength()) { super.remove(0, getLength()); return; } int selectionStart = getSelectionStart(); if (selectionStart > 0) { selectionStart--; } // All text removed. Display blank. if (selectionStart == 0) { super.remove(0, getLength()); return; } // Try to match on text entered so far. String match = getMatch(getText(0, selectionStart)); if (match.length() == 0) { // No match. Just remove the text. super.remove(offs, len); } else { String text = getText(0, getLength()); super.remove(0, getLength()); // Enter the existing text, then the remaining match text. // Must do this to preserve entered upper/lower case. super.insertString(0, text.substring(0, offs), null); super.insertString(offs, match.substring(offs, match.length()), null); } try { setSelectionStart(selectionStart); setSelectionEnd(getLength()); } catch (Exception exception) { // Don't really care. } } } }