In Ihrem Leben als Java-EntwicklerIn ist es wohl eher unwahrscheinlich, dass Sie eine komplette Textverarbeitung in Java programmieren werden. Dennoch können Sie mit dem punktuellen Einsatz von Formatierungen und Textauszeichnungen Ihre Anwendungen optisch aufwerten und ergonomischer gestalten. Beispiel Hilfetexte: Selbst wenn Sie nicht die JavaHelp-Technologie einsetzen, können Sie erläuternde Dokumentation zu Ihren Anwendungen in HTML verfassen und durch Swing-Komponenten anzeigen lassen. Beispiel Annotationen: Ein Benutzer mag zu einzelnen Datensätzen eines Geschäftsvorgangs eigene Bemerkungen hinzufügen. Hierbei könnte es ihm erlaubt sein, einzelne Wörter fett oder kursiv hervorzuheben. Beispiel Konsole: Eine Anwendung, die eine länger dauernde Aktion in einem separatem Thread oder System-Prozess startet, mag die verschiedenen Ausgaben dieser Aktion in einer Konsole anzeigen. Warnungen oder Fehler (oder Ausgaben nach System.err anstatt System.out) könnten sogleich durch eine rote Schrift automatisch kenntlich gemacht werden. Beispiel Syntax Highlighting: Ein Editor für eine proprietäre Skript- oder Makrosprache könnte Schlüsselwörter und Kommentare farblich hervorheben. Für diese verschiedenen Anwendungsfälle bietet Ihnen das Swing-API jeweils unterschiedlich geeignete Mittel und Wege:
- Mit der JEditorPane können Sie Texte im HTML- oder RTF-Format anzeigen lassen.
- Mit AttributeSets können Sie programmatisch Textattribute ändern und neue Abschnitte mit speziell definierten Formatierungen einfügen.
- Mit Styles können Sie benannte AttributeSets komfortabler verwenden.
- Mit EditorKits bekommen Sie Actions zur Textmanipulation, die Sie direkt an Oberflächenkomponenten wie JMenuItems oder JButtons anbinden können.
JEditorPane
JEditorPane bietet sich an, wenn Sie komplette Texte im HTML- oder RTF-Format darstellen wollen. Diese können schon statisch vorliegen, wie etwa Hilfetexte, Sie können sie aber auch dynamisch zur Laufzeit des Programms zusammenbauen, wie etwa Berichte über einen Datenbestand (Abb. 1).import java.awt.*;import java.text.*;import java.util.*;import javax.swing.*;class HtmlStringAnzeiger extends JPanel {public static void main(String args[]) throws Exception {JFrame f = new JFrame("HtmlStringAnzeiger");// Hier wird der anzuzeigende Text dynamisch zur// Laufzeit zusammengestellt.DateFormat dateFormat =DateFormat.getDateInstance(DateFormat.LONG);int wert = 3;String text ="<h1>Inventar</h1><p>Am "+dateFormat.format(new Date())+" besitzen Sie </p><ul><li>"+wert+" Exemplare der besonders seltenen marelukkischen</li></ul>";f.getContentPane().add(new HtmlStringAnzeiger(text), BorderLayout.CENTER);f.setBounds(10,10,225,180);f.setVisible(true);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}// Hier wird einer JEditorPane der Mime-Type und der Text// zugewiesen und diese dann in eine JScrollPane gepacktHtmlStringAnzeiger(String text) throws Exception {setLayout(new BorderLayout());JEditorPane pane = new JEditorPane();pane.setContentType("text/html");pane.setText(text);pane.setEditable(false);JScrollPane scrollPane = new JScrollPane(pane);add(scrollPane, BorderLayout.CENTER);}
public void insertBeforeStart(<br></br> Element elem,String htmlText)oderpublic void insertAfterEnd(Element elem,String htmlText)
AttributeSets
Nun schauen wir uns an, wie Sie eine Textanzeige realisieren können, in der Sie auch zur Laufzeit Ihres Programms noch weiteren formatierten Text anfügen können, etwa für eine Konsole zur Anzeige von Ergebnissen eines separat ablaufenden Prozesses, oder für ein Dialogsystem. Sie beginnen mit einer Instanz von JTextPane (das ist eine von JEditorPane abgeleitete Klasse). Diese JTextPane können Sie wie üblich in eine JScrollPane einbauen und dann irgendwo anzeigen. Zum Textanfügen arbeiten Sie allerdings mit dem Model, das ist ein StyledDocument, welches Sie sich von der JTextPane geben lassen. Die uns in erster Linie interessierende Methode lautet:public void insertString(int offset,String str,AttributeSet a)throws BadLocationException
public static void setBold(MutableAttributeSet a, boolean b)public static void setForeground(MutableAttributeSet a, Color fg)public static void setFontSize(MutableAttributeSet a, int s)
import java.awt.*;import javax.swing.*;import javax.swing.text.*;public class TextMitAttributeSets {public static void main(String args[]) throws Exception {JFrame frame = new JFrame("TextMitAttributeSets");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JTextPane pane = new JTextPane();pane.setEditable(false);// Arbeite nicht mit der Pane, sondern mit dem darunterliegenden ModelDocument doc = pane.getStyledDocument();// Das erste Wort ohne irgendwelche speziellen Attribute (null)doc.insertString(doc.getLength(), "Drei ",null);// Baue ein AttributeSet für kleine Schrift und verwende dieses// für das nächste WortSimpleAttributeSet klein = new SimpleAttributeSet();StyleConstants.setFontSize(klein, 10);doc.insertString(doc.getLength(), "kleine ",klein);// Baue ein AttributeSet für fette rosa Schrift// und verwende dieses für das letzte WortSimpleAttributeSet fettRosa = new SimpleAttributeSet();StyleConstants.setBold(fettRosa, true);StyleConstants.setForeground(fettRosa, Color.PINK);doc.insertString(doc.getLength(),"Schweinchen", fettRosa);JScrollPane scrollPane = new JScrollPane(pane);frame.getContentPane().add(scrollPane, BorderLayout.CENTER);frame.setSize(200, 60);frame.setVisible(true);}}
Syntax Highlighting
Eine weitere Methode von StyledDocuments ist:setCharacterAttributes(int offset,int length,AttributeSet s,boolean replace)
Styles
Ein Style ist ein Interface für benannte AttributeSets. Das uns schon bekannte StyledDocument erlaubt auch, neue Styles durch Angabe eines Namens zu definieren. Der Clou ist, dass neue Styles einen bestehenden anderen als Parent bekommen und dessen Attribute zur Darstellung herangezogen werden. Deswegen müssen Sie nur neue, abweichende Attribute wirklich setzen. Sie gehen dabei von einem default-Style aus, der bereits definiert ist. Die Methode addStyle() hat einen eigentlich irreführenden Namen, Sie müssen nämlich den Namen des neuen Styles und den Parent-Style übergeben und bekommen den neuen Style zurück. Diesen werden Sie in der Regel noch variieren, und zwar am günstigsten mit den Hilfsmethoden von StyleConstants (Listing 3) Listing 3// Der Default-Style als Parent der anderen wird angepaßt.Style defaultStyle = doc.getStyle("default");StyleConstants.setFontSize(defaultStyle, 14);StyleConstants.setFontFamily(defaultStyle, "SansSerif");// Zwei neue Styles mit dem Default-Style als Parent.Style eingabeStyle = doc.addStyle("eingabe", defaultStyle);StyleConstants.setForeground(eingabeStyle, Color.blue);StyleConstants.setItalic(eingabeStyle, true);Style ausgabeStyle = doc.addStyle("ausgabe", defaultStyle);// Der Fehler-Style ist eine Variante des Ausgabe-StylesStyle fehlerStyle = doc.addStyle("fehler", ausgabeStyle);StyleConstants.setForeground(fehlerStyle, Color.red);
// Über den Namen wird durch das StyledDocument der richtige// Style ausgewählt und wie ein AttributeSet eingesetzt.public void append(String text, String styleName) {try {doc.insertString(doc.getLength(), text, doc.getStyle(styleName));}catch(BadLocationException ignore){}setCaretPosition(doc.getLength());}
EditorKits
Die JTextPane und die JEditorPane verwenden - abhängig vom Inhaltstyp - intern unterschiedliche EditorKits, mit denen wir bisher nicht viel Kontakt hatten. Ihr praktischer Nutzwert liegt darin, dass sie Actions anbieten, die Sie direkt mit AbstractButtons (also zum Beispiel JButtons oder JMenuItems) verbinden können. Wählt ein Benutzer einen solchen Knopf oder Menüeintrag aus, wird sogleich die actionPerformed()-Methode der Action aufgerufen und darüber der Text manipuliert; Sie müssen keinen weiteren zusätzlichen Code schreiben! Ein gewisser Aufwand besteht aber darin, aus dem Array aller implementierten Actions die geeigneten herauszufinden. Eine Übersicht über die bereits vorhandenen Actions bekommen Sie mit einer einfachen Schleife wie etwa folgender: Das Beispiel auf der Leser-CD zeigt die Actions der drei EditorKit-Klassen DefaultEditorKit, StyledEditorKit und HTMLEditorKit. Darunter sind sowohl Actions zum Bewegen des Carets und zum Auswählen von Textbereichen als auch zum Setzen von AttributeSets. Und als Sahnehäubchen ist es bei dem StyledEditorKit möglich, mit geeigneten Konstruktoren zusätzliche, parametrisierte Actions zu erzeugen, die ebenfalls an AbstractButtons angebunden werden können und neue, bisher noch nicht definierte Styles setzen.import java.awt.*;import java.util.*;import javax.swing.*;import javax.swing.text.*;import javax.swing.text.html.*;class AnnotationEditorStyled extends JFrame {JTextPane pane;Hashtable actionTable;public static void main(String args[]) throws Exception {new AnnotationEditorStyled();}AnnotationEditorStyled() {super("AnnotationEditorStyled");pane = new JTextPane();JScrollPane scrollPane = new JScrollPane(pane);getContentPane().add(scrollPane, BorderLayout.CENTER);initActionTable();initToolbar();setBounds(10,10,225,180);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}// Alle Actions werden unter ihrem Namen in einer Hashtable abgelegtprivate void initActionTable() {actionTable = new Hashtable();StyledEditorKit editorKit = (StyledEditorKit) pane.getEditorKit();Action[] actions = editorKit.getActions();for (int i=0; i < actions.length; i++) {Action action = actions[i];actionTable.put(action.getValue(Action.NAME),action);}}// Im Toolbar werden drei Knöpfe an drei Actions angebunden.private void initToolbar() {JToolBar toolBar = new JToolBar();// Ein Knopf an die vorhandene Action "font-bold"JButton boldButton = new JButton(new ImageIcon("images/bold.gif"));boldButton.addActionListener((Action)actionTable.get("font-bold"));toolBar.add(boldButton);// Ein Knopf an die vorhandene Action "font-italic"JButton italicButton = new JButton(new ImageIcon("images/italic.gif"));italicButton.addActionListener((Action)actionTable.get("font-italic"));toolBar.add(italicButton);getContentPane().add(toolBar, BorderLayout.NORTH);// Ein Knopf an eine neu erzeugte Action, die die Vordergrundfarbe// auf den im Konstruktor übergebenen Wert setzt.JButton rotButton = new JButton(new ImageIcon("images/rot.gif"));rotButton.addActionListener(new StyledEditorKit.ForegroundAction("rot",Color.red));toolBar.add(rotButton);getContentPane().add(toolBar, BorderLayout.NORTH);}}




