|
View:
New views
4 Messages
—
Rating Filter:
Alert me
|
|
|
Autocomplete length limitingWe are transitioning our two autocomplete combo boxes to Glazed List ones, and, so far, I like them a lot. However, one thing we used to do with the old ones was to limit the length of the text that the user typed in (to match a database column length). We used a custom document filter class for that feature, but I can't do the same approach with Glazed Lists because it installs its own document filter (if I overwrite it, I lose the autocompletion feature).
I'm sure that there's some way to do this that I'm just not seeing. Can anyone help me out?
Thanks in advance,
Larry |
|
|
Re: Autocomplete length limitingHey Larry,
It's slightly less than ideal, but I think you could first call: AutoCompleteSupport.install(comboBox, ...); and then install your own length-checking, delegating LengthLimitDocumentFilter that performs your own logic like so: final DocumentFilter glFilter = ((AbstractDocument) comboBox.getDocument()).getDocumentFilter(); final DocumentFilter lengthLimitDocumentFilter = new LengthLimitDocumentFilter(glFilter); ((AbstractDocument) comboBox.getDocument()).setDocumentFilter(lengthLimitDocumentFilter); where LengthLimitDocumentFilter looks like this: public class LengthLimitDocumentFilter extends DocumentFilter { private final DocumentFilter delegate; public LengthLimitDocumentFilter(DocumentFilter delegate) { this.delegate = delegate; } public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { // perform length check, return if it fails delegate.insertString(fb, offset, string, attr); } public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { // perform length check, return if it fails delegate.replace(fb, offset, length, test, attrs); } } Note: this will prevent AutoCompleteSupport.uninstall() from working completely correct, since it no longer believes it installed the DocumentFilter that it finds on the Document. Hope this helps, James On Tue, Aug 11, 2009 at 2:10 PM, Larry Mello <nicc0lo1966@...> wrote:
|
|
|
Re: Autocomplete length limitingHey James,
Thanks for replying. What I was using before was similar except that I didn't have the delegate in my doc filter. Unfortunately, autocomplete doesn't work now (this is the same behavior I had when I originally posted). The problem is not in the doc filter (the debugger never even gets to its "insertString" method to check the length of the string being entered). The problem is where I overwrite the doc filter on the combo box's editor w/setDocumentFilter(). This replaces the filter installed by AutoCompleteSupport (ca.odell.glazedlists.swing.AutoCompleteSupport$AutoCompleteFilter) with my custom one. Can you think of an alternative approach that doesn't replace the autocomplete filter? I was thinking about a propery listener. Does the editor dispatch any property events? Larry
|
|
|
Re: Autocomplete length limitingI have a solution that works. It's not elegant at all, but it works. In case anyone else runs into the same problem, I am posting it here. I didn't see any useful property events from the editor or combo so I did something different.
The main thing I am using is a document listener I attach to the autocomplete combo box editor. In its insertUpdate method, I check the length of the document. If it's larger than allowed, I do a toolkit beep then I use SwingUtilities.invokeLater and set the editor's text to the truncated document's text. Here is the (pseudo)code: if (autocompleteCombo.getEditor().getEditorComponent() instanceof JTextField) { final JTextField autocompleteTextField = (JTextField) autocompleteCombo.getEditor().getEditorComponent(); if (autocompleteTextField.getDocument() instanceof AbstractDocument) { AbstractDocument doc = (AbstractDocument) autocompleteTextField.getDocument(); doc.addDocumentListener(new DocumentListener() { public void changedUpdate(DocumentEvent e) { // intentional no-op } public void insertUpdate(DocumentEvent e) { // all USER_GENERATOR means is that the event comes from a user gesture, not the system. // I do this to prevent runaway endless loops. if (getEventGenerator() == USER_GENERATOR) { try { String docText = e.getDocument().getText(0, e.getDocument().getLength()); int docCharCount = (docText == null) ? 0: docText.length(); // the next line checks to see if the document is larger than allowed if (docCharCount > yourMaximumNumberOfCharacters) { Toolkit.getDefaultToolkit().beep(); // SYSTEM_GENERATOR prevents events from endlessly propagating and stops endless loops setEventGenerator(SYSTEM_GENERATOR); final StringBuilder fixedText = new StringBuilder(); // the document's text is already too large - truncate it fixedText.append(docText.substring(0, yourMaximumNumberOfCharacters)); SwingUtilities.invokeLater(new Runnable() { public void run() { autocompleteTextField.setText(fixedText.toString()); } }); } } catch (BadLocationException ble) { // intentionally ignored } finally { setEventGenerator(USER_GENERATOR); } } } public void removeUpdate(DocumentEvent e) { // intentional no-op } }); } } Like I said, it's not pretty but it works. If you have questions about it, let me know. Larry
|
| Free embeddable forum powered by Nabble | Forum Help |