/* * org.openmicroscopy.shoola.util.ui.omeeditpane.OMERegexFormatter * *------------------------------------------------------------------------------ * Copyright (C) 2006-2009 University of Dundee. All rights reserved. * * * This program 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; either version 2 of the License, or * (at your option) any later version. * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.util.ui.omeeditpane; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; /** * This is a {@link DocumentListener} that takes a set of Regular expressions * and {@link SimpleAttributeSet} for each. * When the Document is edited, it is parsed and if it is a * {@link StyledDocument} applies a Style to the matching Strings. * * @author William Moore      * <a href="mailto:will@lifesci.dundee.ac.uk">will@lifesci.dundee.ac.uk</a> * @version 3.0 * @since 3.0-Beta4 */ public class OMERegexFormatter implements DocumentListener { /** The Doc to parse */ StyledDocument doc; /** A Map of the Regex patterns, each with a Style */ private Map <String, SimpleAttributeSet> styles; /** The Style of the plain text */ private SimpleAttributeSet plainText; boolean refresh; /** * Called by the update edits. * Delegates to {@link #parseRegex(StyledDocument)} * * @param e The DocumentEvent * @param refresh True if you want to make the whole document * plain before applying styles */ private void parseRegex(DocumentEvent e, boolean refresh) { if (e.getDocument() instanceof StyledDocument) { parseRegex((StyledDocument)e.getDocument(), refresh); } else { return; } } /** * Creates an instance. * Sets the plain text to Sans-Serif, size 14. */ public OMERegexFormatter() { styles = new HashMap<String, SimpleAttributeSet>(); plainText = new SimpleAttributeSet(); StyleConstants.setFontFamily(plainText, "SansSerif"); StyleConstants.setFontSize(plainText, 14); } /** * Creates an instance. * * @param plainText The Style of text with no regex matches. */ public OMERegexFormatter(SimpleAttributeSet plainText) { this(); this.plainText = plainText; } /** * Add a Regex to the Map parsed for matches. * * @param regex The Regex to find. * @param style The Style to apply to matching text. */ public void addRegex(String regex, SimpleAttributeSet style) { styles.put(regex, style); } /** * Implemented as specified by the {@link DocumentListener} interface. * Null implementation here, since Regex matching should not be affected * by changes to fonts etc. */ public void changedUpdate(DocumentEvent e) {} /** * Implemented as specified by the {@link DocumentListener} interface. * Calls {@link #parseRegex(DocumentEvent, boolean)} */ public void insertUpdate(DocumentEvent e) { parseRegex(e, true); } /** * Implemented as specified by the {@link DocumentListener} interface. * Calls {@link #parseRegex(DocumentEvent, boolean)} */ public void removeUpdate(DocumentEvent e) { parseRegex(e, true); } /** * Parse the document, find the regex matches and apply the appropriate * Style to each. The Source of the Edit Event should be a * StyledDocument in order that the styles are applied. * Method is public so that it can be called to apply styles before any * editing occurs. * * @param document The document to handle. * @param refreshStyle True if you want to make the whole document * plain before applying styles */ public void parseRegex(StyledDocument document, boolean refreshStyle) { doc = document; refresh = refreshStyle; SwingUtilities.invokeLater(new Runnable() { public void run() { // remove this class as a listener, to avoid recursive edits doc.removeDocumentListener(OMERegexFormatter.this); // first, make all the text plain. if (refresh) doc.setCharacterAttributes(0, doc.getLength(), plainText, true); try { Iterator<String> i = styles.keySet().iterator(); String text = doc.getText(0, doc.getLength()); List<Position> positionList = new ArrayList<Position>(); String regex; SimpleAttributeSet style; while (i.hasNext()) { regex = i.next(); style = styles.get(regex); positionList.clear(); WikiView.findExpressions(text, regex, positionList); // paint the regex int start, end; for (Position p : positionList) { start = p.getStart(); end = p.getEnd(); doc.setCharacterAttributes(start, end-start, style, false); } } } catch (BadLocationException e1) { } doc.addDocumentListener(OMERegexFormatter.this); } }); } }