001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.widgets; 003 004import java.awt.Color; 005 006import javax.swing.UIManager; 007import javax.swing.event.DocumentEvent; 008import javax.swing.event.DocumentListener; 009import javax.swing.text.JTextComponent; 010 011import org.openstreetmap.josm.Main; 012import org.openstreetmap.josm.actions.search.SearchCompiler; 013 014/** 015 * Decorates a text component with an execution to the search compiler. Afterwards, a {@code "filter"} property change 016 * will be fired and the compiled search can be accessed with {@link #getMatch()}. 017 */ 018public final class CompileSearchTextDecorator implements DocumentListener { 019 020 private final JTextComponent textComponent; 021 private final String originalToolTipText; 022 private SearchCompiler.Match filter; 023 024 private CompileSearchTextDecorator(JTextComponent textComponent) { 025 this.textComponent = textComponent; 026 this.originalToolTipText = textComponent.getToolTipText(); 027 textComponent.getDocument().addDocumentListener(this); 028 } 029 030 /** 031 * Decorates a text component with an execution to the search compiler. Afterwards, a {@code "filter"} property change 032 * will be fired and the compiled search can be accessed with {@link #getMatch()}. 033 * @param f the text component to decorate 034 * @return an instance of the decorator in order to access the compiled search via {@link #getMatch()} 035 */ 036 public static CompileSearchTextDecorator decorate(JTextComponent f) { 037 return new CompileSearchTextDecorator(f); 038 } 039 040 private void setFilter() { 041 try { 042 textComponent.setBackground(UIManager.getColor("TextField.background")); 043 textComponent.setToolTipText(originalToolTipText); 044 filter = SearchCompiler.compile(textComponent.getText()); 045 } catch (SearchCompiler.ParseError ex) { 046 textComponent.setBackground(new Color(255, 224, 224)); 047 textComponent.setToolTipText(ex.getMessage()); 048 filter = SearchCompiler.Always.INSTANCE; 049 Main.debug(ex); 050 } 051 textComponent.firePropertyChange("filter", 0, 1); 052 } 053 054 /** 055 * Returns the compiled search 056 * @return the compiled search 057 */ 058 public SearchCompiler.Match getMatch() { 059 return filter; 060 } 061 062 @Override 063 public void insertUpdate(DocumentEvent e) { 064 setFilter(); 065 } 066 067 @Override 068 public void removeUpdate(DocumentEvent e) { 069 setFilter(); 070 } 071 072 @Override 073 public void changedUpdate(DocumentEvent e) { 074 setFilter(); 075 } 076}