In diesem Artikel zeige ich Euch die Basisformatierungen der JTextPane-Komponente, nämlich das markieren der gewünschten Textstelle in Bold (Fett), Italic (Kursiv) und Underline (Unterstrich).
Als Basis dient das TextPane RTF und ich habe drei Buttons für Bold, Italic und Underline hinzugefügt. Auch an dieser Stelle kommt der Hinweis, das Ihr zum Nacharbeiten des Beispiels intelliJ IDEA benötigt.
Wie funktioniert die Formatierung? Ihr benötigt als Erstes eine Routine (textPane.addCaretListener), welche auf Selektionen im TextPane achtet und die „Koordinaten“ für den Beginn und das Ende in die Variablen selectionStart und selectionEnd überträgt. Zusätzlich erhält das StyledDocument die Koordinaten übermittelt.
Der Klick auf den jeweiligen Formatierungs-Button löst immer die gleiche Aktionskette aus: auslesen der Formatierung am Anfang der Selektion, ein Umschalter für die gewünschte Formatierung (z.B. wenn es nicht Bold-formatiert war ist der Text nun Bold, ist der Text vorher Italic-formatiert wird daraus „nicht“-Italic).
Zur Unterstützung dient die Methode „public MutableAttributeSet setStyles(MutableAttributeSet attr)“, welche die Formatierungen ausliest und zwischenspeichert.
Ein Tipp von meiner Seite: Ihr solltet Euch diese Bearbeitungsschritte genau ansehen, denn darauf wird bei den anderen Formatierungen immer wieder zugegriffen.
Hier nun der Sourcecode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
/* * Herkunft/Origin: http://java-crypto.bplaced.net/ * Programmierer/Programmer: Michael Fehr * Copyright/Copyright: frei verwendbares Programm (Public Domain) * Copyright: This is free and unencumbered software released into the public domain. * Lizenttext/Licence: <http://unlicense.org> * getestet mit/tested with: Java Runtime Environment 11.0.5 x64 * verwendete IDE/used IDE: intelliJ IDEA 2019.3.1 * Datum/Date (dd.mm.jjjj): 31.12.2019 * Funktion: TextPane Bold-Italic-Underline = * formatiert selektierten Text in Bold/Italic/Underline * Function: TextPane Bold-Italic-Underline = * format of selected text in bold/italic/underline * * Hinweis/Notice * Sie benoetigen intelliJ um das Programm uebersetzen und ausfuehren zu koennen * You need intelliJ to build and run the program */ import javax.swing.*; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.text.*; import javax.swing.text.rtf.RTFEditorKit; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; public class TextPane { private JPanel panelMain; private JPanel panelButtons; private JButton buttonLoad; private JScrollPane scrollPane; private JTextPane textPane; private JButton buttonSave; private JButton buttonBold; private JButton buttonItalic; private JButton buttonUnderline; private int selectionStart, selectionEnd; private AttributeSet selectedAttribute; public TextPane() { textPane.setContentType("text/rtf"); textPane.setEditorKit(new RTFEditorKit()); buttonLoad.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { loadRtf("textpane_rtf.rtf"); } }); buttonSave.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { saveRtf("textpane_rtf.rtf"); } }); buttonBold.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { toggleBold(); } }); buttonItalic.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { toggleItalic(); } }); buttonUnderline.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { toggleUnderline(); } }); // notwendig für selections textPane.addCaretListener(new CaretListener() { // achtet auf selektion @Override public void caretUpdate(CaretEvent caretEvent) { selectionStart = textPane.getSelectionStart(); selectionEnd = textPane.getSelectionEnd(); StyledDocument doc = textPane.getStyledDocument(); selectedAttribute = doc.getCharacterElement(selectionStart).getAttributes(); selectionStart = textPane.getSelectionStart(); } }); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setContentPane(new TextPane().panelMain); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setTitle("TextPane Bold/Italic/Underline"); frame.setSize(500, 300); frame.setVisible(true); } public void loadRtf(String filename) { RTFEditorKit RTF_KIT = new RTFEditorKit(); textPane.setContentType("text/rtf"); InputStream inputStream; try { inputStream = new FileInputStream(filename); final DefaultStyledDocument styledDocument = new DefaultStyledDocument(new StyleContext()); RTF_KIT.read(inputStream, styledDocument, 0); textPane.setDocument(styledDocument); // delete added last line String content = textPane.getDocument().getText(0, textPane.getDocument().getLength()); int lastLineBreak = content.lastIndexOf('\n'); textPane.getDocument().remove(lastLineBreak, textPane.getDocument().getLength() - lastLineBreak); } catch (IOException | BadLocationException e) { e.printStackTrace(); } textPane.requestFocus(); } public void saveRtf(String filename) { try { FileOutputStream fos = new FileOutputStream(filename); RTFEditorKit kit = (RTFEditorKit) textPane.getEditorKit(); StyledDocument doc = textPane.getStyledDocument(); int len = doc.getLength(); kit.write(fos, doc, 0, len); fos.close(); } catch (IOException | BadLocationException e) { e.printStackTrace(); } textPane.requestFocus(); } // AttributeSet public MutableAttributeSet setStyles(MutableAttributeSet attr) { String font = StyleConstants.getFontFamily(selectedAttribute); StyleConstants.setFontFamily(attr, font); int size = StyleConstants.getFontSize(selectedAttribute); StyleConstants.setFontSize(attr, size); Color c = StyleConstants.getForeground(selectedAttribute); StyleConstants.setForeground(attr, c); Boolean bold = StyleConstants.isBold(selectedAttribute); StyleConstants.setBold(attr, bold); Boolean underline = StyleConstants.isUnderline(selectedAttribute); StyleConstants.setItalic(attr, underline); Boolean italic = StyleConstants.isItalic(selectedAttribute); StyleConstants.setItalic(attr, italic); return attr; } private void changeStyleBold() { StyledDocument doc = (StyledDocument) textPane.getDocument(); if (selectionStart == selectionEnd) { return; } Element element = doc.getCharacterElement(selectionStart); AttributeSet as = element.getAttributes(); MutableAttributeSet asNew = new SimpleAttributeSet(as.copyAttributes()); StyleConstants.setBold(asNew, !StyleConstants.isBold(as)); doc.setCharacterAttributes(selectionStart, textPane.getSelectedText() .length(), asNew, true); textPane.select(selectionStart, selectionEnd); } private void changeStyleItalic() { StyledDocument doc = (StyledDocument) textPane.getDocument(); if (selectionStart == selectionEnd) { return; } Element element = doc.getCharacterElement(selectionStart); AttributeSet as = element.getAttributes(); MutableAttributeSet asNew = new SimpleAttributeSet(as.copyAttributes()); StyleConstants.setItalic(asNew, !StyleConstants.isItalic(as)); doc.setCharacterAttributes(selectionStart, textPane.getSelectedText() .length(), asNew, true); textPane.select(selectionStart, selectionEnd); } private void changeStyleUnderline() { StyledDocument doc = (StyledDocument) textPane.getDocument(); if (selectionStart == selectionEnd) { return; } Element element = doc.getCharacterElement(selectionStart); AttributeSet as = element.getAttributes(); MutableAttributeSet asNew = new SimpleAttributeSet(as.copyAttributes()); StyleConstants.setUnderline(asNew, !StyleConstants.isUnderline(as)); doc.setCharacterAttributes(selectionStart, textPane.getSelectedText() .length(), asNew, true); textPane.select(selectionStart, selectionEnd); } private void toggleBold() { changeStyleBold(); textPane.requestFocus(); } private void toggleItalic() { changeStyleItalic(); textPane.requestFocus(); } private void toggleUnderline() { changeStyleUnderline(); textPane.requestFocus(); } } |
Der XML-Code der Form:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
<?xml version="1.0" encoding="UTF-8" ?> - <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="TextPane"> - <grid id="27dc6" binding="panelMain" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="10" left="10" bottom="10" right="10" /> - <constraints> <xy x="20" y="20" width="500" height="400" /> </constraints> <properties /> <border type="none" /> - <children> - <grid id="69623" binding="panelButtons" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0" /> - <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false" /> </constraints> <properties /> <border type="none" /> - <children> - <component id="b1559" class="javax.swing.JButton" binding="buttonLoad"> - <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="load" /> </properties> </component> - <component id="1e556" class="javax.swing.JButton" binding="buttonSave"> - <constraints> <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="save" /> </properties> </component> - <component id="26a30" class="javax.swing.JButton" binding="buttonBold"> - <constraints> <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="bold" /> </properties> </component> - <component id="3071f" class="javax.swing.JButton" binding="buttonItalic"> - <constraints> <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="italic" /> </properties> </component> - <component id="cf008" class="javax.swing.JButton" binding="buttonUnderline"> - <constraints> <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="underline" /> </properties> </component> </children> </grid> - <scrollpane id="5bf0e" binding="scrollPane"> - <constraints> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false" /> </constraints> <properties /> <border type="none" /> - <children> - <component id="100bc" class="javax.swing.JTextPane" binding="textPane"> <constraints /> <properties /> </component> </children> </scrollpane> </children> </grid> </form> |
Alle Quellcodes zur JTextPane findet Ihr zum Download in meinem Github-Repository, welches Ihr über diesen Link erreicht: https://github.com/java-crypto/JTextPane. Alle Programme sind unter Java 11 lauffähig (vermutlich auch unter Java 8) und wurden mit intelliJ IDEA entwickelt, welches für das eigene „Spielen“ notwendig ist.
Die Lizenz zum obigen Beispiel findet Ihr auf der eigenen Lizenz-Seite.
Letzte Bearbeitung: 31.12.2019