Markieren von Text in Textkomponenten ('Highlighting')
Zur Demonstration wird ein einfaches Fenster auf Basis eines JFrame
erzeugt, das untereinander ein JTextField
zur Eingabe des zu markierenden Textanteils und eine JTextArea
mit dem Haupttext enthält. Das GUI wird in der
Methode initGUI()
erzeugt.
Der
vollständige, kopierfähige Quelltext des
Beispiels ist unten
notiert.
private void initGUI() { area = new JTextArea(TEXT, 10, 20); area.setLineWrap(true); area.setWrapStyleWord(true); JScrollPane scrollPane = new JScrollPane(area); field = new JTextField(); field.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { search(); } }); JFrame frame = new JFrame(); frame.add(field, BorderLayout.PAGE_START); frame.add(scrollPane, BorderLayout.CENTER); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("Highlighter-Beispiel"); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); }
Auf die Eingabe eines Textes im Suchfeld reagiert ein KeyListener
[7], der nach Eingabe jedes Zeichens die Methode search()
aufruft [9]. Sie startet die Suche des im Suchfeld
eingegebenen Textes in der Textarea.
private void search() { area.getHighlighter().removeAllHighlights(); if (field.getText() == null) { return; } highlightString(Color.YELLOW, field.getText()); scrollToHighlight(); }
in search()
wird zu Beginn durch die
Methode getHighlighter()
der Highlighter
der JTextArea
ermittelt. Er besitzt
wiederum eine Methode removeAllHighlights()
,
die dafür sorgt, dass alle eventuell vorhandenen
Markierungen des Textbereiches gelöscht werden [2].
Nach einer Abfrage, die sicherstellt, dass Text im
Suchfeld vorhanden ist [3], wird zuächst die
Methode highlightString
aufgerufen, die das
eigentliche Markieren vornimmt. Der Aufruf von scrollToHighlight()
sorgt dann dafür, dass die Textarea zur ersten
Markierung gescrollt wird.
Highlighter
ist ein Interface im Package javax.swing.text
,
das zwei innere statische Interfaces kapselt. Highlighter.HighlightPainter
und Highlighter.Highlight
. Die
Schnittstelle Highlighter
selbst deklariert
Methoden, die für das Hinzufügen, die
Entfernung und den Zugriff auf Markierungen
zuständig sind. Das innere Interface Highlighter.HighlightPainter
ermöglicht das Zeichnen einer Markierung. Für
beides bietet Java einfache Implementierungen in Form
der Klassen DefaultHighlighter
und DefaultHighlighter.DefaultHighlightPainter
an.
private String highlightString(Color color, String target) { String text = null; try { Highlighter highlighter = area.getHighlighter(); text = area.getText(); int pos = 0; Highlighter.HighlightPainter hp = new DefaultHighlighter.DefaultHighlightPainter(color); if (target.length() > 0) { while ((pos = text.indexOf(target, pos)) >= 0) { highlighter.addHighlight(pos, pos + target.length(), hp); pos += target.length(); } } } catch (BadLocationException e) { } return text; }
Die Methode highlightString()
führt
die eigentliche Markierung durch. Ihr werden zwei
Argumente übergeben: die Markierungsfarbe und der
zu markierende String.
Innerhalb eines
try-catch-Blocks werden zunächst der Highlighter
der Textarea und deren Text ermittelt. Ein HighlightPainter
wird mit Übergabe der Markierungsfarbe gebildet.
Innerhalb einer Schleife werden dann der Areatext
durchlaufen und die Position(en) des gesuchten Strings
ermittelt. Die Methode addHighlight()
des Highlighter
fügt die Markierung dem Text hinzu. Hierzu werden
ihr die Anfangsposition des gesuchten Strings, dessen
Länge und der mit der Markierungsfarbe gebildete HighlightPainter
als Parameter übergeben.
private void scrollToHighlight() { Rectangle rect = null; try { rect = area.modelToView(area.getText().indexOf(field.getText())); } catch (BadLocationException e1) { } if (rect != null) { area.scrollRectToVisible(rect); } } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new HighlighterBsp()); }
Die Methode scrollToHighlight()
bewirkt,
dass der Text der Area ggfs. zur ersten Markierung
gescrollt wird. Erreicht wird dies dadurch, dass ein
Rechteck ermittelt wird, das am Startpunkt des ersten
Vorkommens des gesuchten Textes im Areatext lokalisiert
ist. Der Methode scrollRectToVisible()
wird
dieses Rectangle
-Objekt übergeben.
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Rectangle; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultHighlighter; import javax.swing.text.Highlighter; public class HighlighterBsp { private JTextArea area; private JTextField field; private static final String TEXT = "Lorem ipsum dolor sit amet, consectetur " + "adipisici elit, sed eiusmod tempor incidunt ut labore et dolore " + "magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation " + "ullamco laboris nisi ut aliquid ex commodi consequat. " + "Quis aute iure reprehenderit in voluptate velit esse cillum " + "dolore eu fugiat nulla pariatur."; public HighlighterBsp() { initGUI(); } private void initGUI() { area = new JTextArea(TEXT, 10, 20); area.setLineWrap(true); area.setWrapStyleWord(true); JScrollPane scrollPane = new JScrollPane(area); field = new JTextField(); field.addKeyListener(new KeyAdapter() { public void keyReleased(KeyEvent e) { search(); } }); JFrame frame = new JFrame(); frame.add(field, BorderLayout.PAGE_START); frame.add(scrollPane, BorderLayout.CENTER); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("Highlighter-Beispiel"); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } private void search() { area.getHighlighter().removeAllHighlights(); if (field.getText() == null) { return; } highlightString(Color.YELLOW, field.getText()); scrollToHighlight(); } private String highlightString(Color color, String target) { String text = null; try { Highlighter highlighter = area.getHighlighter(); text = area.getText(); int pos = 0; Highlighter.HighlightPainter hp = new DefaultHighlighter.DefaultHighlightPainter(color); if (target.length() > 0) { while ((pos = text.indexOf(target, pos)) >= 0) { highlighter.addHighlight(pos, pos + target.length(), hp); pos += target.length(); } } } catch (BadLocationException e) { } return text; } private void scrollToHighlight() { Rectangle rect = null; try { rect = area.modelToView(area.getText().indexOf(field.getText())); } catch (BadLocationException e1) { } if (rect != null) { area.scrollRectToVisible(rect); } } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new HighlighterBsp()); } }
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.