{"id":909,"date":"2021-01-11T21:21:19","date_gmt":"2021-01-11T21:21:19","guid":{"rendered":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/?page_id=909"},"modified":"2021-01-12T00:24:31","modified_gmt":"2021-01-12T00:24:31","slug":"text-input-components","status":"publish","type":"page","link":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/","title":{"rendered":"Text Input Components"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_84 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a21d08ac5b86\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a21d08ac5b86\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JTextComponent\" >JTextComponent<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JTextField\" >JTextField<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JPasswordField\" >JPasswordField<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JTextArea\" >JTextArea<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#The_Document_Model\" >The Document Model<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#Tracking_Text_Changes\" >Tracking Text Changes<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#Input_Validation\" >Input Validation<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JFormattedTextField\" >JFormattedTextField<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#Scrolling_and_Wrapping_Text_in_a_JTextArea\" >Scrolling and Wrapping Text in a JTextArea<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/text-input-components\/#JTextArea_Editing\" >JTextArea Editing<\/a><\/li><\/ul><\/nav><\/div>\n\n<p class=\"wp-block-paragraph\">There is a (small) family of components whose purpose in life is to display text, and also to accept changes to that text.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The two most commonly used members of the family are:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><code>JTextField<\/code><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">and<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><strong><code>JTextArea<\/code><\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">both of which extend the abstract class&nbsp;<strong><code>JTextComponent<\/code><\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are also some other text input components that we&#8217;ll cover, and a number of more complex ones that we won&#8217;t cover.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JTextComponent\"><\/span>JTextComponent<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The abstract class&nbsp;<strong><code>JTextComponent<\/code><\/strong>&nbsp;is the superclass for all text components.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It contains a number of useful methods, the most commonly used of which are:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><th>Method<\/th><th>Description<\/th><\/tr><tr><td><code><strong>public void setText(String&nbsp;t)<\/strong><\/code><\/td><td>Sets the text that is presented by this text component to be the specified text.<br>If t is null, the text is set to the empty string (&#8220;&#8221;).<\/td><\/tr><tr><td><code><strong>public String getText()<\/strong><\/code><\/td><td>Gets the text that is presented by this text component.<\/td><\/tr><tr><td><code><strong>public void setEditable(boolean&nbsp;b)<\/strong><\/code><\/td><td>Sets the flag that determines whether or not this text component is editable.<br>If the flag is set to&nbsp;<code>true<\/code>, this text component becomes user editable. If the flag is set to&nbsp;<code>false<\/code>, the user cannot change the text of this text component.<\/td><\/tr><tr><td><code><strong>public boolean isEditable()<\/strong><\/code><\/td><td>Indicates whether or not this text component is editable.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">These methods are pretty much self-describing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are also some other useful methods, but we won&#8217;t cover them at this point.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JTextField\"><\/span>JTextField<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong><code>JTextField<\/code><\/strong>&nbsp;is a text component that provides a single line of text.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here are some examples of how text fields can be used:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Font;\n\nimport javax.swing.JPanel;\nimport javax.swing.JFrame;\nimport javax.swing.JTextField;\n\nclass SimpleTextFieldsPanel extends JPanel\n{\n  public SimpleTextFieldsPanel()\n  {\n    JTextField look = new JTextField();\n    look.setText(&quot;Look at me!  I&#039;m a text field!&quot;);\n    add(look);\n    JTextField whoopee = new JTextField(8); \n                           \/\/ 8 characters in current font\n    whoopee.setText(&quot;Whoopee!&quot;);\n    whoopee.setForeground(Color.RED);\n    whoopee.setBackground(Color.BLUE);\n    whoopee.setFont(new Font(&quot;monospaced&quot;, Font.BOLD, 18));\n    add(whoopee);\n    String text = \n        &quot;Please quiet down up there; I&#039;m trying to sleep...&quot;;\n    JTextField conservative = new JTextField(text);\n    conservative.setEditable(false);\n    conservative.setFont(new Font(&quot;serif&quot;, Font.PLAIN, 10));\n    add(conservative);\n    JTextField bobby = \n        new JTextField(&quot;&#039;ere, &#039;ere, Wot&#039;s going on &#039;ere?&quot;);\n    bobby.setForeground(Color.YELLOW);\n    bobby.setBackground(Color.BLACK);\n    add(bobby);\n  }\n}\n\nclass SimpleTextFieldsFrame extends JFrame\n{\n  public SimpleTextFieldsFrame()\n  {\n    setTitle(&quot;SimpleTextFields&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new SimpleTextFieldsPanel() );\n  }\n}\n\npublic class SimpleTextFields\n{\n  public static void main(String&#x5B;] args)\n  {\n    SimpleTextFieldsFrame frame = \n                    new SimpleTextFieldsFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/SimpleTextFields.gif\" alt=\"\" class=\"wp-image-915\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:39px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that, when you set a text field as&nbsp;<em>not editable<\/em>, the default background color changes from white to light gray, and the border changes to make it look more 2-dimensional.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both foreground and background colors may be set.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JPasswordField\"><\/span>JPasswordField<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong><code>JPasswordField<\/code><\/strong>&nbsp;is a special case of a&nbsp;<code><strong>JTextField<\/strong><\/code>. (it&#8217;s a subclass of&nbsp;<code><strong>JTextField<\/strong><\/code>).&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It does not display the text stored in this field;&nbsp; instead, it echoes each character of the text with an &#8220;echo&#8221; character instead of the real character.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [9,21,22,23,24]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Container;\nimport java.awt.FlowLayout;\n\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JPasswordField;\nimport javax.swing.JTextField;\n\nclass PasswordFieldPanel extends JPanel\n{\n  public PasswordFieldPanel()\n  {\n    setLayout( new FlowLayout(FlowLayout.LEFT) );\n    JLabel userLabel = new JLabel(&quot;Username:&quot;);\n    add(userLabel);\n    JTextField user = new JTextField(25);\n    add(user);\n    JLabel passwordLabel = new JLabel(&quot;Password:&quot;);\n    add(passwordLabel);\n    JPasswordField password = new JPasswordField(25);\n    add(password);\n  }\n}\n\nclass PasswordFieldFrame extends JFrame\n{\n  public PasswordFieldFrame()\n  {\n    setTitle(&quot;PasswordField&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new PasswordFieldPanel() );\n  }\n}\n\npublic class PasswordField\n{\n  public static void main(String&#x5B;] args)\n  {\n    PasswordFieldFrame frame = new PasswordFieldFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/JPassw26.jpg\" alt=\"\" class=\"wp-image-919\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JTextArea\"><\/span>JTextArea<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<strong><code>JTextArea<\/code><\/strong>&nbsp;is a text component that allows more than a single line.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how to use text areas:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [8,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Container;\n\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.JTextArea;\n\nclass SimpleTextAreasPanel extends JPanel\n{\n  public SimpleTextAreasPanel()\n  {\n    setBackground(Color.cyan);\n    JTextArea area1 = new JTextArea(4, 10); \n                        \/\/ 4 lines of 10 characters\n    area1.setText(&quot;Hello!\\nI am an editable\\ntext area!&quot;);\n    add(area1);\n    \n    JTextArea area2 = \n        new JTextArea(&quot;A non-editable text area...&quot;);\n    area2.setEditable(false);\n    area2.setColumns(20);\n    area2.setRows(3);\n    area2.setForeground(Color.BLUE);\n    add(area2);\n    \n    JTextArea area3 = new JTextArea(\n        &quot;I&#039;m another non-editable text area,\\nyellow-on black&quot;);\n    area3.setEditable(false);\n    area3.setBackground(Color.BLACK);\n    area3.setForeground(Color.YELLOW);\n    add(area3);\n  }\n}\n\nclass SimpleTextAreasFrame extends JFrame\n{\n  public SimpleTextAreasFrame()\n  {\n    setTitle(&quot;SimpleTextAreas&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new SimpleTextAreasPanel() );\n  }\n}\n\npublic class SimpleTextAreas\n{\n  public static void main(String&#x5B;] args)\n  {\n    SimpleTextAreasFrame frame = new SimpleTextAreasFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/SimpleTextAreas.gif\" alt=\"\" class=\"wp-image-923\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:39px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that the non-editable text area does not have a different background color than the editable text area.&nbsp; Also, while the user cannot input anything into the non-editable text area, s\/he can select and copy text from it into the paste buffer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note also that a&nbsp;<code><strong>JTextArea<\/strong><\/code>&nbsp;has no standard built-in border decorations, which makes it rather boring.&nbsp; We&#8217;ll see how to improve matters soon.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Document_Model\"><\/span>The Document Model<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em><strong>model<\/strong><\/em>&nbsp;(remember MVC?) for all text components is the&nbsp;<code><strong>Document<\/strong><\/code>&nbsp;interface.&nbsp; Of course, that means that, in order to be a text component model, a class must implement the&nbsp;<code><strong>Document<\/strong>&nbsp;<\/code>interface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There are several document models which cover both plain text and formatted text, such as HTML.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Tracking_Text_Changes\"><\/span>Tracking Text Changes<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how you can use a document model to track changes in one or more text fields:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [20,21,38,39,46,50,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\n\nimport java.awt.geom.Ellipse2D;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Point2D;\n\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\n\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\n\nclass ClockTextFieldsFrame extends JFrame\n{\n  public ClockTextFieldsFrame()\n  {\n    setTitle(&quot;ClockTextFields&quot;);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    \n    \/\/ Create main panel and add it to the content pane\n    JPanel mainPanel = new JPanel(new BorderLayout());\n    Container contentPane = getContentPane();\n    contentPane.add(mainPanel);\n    \n    \/\/ Add the clock panel to the center of the main panel\n    mainPanel.add(m_clockPanel, BorderLayout.CENTER);\n    \n    \/\/ Prepare a document listener\n    DocumentListener listener = new ClockFieldListener();\n    \n    \/\/ Create the input panel containing text input fields,\n    \/\/ and connect the text input fields up with the listener\n    JPanel inputPanel = new JPanel();\n    inputPanel.add(new JLabel(&quot;Hours:&quot;));\n    inputPanel.add(m_hourField);\n    m_hourField.getDocument().addDocumentListener(listener);\n    \n    inputPanel.add(new JLabel(&quot;Minutes:&quot;));\n    inputPanel.add(m_minuteField);\n    m_minuteField.getDocument().addDocumentListener(listener);\n    \n    \/\/ Add the input panel to the south of the main panel\n    mainPanel.add(inputPanel, BorderLayout.SOUTH);\n    \n    \/\/ Set the clock&#039;s initial state\n    setClock();\n    \n    \/\/ Self-size the frame.\n    pack();\n  }\n  \n  private void setClock()\n  {\n    try\n    {\n      int hours = \n          Integer.parseInt(m_hourField.getText().trim());\n      int minutes = \n          Integer.parseInt(m_minuteField.getText().trim());\n      m_clockPanel.setTime(hours, minutes);\n    }\n    catch (NumberFormatException nfe)\n    {\n      \/\/ Don&#039;t set the clock on formatting errors.\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private ClockPanel m_clockPanel = new ClockPanel();\n  private JTextField m_hourField = new JTextField(&quot;12&quot;, 3);\n  private JTextField m_minuteField = new JTextField(&quot;00&quot;, 3);\n  \n  \/\/\/ Inner class \/\/\/\n  private class ClockFieldListener \n      implements DocumentListener\n  {\n    public void insertUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void removeUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void changedUpdate(DocumentEvent event)\n    {}\n  }\n}\n\nclass ClockPanel extends JPanel\n{\n  public ClockPanel()\n  {\n    \/\/ Set the preferred size of the panel \n    \/\/ for layout purposes (pack)\n    setPreferredSize(\n        new Dimension(2 * RADIUS + 1 + 10, \/\/ Insets\n                      2 * RADIUS + 1 + 10) \/\/ Insets\n                    );\n  }\n  \n  public void paintComponent(Graphics g)\n  {\n    super.paintComponent(g);\n    \n    Graphics2D g2 = (Graphics2D) g;\n    \n    \/\/ Create a BasicStroke for drawing outlines\n    BasicStroke stroke = new BasicStroke(3.0F,\n        BasicStroke.CAP_ROUND,\n        BasicStroke.JOIN_ROUND);\n    g2.setStroke(stroke);\n    \n    \/\/ Draw the outline of the clock\n    Ellipse2D circle = \n        new Ellipse2D.Double(INSET, INSET, \n                             2 * RADIUS,\n                             2 * RADIUS);\n    g2.setPaint(Color.GRAY);\n    g2.draw(circle);\n    \n    stroke = new BasicStroke(\n                  8.0F,\n                  BasicStroke.CAP_ROUND,\n                  BasicStroke.JOIN_ROUND);\n    g2.setStroke(stroke);\n    \n    \/\/ Draw the hour hand\n    double hourDegrees = \n        90 - 360 * m_minutes \/ (12 * 60);\n    double hourAngle = Math.toRadians(hourDegrees);\n    g2.setPaint(Color.BLUE);\n    drawHand(g2, hourAngle, HOUR_HAND_LENGTH);\n    \n    \/\/ Draw the minute hand\n    double minuteDegrees = 90 - 360 * m_minutes \/ 60;\n    double minuteAngle = Math.toRadians(minuteDegrees);\n    g2.setPaint(Color.BLUE);\n    drawHand(g2, minuteAngle, MINUTE_HAND_LENGTH);\n    \n    \/\/ Draw the axle\n    Ellipse2D axle = \n        new Ellipse2D.Double(INSET + RADIUS - AXLE_RADIUS,\n                             INSET + RADIUS - AXLE_RADIUS,\n                             2 * AXLE_RADIUS,\n                             2 * AXLE_RADIUS);\n    g2.setPaint(Color.RED);\n    g2.fill(axle);\n  }\n  \n  private void drawHand(Graphics2D g2, \n                        double angle, double handLength)\n  {\n    Point2D end = \n        new Point2D.Double(INSET + RADIUS +\n                              handLength * Math.cos(angle),\n                           INSET + RADIUS -\n                              handLength * Math.sin(angle));\n    Point2D center = \n        new Point2D.Double(INSET + RADIUS, INSET + RADIUS);\n    g2.draw(new Line2D.Double(center, end));\n  }\n  \n  public void setTime(int hours, int minutes)\n  {\n    m_minutes = hours * 60 + minutes;\n    repaint();\n  }\n  \n  \/\/\/\/\/\/ Private data \/\/\/\/\/\/\n  private static final int INSET = 5;\n  private static final int RADIUS = 100;\n  private static final double HOUR_HAND_LENGTH = \n                                   0.6 * RADIUS;\n  private static final double MINUTE_HAND_LENGTH = \n                                   0.9 * RADIUS;\n  private static final double AXLE_RADIUS = 10;\n  \n  private double m_minutes = 0;\n}\n\n\npublic class ClockTextFields\n{\n  public static void main(String&#x5B;] args)\n  {\n    ClockTextFieldsFrame frame = \n                new ClockTextFieldsFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"219\" height=\"275\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ClockTextFields.gif\" alt=\"\" class=\"wp-image-924\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:34px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">If you change the contents of the text fields (Hours and Minutes), the clock hands move to indicate that time.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Input_Validation\"><\/span>Input Validation<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Sometimes, we&#8217;d like to constrain what&#8217;s allowed to be input into a text field.&nbsp; In the above clock example, we&#8217;d like to enforce the fact that we expect only integers to be input into the two fields.&nbsp; To do this, we do the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Create a subclass of&nbsp;<code><strong>JTextField<\/strong><\/code>, called&nbsp;<code><strong>IntTextField<\/strong><\/code>, that adds a few useful methods, and uses&nbsp;<code><strong>IntTextDocument<\/strong><\/code>&nbsp;as its model.<\/li><li>Create a subclass of&nbsp;<code><strong>PlainDocument<\/strong><\/code>, called&nbsp;<code><strong>IntTextDocument<\/strong><\/code>.&nbsp; This will enforce the integer requirement.<\/li><li>Use&nbsp;<code><strong>IntTextField<\/strong><\/code>&nbsp;in place of&nbsp;<code><strong>JTextField<\/strong><\/code>&nbsp;for the hours and minutes text fields<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">For example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [63,64,65,66,67,68,69,70,71,72,73,87,88,89,90,91,92,199,200,201,202,203,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport java.awt.geom.Ellipse2D;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Point2D;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JTextField;\n\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\n\nimport javax.swing.text.AttributeSet;\nimport javax.swing.text.BadLocationException;\nimport javax.swing.text.Document;\nimport javax.swing.text.PlainDocument;\n\nclass ValidatedClockFrame extends JFrame\n{\n  public ValidatedClockFrame()\n  {\n    setTitle(&quot;ValidatedClock&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    \n    \/\/ Create main panel and add it to the content pane\n    JPanel mainPanel = new JPanel(new BorderLayout());\n    Container contentPane = getContentPane();\n    contentPane.add(mainPanel);\n    \n    \/\/ Add the clock panel to the center of the main panel\n    mainPanel.add(m_clockPanel, BorderLayout.CENTER);\n    \n    \/\/ Prepare a document listener\n    DocumentListener listener = new ClockFieldListener();\n    \n    \/\/ Create the input panel containing text input fields,\n    \/\/ and connect the text input fields up with the listener\n    JPanel inputPanel = new JPanel();\n    inputPanel.add(new JLabel(&quot;Hours:&quot;));\n    inputPanel.add(m_hourField);\n    m_hourField.getDocument().addDocumentListener(listener);\n    \n    inputPanel.add(new JLabel(&quot;Minutes:&quot;));\n    inputPanel.add(m_minuteField);\n    m_minuteField.getDocument().addDocumentListener(listener);\n    \n    \/\/ Add the Tick button and hook it up\n    JButton tickButton = new JButton(&quot;Tick&quot;);\n    tickButton.addActionListener(new ActionListener()\n    {\n      public void actionPerformed(ActionEvent ev)\n      {\n        m_clockPanel.tick();\n      }\n    }\n    );\n    inputPanel.add(tickButton);\n    \n    \/\/ Add the input panel to the south of the main panel\n    mainPanel.add(inputPanel, BorderLayout.SOUTH);\n    \n    \/\/ Set the clock&#039;s initial state\n    setClock();\n    \n    \/\/ Self-size the frame.\n    pack();\n  }\n  \n  private void setClock()\n  {\n    if (m_hourField.isValid() &amp;&amp; m_minuteField.isValid())\n    {\n      int hours = m_hourField.getValue();\n      int minutes = m_minuteField.getValue();\n      m_clockPanel.setTime(hours, minutes);\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private ClockPanel m_clockPanel = new ClockPanel();\n  private IntTextField m_hourField = new IntTextField(12, 3);\n  private IntTextField m_minuteField = new IntTextField(00, 3);\n  \n  \/\/\/ Inner class \/\/\/\n  private class ClockFieldListener implements DocumentListener\n  {\n    public void insertUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void removeUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void changedUpdate(DocumentEvent event)\n    {}\n  }\n}\n\nclass ClockPanel extends JPanel\n{\n  public ClockPanel()\n  {\n    \/\/ Set the preferred size of the panel \n    \/\/ for layout purposes (pack)\n    setPreferredSize(\n        new Dimension(2 * RADIUS + 1 + 10, \/\/ Insets\n                      2 * RADIUS + 1 + 10) \/\/ Insets\n        );\n  }\n  \n  public void paintComponent(Graphics g)\n  {\n    super.paintComponent(g);\n    \n    Graphics2D g2 = (Graphics2D) g;\n    \n    \/\/ Create a BasicStroke for drawing outlines\n    BasicStroke stroke = \n        new BasicStroke(3.0F,\n                        BasicStroke.CAP_ROUND,\n                        BasicStroke.JOIN_ROUND);\n    g2.setStroke(stroke);\n    \n    \/\/ Draw the outline of the clock\n    Ellipse2D circle = \n        new Ellipse2D.Double(INSET, INSET, \n                             2 * RADIUS,\n                             2 * RADIUS);\n    g2.setPaint(Color.GRAY);\n    g2.draw(circle);\n    \n    stroke = new BasicStroke(8.0F,\n                             BasicStroke.CAP_ROUND,\n                             BasicStroke.JOIN_ROUND);\n    g2.setStroke(stroke);\n    \n    \/\/ Draw the hour hand\n    double hourDegrees = \n        90 - 360 * m_minutes \/ (12 * 60);\n    double hourAngle = Math.toRadians(hourDegrees);\n    g2.setPaint(Color.BLUE);\n    drawHand(g2, hourAngle, HOUR_HAND_LENGTH);\n    \n    \/\/ Draw the minute hand\n    double minuteDegrees = \n        90 - 360 * m_minutes \/ 60;\n    double minuteAngle = Math.toRadians(minuteDegrees);\n    g2.setPaint(Color.BLUE);\n    drawHand(g2, minuteAngle, MINUTE_HAND_LENGTH);\n    \n    \/\/ Draw the axle\n    Ellipse2D axle = \n        new Ellipse2D.Double(INSET + RADIUS - AXLE_RADIUS,\n                             INSET + RADIUS - AXLE_RADIUS,\n                             2 * AXLE_RADIUS,\n                             2 * AXLE_RADIUS);\n    g2.setPaint(Color.RED);\n    g2.fill(axle);\n  }\n  \n  private void drawHand(Graphics2D g2, \n                        double angle, double handLength)\n  {\n    Point2D end = \n        new Point2D.Double(INSET + RADIUS +\n                              handLength * Math.cos(angle),\n                           INSET + RADIUS -\n                              handLength * Math.sin(angle));\n    Point2D center = \n        new Point2D.Double(INSET + RADIUS, INSET + RADIUS);\n    g2.draw(new Line2D.Double(center, end));\n  }\n  \n  public void setTime(int hours, int minutes)\n  {\n    m_minutes = hours * 60 + minutes;\n    repaint();\n  }\n  \n  public void tick()\n  {\n    m_minutes++;\n    repaint();\n  }\n  \n  \/\/\/\/\/\/ Private data \/\/\/\/\/\/\n  private static final int INSET = 5;\n  private static final int RADIUS = 100;\n  private static final double HOUR_HAND_LENGTH = \n                                0.6 * RADIUS;\n  private static final double MINUTE_HAND_LENGTH = \n                                0.9 * RADIUS;\n  private static final double AXLE_RADIUS = 10;\n  \n  private double m_minutes = 0;\n}\n\nclass IntTextField extends JTextField\n{\n  public IntTextField(int defaultValue, int columns)\n  {\n    super(&quot;&quot; + defaultValue, columns);\n  }\n  \n  public boolean isValid()\n  {\n    boolean ret = false;\n    try\n    {\n      Integer.parseInt(getText());\n      ret = true;\n    }\n    catch (NumberFormatException ex)\n    {\n      \/\/ Do nothing\n    }\n    return ret;\n  }\n  \n  public int getValue()\n  {\n    int value = 0;\n    try\n    {\n      value = Integer.parseInt(getText());\n    }\n    catch (NumberFormatException ex)\n    {\n    }\n    return value;\n  }\n  \n  protected Document createDefaultModel()\n  {\n    return new IntTextDocument();\n  }\n}\n\nclass IntTextDocument extends PlainDocument\n{\n  public void insertString(int offset, String text,\n      AttributeSet attr) throws BadLocationException\n  {\n    if (text != null)\n    {\n      String oldString = getText(0, getLength());\n      String newString = oldString.substring(0, offset)\n      + text + oldString.substring(offset);\n      try\n      {\n        Integer.parseInt(newString + &quot;0&quot;); \n                    \/\/ For the case of &quot;&quot; or &quot;-&quot;, etc.\n        super.insertString(offset, text, attr);\n      }\n      catch (NumberFormatException ex)\n      {\n      }\n    }\n  }\n}\n\npublic class ValidatedClock\n{\n  public static void main(String&#x5B;] args)\n  {\n    ValidatedClockFrame frame = new ValidatedClockFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"255\" height=\"281\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ValidatedClock.gif\" alt=\"\" class=\"wp-image-931\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:21px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Note that I&#8217;ve added a button which, when clicked, causes the clock to &#8220;tick&#8221; by one minute.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When you attempt to enter something that is not a valid integer value in either text field, that input is ignored.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JFormattedTextField\"><\/span>JFormattedTextField<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Until Java 1.4, the previous attempts at producing validated integer input in a text field were pretty much what you had to do.&nbsp; Using Document models, etc., was not for the faint of heart.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Java 1.4, the Java developers produced a new text input component, called&nbsp;<code><strong>JFormattedTextField<\/strong><\/code>, which allows you to do such checking of input &#8212; not only for integers, but for dates and more.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This area of Java is still not easy to deal with, but now at least there is a well-defined (if not particularly well documented!) way of doing it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example, which re-implements the <strong>ValidatedClock<\/strong> example using&nbsp;<code><strong>JFormattedTextField<\/strong><\/code>s:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [21,52,53,58,59,88,89,96,97,98,99]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BasicStroke;\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Dimension;\nimport java.awt.Graphics;\nimport java.awt.Graphics2D;\nimport java.awt.Insets;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport java.awt.geom.Ellipse2D;\nimport java.awt.geom.Line2D;\nimport java.awt.geom.Point2D;\nimport java.text.NumberFormat;\n\nimport javax.swing.JButton;\nimport javax.swing.JFormattedTextField;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.event.DocumentEvent;\nimport javax.swing.event.DocumentListener;\n\nclass FormattedTextClockFrame extends JFrame\n{\n  public FormattedTextClockFrame()\n  {\n    setTitle(&quot;FormattedTextClock&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    \n    \/\/ Create main panel and add it to the content pane\n    JPanel mainPanel = new JPanel(new BorderLayout());\n    Container contentPane = getContentPane();\n    contentPane.add(mainPanel);\n    \n    \/\/ Add the clock panel to the center of the main panel\n    mainPanel.add(m_clockPanel, BorderLayout.CENTER);\n    \n    \/\/ Prepare a document listener\n    DocumentListener listener = new ClockFieldListener();\n    \n    \/\/ Create the input panel containing text input fields,\n    \/\/ and connect the text input fields up with the listener\n    JPanel inputPanel = new JPanel();\n    inputPanel.add(new JLabel(&quot;Hours:&quot;));\n    inputPanel.add(m_hourField);\n    m_hourField.setColumns(3);\n    m_hourField.setValue( new Long(12) );\n    m_hourField.getDocument().addDocumentListener(listener);\n    \n    inputPanel.add(new JLabel(&quot;Minutes:&quot;));\n    inputPanel.add(m_minuteField);\n    m_minuteField.setColumns(3);\n    m_minuteField.setValue( new Long(0) );\n    m_minuteField.getDocument().addDocumentListener(listener);\n    \n    \/\/ Add the Tick button and hook it up\n    JButton tickButton = new JButton(&quot;Tick&quot;);\n    tickButton.addActionListener(new ActionListener()\n    {\n      public void actionPerformed(ActionEvent ev)\n      {\n        m_clockPanel.tick();\n      }\n    }\n    );\n    inputPanel.add(tickButton);\n    \n    \/\/ Add the input panel to the south of the main panel\n    mainPanel.add(inputPanel, BorderLayout.SOUTH);\n    \n    \/\/ Set the clock&#039;s initial state\n    setClock();\n    \n    \/\/ Self-size the frame.\n    pack();\n  }\n  \n  private void setClock()\n  {\n    if (m_hourField.isValid() &amp;&amp; m_minuteField.isValid())\n    {\n      long hours = (Long) m_hourField.getValue();\n      long minutes = (Long) m_minuteField.getValue();\n      m_clockPanel.setTime((int)hours, (int)minutes);\n    }\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private ClockPanel m_clockPanel = new ClockPanel();\n  private JFormattedTextField m_hourField =\n      new JFormattedTextField( NumberFormat.getIntegerInstance() );\n  private JFormattedTextField m_minuteField =\n      new JFormattedTextField( NumberFormat.getIntegerInstance() );\n  \n  \/\/\/ Inner class \/\/\/\n  private class ClockFieldListener implements DocumentListener\n  {\n    public void insertUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void removeUpdate(DocumentEvent event)\n    {\n      setClock();\n    }\n    \n    public void changedUpdate(DocumentEvent event)\n    {}\n  }\n  \n  \/\/\/\/ Inner class \/\/\/\/\n  class ClockPanel extends JPanel\n  {\n    public ClockPanel()\n    {\n      \/\/ Set the preferred size of the panel\n      \/\/ for layout purposes (pack)\n      setPreferredSize(\n          new Dimension(2 * RADIUS + 1 + 10, \/\/ Insets\n          2 * RADIUS + 1 + 10) \/\/ Insets\n          );\n    }\n    \n    public void paintComponent(Graphics g)\n    {\n      super.paintComponent(g);\n      \n      Graphics2D g2 = (Graphics2D) g;\n      \n      \/\/ Create a BasicStroke for drawing outlines\n      BasicStroke stroke =\n          new BasicStroke(3.0F,\n                          BasicStroke.CAP_ROUND,\n                          BasicStroke.JOIN_ROUND);\n      g2.setStroke(stroke);\n      \n      \/\/ Draw the outline of the clock\n      Ellipse2D circle =\n          new Ellipse2D.Double(INSET, INSET,\n                               2 * RADIUS,\n                               2 * RADIUS);\n      g2.setPaint(Color.GRAY);\n      g2.draw(circle);\n      \n      stroke = new BasicStroke(8.0F,\n                               BasicStroke.CAP_ROUND,\n                               BasicStroke.JOIN_ROUND);\n      g2.setStroke(stroke);\n      \n      \/\/ Draw the hour hand\n      double hourDegrees =\n          90 - 360 * m_minutes \/ (12 * 60);\n      double hourAngle = Math.toRadians(hourDegrees);\n      g2.setPaint(Color.BLUE);\n      drawHand(g2, hourAngle, HOUR_HAND_LENGTH);\n      \n      \/\/ Draw the minute hand\n      double minuteDegrees =\n          90 - 360 * m_minutes \/ 60;\n      double minuteAngle = Math.toRadians(minuteDegrees);\n      g2.setPaint(Color.BLUE);\n      drawHand(g2, minuteAngle, MINUTE_HAND_LENGTH);\n      \n      \/\/ Draw the axle\n      Ellipse2D axle =\n          new Ellipse2D.Double(\n                    INSET + RADIUS - AXLE_RADIUS,\n                    INSET + RADIUS - AXLE_RADIUS,\n                    2 * AXLE_RADIUS,\n                    2 * AXLE_RADIUS);\n      g2.setPaint(Color.RED);\n      g2.fill(axle);\n    }\n    \n    private void drawHand(Graphics2D g2,\n                          double angle, double handLength)\n    {\n      Point2D end =\n          new Point2D.Double(\n                    INSET + RADIUS +\n                    handLength * Math.cos(angle),\n                    INSET + RADIUS -\n                    handLength * Math.sin(angle));\n      Point2D center =\n          new Point2D.Double(INSET + RADIUS, INSET + RADIUS);\n      g2.draw(new Line2D.Double(center, end));\n    }\n    \n    public void setTime(int hours, int minutes)\n    {\n      m_minutes = hours * 60 + minutes;\n      repaint();\n    }\n    \n    public void tick()\n    {\n      m_minutes++;\n      repaint();\n    }\n    \n    \/\/\/\/\/\/ Private data \/\/\/\/\/\/\n    private static final int INSET = 5;\n    private static final int RADIUS = 100;\n    private static final double HOUR_HAND_LENGTH =\n        0.6 * RADIUS;\n    private static final double MINUTE_HAND_LENGTH =\n        0.9 * RADIUS;\n    private static final double AXLE_RADIUS = 10;\n    \n    private long m_minutes = 0;\n  }\n}\n\n\npublic class FormattedTextClock\n{\n  public static void main(String&#x5B;] args)\n  {\n    FormattedTextClockFrame frame =\n        new FormattedTextClockFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"255\" height=\"281\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/JForma27.jpg\" alt=\"\" class=\"wp-image-938\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:37px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Scrolling_and_Wrapping_Text_in_a_JTextArea\"><\/span>Scrolling and Wrapping Text in a JTextArea<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You may have noticed that the text areas shown earlier do not have much of a visible border.&nbsp; In addition, if you add more lines of text to a text area, it increases its vertical size, which is not usually a desirable feature.&nbsp;&nbsp; In most cases, you&#8217;d like to have the text area scroll appropriately, without changing size.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To do this, you place the text area in a&nbsp;<code><strong>JScrollPane<\/strong><\/code>, and then add the scroll pane to the panel:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [12,39,40,41,42,43,44]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextArea;\n\nclass ScrollingTextAreasPanel extends JPanel\n{\n  public ScrollingTextAreasPanel()\n  {\n    setLayout(new BorderLayout());\n    add(new TextAreaPanel(), BorderLayout.CENTER);\n    add(new InputPanel(), BorderLayout.SOUTH);\n  }\n  \n  \/\/\/\/\/\/\/ Private data \/\/\/\/\/\n  private JTextArea m_textArea = new JTextArea(8, 40);\n  private JButton m_insertButton = new JButton(&quot;Insert&quot;);\n  private JButton m_wrapButton = new JButton(&quot;Wrap&quot;);\n  private JButton m_noWrapButton = new JButton(&quot;No Wrap&quot;);\n  private JButton m_replaceButton = new JButton(&quot;Replace&quot;);\n  \n  \/\/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class TextAreaPanel extends JPanel\n  {\n    public TextAreaPanel()\n    {\n      setLayout(new BorderLayout());\n      \/\/ Place text area within a scroll pane\n      m_textArea = new JTextArea(8, 40);\n      JScrollPane scrollPane = new JScrollPane(m_textArea);\n      scrollPane.setVerticalScrollBarPolicy(\n          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);\n      scrollPane.setHorizontalScrollBarPolicy(\n          JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n      add(scrollPane, BorderLayout.CENTER);\n    }\n  }\n  \n  class InputPanel extends JPanel\n  {\n    public InputPanel()\n    {\n      add(m_insertButton);\n      m_insertButton.addActionListener(new ActionListener()\n      {\n        public void actionPerformed(ActionEvent ev)\n        {\n          m_textArea.append(\n              &quot;The quick brown fox jumps over the lazy dog. &quot;);\n        }\n      }\n      );\n      add(m_wrapButton);\n      m_wrapButton.addActionListener(new ActionListener()\n      {\n        public void actionPerformed(ActionEvent ev)\n        {\n          m_textArea.setLineWrap(true);\n        }\n      }\n      );\n      add(m_noWrapButton);\n      m_noWrapButton.addActionListener(new ActionListener()\n      {\n        public void actionPerformed(ActionEvent ev)\n        {\n          m_textArea.setLineWrap(false);\n        }\n      }\n      );\n    }\n  }\n}\n\nclass ScrollingTextAreasFrame extends JFrame\n{\n  public ScrollingTextAreasFrame()\n  {\n    setTitle(&quot;ScrollingTextAreas&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new ScrollingTextAreasPanel() );\n  }\n}\n\npublic class ScrollingTextAreas\n{\n  public static void main(String&#x5B;] args)\n  {\n    ScrollingTextAreasFrame frame = \n                        new ScrollingTextAreasFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ScrollingTextAreasNoWrap.gif\" alt=\"\" class=\"wp-image-944\"\/><\/figure><\/div>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ScrollingTextAreasWrap.gif\" alt=\"\" class=\"wp-image-945\"\/><\/figure>\n\n\n\n<div style=\"height:31px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"JTextArea_Editing\"><\/span>JTextArea Editing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We can also explore editing text in a text area.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example, which is slightly modified from the earlier scrolling text area examples:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [28,29,30,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.JTextField;\nimport javax.swing.JTextArea;\n\nclass EditingTextAreasPanel extends JPanel\n{\n  public EditingTextAreasPanel()\n  {\n    setLayout(new BorderLayout());\n    add( new TextAreaPanel(), BorderLayout.CENTER);\n    add( new InputPanel(), BorderLayout.SOUTH);\n  }\n  \n  \/\/\/\/\/\/\/ Private data \/\/\/\/\/\n  private JTextArea m_textArea = new JTextArea(8, 40);\n  private JButton m_replaceButton = new JButton(&quot;Replace&quot;);\n  private JTextField m_fromField = new JTextField(5);\n  private JTextField m_toField = new JTextField(5);\n  \n  \/\/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class TextAreaPanel extends JPanel\n  {\n    public TextAreaPanel()\n    {\n      setLayout(new BorderLayout());\n      m_textArea = new JTextArea(8, 40);\n      m_textArea.setText(\n          &quot;The quick brown fox jumps over the lazy dog.&quot;);\n      JScrollPane scrollPane = new JScrollPane(m_textArea);\n      scrollPane.setVerticalScrollBarPolicy(\n          JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);\n      scrollPane.setHorizontalScrollBarPolicy(\n          JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);\n      add(scrollPane, BorderLayout.CENTER);\n    }\n  }\n  \n  class InputPanel extends JPanel\n  {\n    public InputPanel()\n    {\n      \n      add(m_replaceButton);\n      m_replaceButton.addActionListener(\n        new ActionListener()\n        {\n          public void actionPerformed(ActionEvent ev)\n          {\n            String from = m_fromField.getText();\n            int index = \n                m_textArea.getText().indexOf(from);\n            if (index &gt;= 0 &amp;&amp; from.length() &gt; 0)\n            {\n              m_textArea.replaceRange(\n                  m_toField.getText(), index,\n                  index + from.length());\n            }\n          }\n        }\n      );\n      add(m_fromField);\n      add(new JLabel(&quot;with&quot;));\n      add(m_toField);\n    }\n  }\n}\n\nclass EditingTextAreasFrame extends JFrame\n{\n  public EditingTextAreasFrame()\n  {\n    setTitle(&quot;EditingTextAreas&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new EditingTextAreasPanel() );\n  }\n}\n\npublic class EditingTextAreas\n{\n  public static void main(String&#x5B;] args)\n  {\n    EditingTextAreasFrame frame = \n                new EditingTextAreasFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/EditingTextAreas.gif\" alt=\"\" class=\"wp-image-952\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:31px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>There is a (small) family of components whose purpose in life is to display text, and also to accept changes to that text.&nbsp;&nbsp; The two most commonly used members of the family are: JTextField and JTextArea both of which extend the abstract class&nbsp;JTextComponent. There are also some other text input components that we&#8217;ll cover, and [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":71,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_eb_attr":"","_uag_custom_page_level_css":"","ocean_post_layout":"left-sidebar","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"ocs-course-topics-sidebar","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","footnotes":""},"class_list":["post-909","page","type-page","status-publish","hentry","entry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"ocean-thumb-m":false,"ocean-thumb-ml":false,"ocean-thumb-l":false},"uagb_author_info":{"display_name":"Bryan Higgs","author_link":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/author\/bryan\/"},"uagb_comment_info":0,"uagb_excerpt":"There is a (small) family of components whose purpose in life is to display text, and also to accept changes to that text.&nbsp;&nbsp; The two most commonly used members of the family are: JTextField and JTextArea both of which extend the abstract class&nbsp;JTextComponent. There are also some other text input components that we&#8217;ll cover, and&hellip;","_links":{"self":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/909","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/comments?post=909"}],"version-history":[{"count":27,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/909\/revisions"}],"predecessor-version":[{"id":954,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/909\/revisions\/954"}],"up":[{"embeddable":true,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/71"}],"wp:attachment":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/media?parent=909"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}