{"id":8,"date":"2007-03-18T15:33:09","date_gmt":"2007-03-18T20:33:09","guid":{"rendered":"http:\/\/wp.javatechniques.com\/blog\/setting-jtextpane-font-and-color\/"},"modified":"2007-06-25T12:53:10","modified_gmt":"2007-06-25T17:53:10","slug":"setting-jtextpane-font-and-color","status":"publish","type":"page","link":"http:\/\/javatechniques.com\/blog\/setting-jtextpane-font-and-color\/","title":{"rendered":"Setting JTextPane Font and Color"},"content":{"rendered":"<p><center><br \/>\n<script type=\"text\/javascript\"><!--\ngoogle_ad_client = \"pub-6996704245138669\";\ngoogle_ad_width = 468;\ngoogle_ad_height = 60;\ngoogle_ad_format = \"468x60_as\";\ngoogle_ad_type = \"text\";\ngoogle_ad_channel = \"\";\ngoogle_color_border = \"663300\";\ngoogle_color_bg = \"330000\";\ngoogle_color_link = \"FFFFFF\";\ngoogle_color_text = \"AECCEB\";\ngoogle_color_url = \"AECCEB\";\n\/\/-->\n<\/script><br \/>\n<script type=\"text\/javascript\"\n  src=\"http:\/\/pagead2.googlesyndication.com\/pagead\/show_ads.js\">\n<\/script><br \/>\n<\/center><\/p>\n<p>Swing&#8217;s <CODE>javax.swing.JTextPane<\/CODE> class represents a significant improvement over AWT&#8217;s <CODE>TextArea<\/CODE>. It allows complex combinations of character and paragraph attributes, embedded images and components, and other features that let you build styled text editors. Unfortunately, however, while <CODE>JTextPane<\/CODE> makes complex things possible, it makes some simple things difficult. Two examples are setting the default font and color.<\/p>\n<p>Figure 1 shows an example of creating an AWT <CODE>TextArea<\/CODE> that uses a 20-point blue serif font.<br \/>\n<HR><\/p>\n<pre>\r\n\r\nimport java.awt.TextArea;\r\nimport java.awt.Frame;\r\n\r\nimport java.awt.event.WindowEvent;\r\nimport java.awt.event.WindowListener;\r\nimport java.awt.event.WindowAdapter;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Font;\r\nimport java.awt.BorderLayout;\r\n\r\npublic class Example1 extends WindowAdapter {\r\n\r\n    public Example1() {\r\n        Frame f = new Frame(\"TextArea Example\");\r\n        f.setLayout(new BorderLayout());\r\n\r\n        \/\/ Make a text area, set its font and color, then add it to the frame\r\n        TextArea text = new TextArea();\r\n        Font font = new Font(\"Serif\", Font.ITALIC, 20);\r\n        text.setFont(font);\r\n        text.setForeground(Color.blue);\r\n        f.add(text, BorderLayout.CENTER);\r\n\r\n        \/\/ Listen for the user to click the frame's close box\r\n        f.addWindowListener(this);\r\n        f.setSize(400, 400);\r\n        f.show();\r\n    }\r\n\r\n    public void windowClosing(WindowEvent evt) {\r\n        System.exit(0);\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        Example1 instance = new Example1();\r\n    }\r\n\r\n}\r\n<\/pre>\n<p><HR><br \/>\n<CENTER>Figure 1. Setting text font and color on an AWT <CODE>TextArea<\/CODE><\/CENTER><\/p>\n<p>The code in Figure 1 includes a call to <CODE>TextArea<\/CODE>&#8216;s <CODE>setFont(&#8230;)<\/CODE> and <CODE>setForeground(&#8230;)<\/CODE> methods, which set the font and color of all of the text in the component. Figure 2 shows a (seemingly) equivalent example using Swing&#8217;s <CODE>JFrame<\/CODE> and <CODE>JTextPane<\/CODE> classes.<\/p>\n<p><HR><\/p>\n<pre>\r\n\r\nimport javax.swing.JTextPane;\r\nimport javax.swing.JFrame;\r\n\r\nimport java.awt.event.WindowEvent;\r\nimport java.awt.event.WindowListener;\r\nimport java.awt.event.WindowAdapter;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Font;\r\nimport java.awt.BorderLayout;\r\n\r\npublic class Example2 extends WindowAdapter {\r\n\r\n    public Example2() {\r\n        JFrame f = new JFrame(\"First JTextPane Example\");\r\n        f.getContentPane().setLayout(new BorderLayout());\r\n\r\n        \/\/ Make a text pane, attempt to set its font and color, then \r\n        \/\/ add it to the frame\r\n        JTextPane text = new JTextPane();\r\n        Font font = new Font(\"Serif\", Font.ITALIC, 20);\r\n        text.setFont(font);\r\n        text.setForeground(Color.blue);\r\n        f.getContentPane().add(text, BorderLayout.CENTER);\r\n\r\n        \/\/ Listen for the user to click the frame's close box\r\n        f.addWindowListener(this);\r\n        f.setSize(400, 400);\r\n        f.show();\r\n    }\r\n\r\n    public void windowClosing(WindowEvent evt) {\r\n        System.exit(0);\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        Example2 instance = new Example2();\r\n    }\r\n\r\n}\r\n<\/pre>\n<p><HR><br \/>\n<CENTER>Figure 2. <I>Seemingly<\/I> equivalent version of Figure 1 using a Swing <CODE>JTextPane<\/CODE><\/CENTER><\/p>\n<p>The code in Figure 2 does not produce the desired result: The text pane uses the default font and color (defined by the current Swing look-and-feel), rather than the font and color passed to the <CODE>setFont(&#8230;)<\/CODE> and <CODE>setForeground(&#8230;)<\/CODE> methods. The explanation for this lies in <CODE>JTextPane<\/CODE>&#8216;s flexibility. Since each character can have a different font and color, the notion of setting the font and color for all of the text does not make as much sense as it does in the case of the less-flexible <CODE>TextArea<\/CODE>.<\/p>\n<p>The trick is to set the character attributes for the entire text content. If the text pane is empty, the character attributes will be used for any text entered later. Figure 3 shows an example of this. The static method <CODE>setJTextPaneFont(&#8230;)<\/CODE> contains the logic for updating a <CODE>JTextPane<\/CODE>&#8216;s attributes from <CODE>Font<\/CODE> and <CODE>Color<\/CODE> objects.<\/p>\n<p><HR><\/p>\n<pre>\r\n\r\nimport javax.swing.JTextPane;\r\nimport javax.swing.JFrame;\r\nimport javax.swing.text.StyledDocument;\r\nimport javax.swing.text.StyleConstants;\r\nimport javax.swing.text.MutableAttributeSet;\r\n\r\nimport java.awt.event.WindowEvent;\r\nimport java.awt.event.WindowListener;\r\nimport java.awt.event.WindowAdapter;\r\n\r\nimport java.awt.Color;\r\nimport java.awt.Font;\r\nimport java.awt.BorderLayout;\r\n\r\npublic class Example3 extends WindowAdapter {\r\n\r\n    public Example3() {\r\n        JFrame f = new JFrame(\"Second JTextPane Example\");\r\n        f.getContentPane().setLayout(new BorderLayout());\r\n\r\n        \/\/ Make a text pane, set its font and color, then add it to the frame\r\n        JTextPane text = new JTextPane();\r\n        Font font = new Font(\"Serif\", Font.ITALIC, 20);\r\n        setJTextPaneFont(text, font, Color.blue);\r\n        f.getContentPane().add(text, BorderLayout.CENTER);\r\n\r\n        \/\/ Listen for the user to click the frame's close box\r\n        f.addWindowListener(this);\r\n        f.setSize(400, 400);\r\n        f.show();\r\n    }\r\n\r\n    \/**\r\n     * Utility method for setting the font and color of a JTextPane. The\r\n     * result is roughly equivalent to calling setFont(...) and \r\n     * setForeground(...) on an AWT TextArea.\r\n     *\/\r\n    public static void setJTextPaneFont(JTextPane jtp, Font font, Color c) {\r\n        \/\/ Start with the current input attributes for the JTextPane. This\r\n        \/\/ should ensure that we do not wipe out any existing attributes\r\n        \/\/ (such as alignment or other paragraph attributes) currently\r\n        \/\/ set on the text area.\r\n        MutableAttributeSet attrs = jtp.getInputAttributes();\r\n\r\n        \/\/ Set the font family, size, and style, based on properties of\r\n        \/\/ the Font object. Note that JTextPane supports a number of\r\n        \/\/ character attributes beyond those supported by the Font class.\r\n        \/\/ For example, underline, strike-through, super- and sub-script.\r\n        StyleConstants.setFontFamily(attrs, font.getFamily());\r\n        StyleConstants.setFontSize(attrs, font.getSize());\r\n        StyleConstants.setItalic(attrs, (font.getStyle() & Font.ITALIC) != 0);\r\n        StyleConstants.setBold(attrs, (font.getStyle() & Font.BOLD) != 0);\r\n\r\n        \/\/ Set the font color\r\n        StyleConstants.setForeground(attrs, c);\r\n\r\n        \/\/ Retrieve the pane's document object\r\n        StyledDocument doc = jtp.getStyledDocument();\r\n\r\n        \/\/ Replace the style for the entire document. We exceed the length\r\n        \/\/ of the document by 1 so that text entered at the end of the\r\n        \/\/ document uses the attributes.\r\n        doc.setCharacterAttributes(0, doc.getLength() + 1, attrs, false);\r\n    }\r\n\r\n    public void windowClosing(WindowEvent evt) {\r\n        System.exit(0);\r\n    }\r\n\r\n    public static void main(String[] args) {\r\n        Example3 instance = new Example3();\r\n    }\r\n\r\n}\r\n<\/pre>\n<p><HR><br \/>\n<CENTER>Figure 3. Setting font and color on a <CODE>JTextPane<\/CODE><\/CENTER><\/p>\n<p>The example in Figure 3 will produce 20-point blue text within the <CODE>JTextPane<\/CODE>.<\/p>\n<p>Of course, <CODE>JTextPane<\/CODE> is not intended as a direct replacement for the AWT <CODE>TextArea<\/CODE>. Swing includes a <CODE>JTextArea<\/CODE> class that mimics <CODE>TextArea<\/CODE>&#8216;s behavior much more closely, and provides direct source code compatibility. There are, however, reasons to use <CODE>JTextPane<\/CODE> instead of <CODE>JTextArea<\/CODE> even in cases where you do not need to support multiple fonts within the text component. For example, <CODE>JTextArea<\/CODE> does not support embedded images or alternate text alignment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Swing&#8217;s javax.swing.JTextPane class represents a significant improvement over AWT&#8217;s TextArea. It allows complex combinations of character and paragraph attributes, embedded images and components, and other features that let you build styled text editors. Unfortunately, however, while JTextPane makes complex things possible, it makes some simple things difficult. Two examples are setting the default font and &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/javatechniques.com\/blog\/setting-jtextpane-font-and-color\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Setting JTextPane Font and Color&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-8","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/pages\/8","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/comments?post=8"}],"version-history":[{"count":0,"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/pages\/8\/revisions"}],"wp:attachment":[{"href":"http:\/\/javatechniques.com\/blog\/wp-json\/wp\/v2\/media?parent=8"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}