/* Copyright (C) 2003-2011 JabRef contributors.
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 net.sf.jabref;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Document;
import javax.swing.text.Highlighter;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
public class JTextAreaWithHighlighting extends JTextArea implements SearchTextListener {
private ArrayList<String> wordsToHighlight;
private UndoManager undo;
public JTextAreaWithHighlighting() {
super();
setupUndoRedo();
}
public JTextAreaWithHighlighting(String text) {
super(text);
setupUndoRedo();
}
public JTextAreaWithHighlighting(Document doc) {
super(doc);
setupUndoRedo();
}
public JTextAreaWithHighlighting(int rows, int columns) {
super(rows, columns);
setupUndoRedo();
}
public JTextAreaWithHighlighting(String text, int rows, int columns) {
super(text, rows, columns);
setupUndoRedo();
}
public JTextAreaWithHighlighting(Document doc, String text, int rows,
int columns) {
super(doc, text, rows, columns);
setupUndoRedo();
}
protected void setupUndoRedo() {
undo = new UndoManager();
Document doc = getDocument();
// Listen for undo and redo events
doc.addUndoableEditListener(new UndoableEditListener() {
public void undoableEditHappened(UndoableEditEvent evt) {
undo.addEdit(evt.getEdit());
}
});
// Create an undo action and add it to the text component
getActionMap().put("Undo",
new AbstractAction("Undo") {
public void actionPerformed(ActionEvent evt) {
try {
if (undo.canUndo()) {
undo.undo();
}
} catch (CannotUndoException e) {
}
}
});
// Bind the undo action to ctl-Z
getInputMap().put(Globals.prefs.getKey("Undo"), "Undo");
// Create a redo action and add it to the text component
getActionMap().put("Redo",
new AbstractAction("Redo") {
public void actionPerformed(ActionEvent evt) {
try {
if (undo.canRedo()) {
undo.redo();
}
} catch (CannotRedoException e) {
}
}
});
// Bind the redo action to ctl-Y
getInputMap().put(Globals.prefs.getKey("Redo"), "Redo");
}
/**
* Highlight words in the Textarea
*
* @param words to highlight
*/
private void highLight(ArrayList<String> words) {
// highlight all characters that appear in charsToHighlight
Highlighter h = getHighlighter();
// myTa.set
h.removeAllHighlights();
if (words == null || words.isEmpty() || words.get(0).isEmpty()) {
return;
}
String content = getText();
if (content.isEmpty())
return;
Matcher matcher = Globals.getPatternForWords(words).matcher(content);
while (matcher.find()) {
try {
h.addHighlight(matcher.start(), matcher.end(), DefaultHighlighter.DefaultPainter);
} catch (BadLocationException ble) {
// should not occur if matcher works right
System.out.println(ble);
}
}
}
@Override
public void setText(String t) {
super.setText(t);
if (Globals.prefs.getBoolean("highLightWords")) {
highLight(wordsToHighlight);
}
if (undo != null) undo.discardAllEdits();
}
public void searchText(ArrayList<String> words) {
// words have to be stored in class variable as
// setText() makes use of them
if (Globals.prefs.getBoolean("highLightWords")) {
this.wordsToHighlight = words;
highLight(words);
} else {
if (this.wordsToHighlight != null) {
// setting of "highLightWords" seems to have changed.
// clear all highlights and remember the clearing (by wordsToHighlight = null)
this.wordsToHighlight = null;
highLight(null);
}
}
}
}