{"id":1007,"date":"2021-01-12T21:32:27","date_gmt":"2021-01-12T21:32:27","guid":{"rendered":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/?page_id=1007"},"modified":"2021-01-12T22:37:41","modified_gmt":"2021-01-12T22:37:41","slug":"lists-combo-boxes","status":"publish","type":"page","link":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/","title":{"rendered":"Lists &#038; Combo Boxes"},"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-6a21c3d92d14e\" 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-6a21c3d92d14e\"  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\/lists-combo-boxes\/#List_Boxes\" >List Boxes<\/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\/lists-combo-boxes\/#Scrolling_Lists\" >Scrolling Lists<\/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\/lists-combo-boxes\/#Combo_Boxes\" >Combo Boxes<\/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\/lists-combo-boxes\/#List_Models\" >List Models<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/#Interface_ListModel\" >Interface ListModel<\/a><\/li><li class='ez-toc-page-1 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\/lists-combo-boxes\/#Class_AbstractListModel\" >Class AbstractListModel<\/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\/lists-combo-boxes\/#Class_DefaultListModel\" >Class DefaultListModel<\/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\/lists-combo-boxes\/#List_Selections\" >List Selections<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/#Example_of_List_Model_and_List_Selection\" >Example of List Model and List Selection<\/a><\/li><\/ul><\/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\/lists-combo-boxes\/#List_Renderers\" >List Renderers<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/#A_Color-Rendered_List\" >A Color-Rendered List<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/#A_Font_List\" >A Font List<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/lists-combo-boxes\/#A_Font-Rendered_List\" >A Font-Rendered List<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n<p class=\"wp-block-paragraph\">When you wish to provide the user with a set of choices that is larger than, say, three or four choices, it is often better to avoid check boxes or radio buttons, because they take up too much space.&nbsp; A better solution is a <em>list box<\/em>, or a <em>combo box<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"List_Boxes\"><\/span>List Boxes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how to use a list box (i.e., a&nbsp;<code><strong>JList<\/strong><\/code>):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [9,12,14,15,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]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Font;\n\nimport javax.swing.JFrame;\nimport javax.swing.JList;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.ListSelectionModel;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\nclass ListsPanel extends JPanel\n{\n  public ListsPanel()\n  {\n    setLayout(new BorderLayout());\n    add(new TextPanel(), BorderLayout.NORTH);\n    add(new InputPanel(), BorderLayout.CENTER);\n  }\n  \n  void setTextFont()\n  {\n    m_text.setFont(new Font(m_name, m_style, m_size));\n  }\n  \n  \/\/\/\/\/\/\/ Private data \/\/\/\/\/\n  private String m_name = &quot;SanSerif&quot;; \/\/ Current font name\n  private int m_style = Font.PLAIN; \/\/ Current font style\n  private int m_size = 14; \/\/ Current font point size\n  \n  private JLabel m_text = \n      new JLabel(\n      &quot;The quick brown fox jumps over the lazy dog&quot;);\n  \n  \/\/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class TextPanel extends JPanel\n  {\n    public TextPanel()\n    {\n      setBackground(Color.white);\n      add(m_text);\n      setTextFont();\n    }\n  }\n  \n  class InputPanel extends JPanel \n      implements ListSelectionListener\n  {\n    public InputPanel()\n    {\n      m_fontNameList = new JList(m_fontNames);\n      m_fontNameList.setSelectionMode(\n          ListSelectionModel.SINGLE_SELECTION);\n      m_fontNameList.addListSelectionListener(this);\n      add(m_fontNameList);\n      m_fontStyleList = new JList(m_fontStyles);\n      m_fontStyleList.setSelectionMode(\n          ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n      m_fontStyleList.addListSelectionListener(this);\n      add(m_fontStyleList);\n      m_fontSizeList = new JList(m_fontSizes);\n      m_fontSizeList.setSelectionMode(\n          ListSelectionModel.SINGLE_SELECTION);\n      m_fontSizeList.addListSelectionListener(this);\n      add(m_fontSizeList);\n    }\n    \n    public void valueChanged(ListSelectionEvent ev)\n    {\n      JList source = (JList) ev.getSource();\n      if (source == m_fontNameList)\n      {\n        setFontName();\n      }\n      else if (source == m_fontStyleList)\n      {\n        setFontStyle();\n      }\n      else if (source == m_fontSizeList)\n      {\n        setFontSize();\n      }\n      setTextFont();\n    }\n    \n    private void setFontName()\n    {\n      String name = \n          (String) m_fontNameList.getSelectedValue();\n      m_name = name;\n    }\n    \n    private void setFontStyle()\n    {\n      Object&#x5B;] styles = \n          m_fontStyleList.getSelectedValues();\n      int stylesSet = 0;\n      for (int i = 0; i &lt; styles.length; i++)\n      {\n        String style = (String) styles&#x5B;i];\n        if (style.equals(&quot;Plain&quot;))\n        {\n          stylesSet |= Font.PLAIN;\n        }\n        else if (style.equals(&quot;Bold&quot;))\n        {\n          stylesSet |= Font.BOLD;\n        }\n        else if (style.equals(&quot;Italic&quot;))\n        {\n          stylesSet |= Font.ITALIC;\n        }\n      }\n      m_style = stylesSet;\n    }\n    \n    private void setFontSize()\n    {\n      String size = \n          (String) m_fontSizeList.getSelectedValue();\n      m_size = Integer.parseInt(size);\n    }\n    \n    \/\/\/\/\/ Private data \/\/\/\/\/\n    private JList m_fontNameList;  \/\/ Font names\n    private JList m_fontStyleList; \/\/ Font styles\n    private JList m_fontSizeList;  \/\/ Font sizes\n  }\n  \n  private static final String&#x5B;] m_fontNames =\n  {\n    &quot;Serif&quot;, &quot;SanSerif&quot;, &quot;Monospaced&quot;, \n    &quot;Dialog&quot;, &quot;DialogInput&quot;\n  };\n  private static final String&#x5B;] m_fontStyles =\n  {\n    &quot;Plain&quot;, &quot;Bold&quot;, &quot;Italic&quot;\n  };\n  private static final String&#x5B;] m_fontSizes =\n  {\n    &quot;6&quot;, &quot;8&quot;, &quot;10&quot;, &quot;12&quot;, &quot;14&quot;, \n    &quot;16&quot;, &quot;18&quot;, &quot;20&quot;, &quot;22&quot;, &quot;24&quot;\n  };\n}\n\nclass ListsFrame extends JFrame\n{\n  public ListsFrame()\n  {\n    setTitle(&quot;Lists&quot;);\n    setSize(400, 300);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new ListsPanel() );\n  }\n}\n\npublic class Lists\n{\n  public static void main(String&#x5B;] args)\n  {\n    ListsFrame frame = new ListsFrame();\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=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Lists1.gif\" alt=\"\" class=\"wp-image-1011\"\/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img decoding=\"async\" width=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Lists2.gif\" alt=\"\" class=\"wp-image-1012\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:27px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Note that the font styles list box (the one with &#8220;Plain&#8221;, &#8220;Bold&#8221; and &#8220;Italic&#8221;) allows multiple selections, while the other two list boxes only allow single selection.<\/p><\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Scrolling_Lists\"><\/span>Scrolling Lists<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, the list boxes don&#8217;t look all that great, because, by default, they will not scroll.&nbsp; They also don&#8217;t have any border.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can provide both scrolling capabilities and a border, by using a&nbsp;<code><strong>JScrollPane<\/strong><\/code>&nbsp;to enclose each list box:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [12,24,60,62,66,68,72,74]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Font;\n\nimport javax.swing.JFrame;\nimport javax.swing.JList;\nimport javax.swing.JLabel;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\nimport javax.swing.ListSelectionModel;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\nclass ScrollingListsPanel extends JPanel\n{\n  public ScrollingListsPanel()\n  {\n    setLayout(new BorderLayout());\n    add(new TextPanel(), BorderLayout.NORTH);\n    add(new InputPanel(), BorderLayout.SOUTH);\n  }\n  \n  void setTextFont()\n  {\n    m_text.setFont(new Font(m_name, m_style, m_size));\n  }\n  \n  \/\/\/\/\/\/\/ Private data \/\/\/\/\/\n  private String m_name = &quot;SanSerif&quot;; \/\/ Current font name\n  private int m_style = Font.PLAIN; \/\/ Current font style\n  private int m_size = 14; \/\/ Current font point size\n  \n  private JLabel m_text = \n      new JLabel(\n      &quot;The quick brown fox jumps over the lazy dog&quot;);\n  \n  \/\/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class TextPanel extends JPanel\n  {\n    public TextPanel()\n    {\n      setBackground(Color.white);\n      add(m_text);\n      setTextFont();\n    }\n  }\n  \n  class InputPanel extends JPanel \n      implements ListSelectionListener\n  {\n    public InputPanel()\n    {\n      m_fontNameList = new JList(m_fontNames);\n      m_fontNameList.setSelectionMode(\n          ListSelectionModel.SINGLE_SELECTION);\n      m_fontNameList.setVisibleRowCount(3);\n      m_fontNameList.addListSelectionListener(this);\n      add(new JScrollPane(m_fontNameList));\n      m_fontStyleList = new JList(m_fontStyles);\n      m_fontStyleList.setSelectionMode(\n          ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n      m_fontStyleList.setVisibleRowCount(3);\n      m_fontStyleList.addListSelectionListener(this);\n      add(new JScrollPane(m_fontStyleList));\n      m_fontSizeList = new JList(m_fontSizes);\n      m_fontSizeList.setSelectionMode(\n          ListSelectionModel.SINGLE_SELECTION);\n      m_fontSizeList.setVisibleRowCount(3);\n      m_fontSizeList.addListSelectionListener(this);\n      add(new JScrollPane(m_fontSizeList));\n    }\n    \n    public void valueChanged(ListSelectionEvent ev)\n    {\n      JList source = (JList) ev.getSource();\n      if (source == m_fontNameList)\n      {\n        setFontName();\n      }\n      else if (source == m_fontStyleList)\n      {\n        setFontStyle();\n      }\n      else if (source == m_fontSizeList)\n      {\n        setFontSize();\n      }\n      setTextFont();\n    }\n    \n    private void setFontName()\n    {\n      String name = \n          (String) m_fontNameList.getSelectedValue();\n      m_name = name;\n    }\n    \n    private void setFontStyle()\n    {\n      Object&#x5B;] styles = \n          m_fontStyleList.getSelectedValues();\n      int stylesSet = 0;\n      for (int i = 0; i &lt; styles.length; i++)\n      {\n        String style = (String) styles&#x5B;i];\n        if (style.equals(&quot;Plain&quot;))\n        {\n          stylesSet |= Font.PLAIN;\n        }\n        else if (style.equals(&quot;Bold&quot;))\n        {\n          stylesSet |= Font.BOLD;\n        }\n        else if (style.equals(&quot;Italic&quot;))\n        {\n          stylesSet |= Font.ITALIC;\n        }\n      }\n      m_style = stylesSet;\n    }\n    \n    private void setFontSize()\n    {\n      String size = \n          (String) m_fontSizeList.getSelectedValue();\n      m_size = Integer.parseInt(size);\n    }\n    \n    \/\/\/\/\/ Private data \/\/\/\/\/\n    private JList m_fontNameList; \/\/ Font names\n    private JList m_fontStyleList; \/\/ Font styles\n    private JList m_fontSizeList; \/\/ Font sizes\n  }\n  \n  private static final String&#x5B;] m_fontNames =\n  {\n    &quot;Serif&quot;, &quot;SanSerif&quot;, &quot;Monospaced&quot;, \n    &quot;Dialog&quot;, &quot;DialogInput&quot;\n  };\n  private static final String&#x5B;] m_fontStyles =\n  {\n    &quot;Plain&quot;, &quot;Bold&quot;, &quot;Italic&quot;\n  };\n  private static final String&#x5B;] m_fontSizes =\n  {\n    &quot;6&quot;, &quot;8&quot;, &quot;10&quot;, &quot;12&quot;, &quot;14&quot;, \n    &quot;16&quot;, &quot;18&quot;, &quot;20&quot;, &quot;22&quot;, &quot;24&quot;\n  };\n}\n\nclass ScrollingListsFrame extends JFrame\n{\n  public ScrollingListsFrame()\n  {\n    setTitle(&quot;ScrollingLists&quot;);\n    setSize(400, 300);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new ScrollingListsPanel() );\n  }\n}\n\npublic class ScrollingLists\n{\n  public static void main(String&#x5B;] args)\n  {\n    ScrollingListsFrame frame = new ScrollingListsFrame();\n    frame.setVisible(true);\n  }\n}\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">By doing three things:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Adding scroll panes for each of the list boxes<\/li><li>Restricting the number of visible rows for each list box<\/li><li>Moving the list boxes from the&nbsp;<code><strong>BorderLayout<\/strong>'<\/code>s <strong>CENTER<\/strong> to its <strong>SOUTH<\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">we make things look a little more reasonable:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img decoding=\"async\" width=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ScrollingLists.gif\" alt=\"\" class=\"wp-image-1017\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:39px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Combo_Boxes\"><\/span>Combo Boxes<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Combo boxes (<code><strong>JComboBox<\/strong><\/code>) are similar to list boxes (<code><strong>JList<\/strong><\/code>), except:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Combo boxes take up less vertical space<\/li><li>Combo boxes can be editable &#8212; that is, they can present a set of choices, and in addition allow the user to enter a choice not listed.<\/li><li>List boxes support multiple selections, and delegate selection responsibilities to an object that implements the interface&nbsp;<code><strong>ListSelectionModel<\/strong><\/code>, while combo boxes&nbsp;<em>only support single selection<\/em>, and&nbsp;<em>selection is handled by the combo box models<\/em>.<\/li><li>Combo boxes support key selection, while list boxes do not.<\/li><li>List boxes do not provide any methods for directly adding, inserting, or removing items directly to\/from a list box.&nbsp; You must modify the list model to accomplish these actions.<\/li><li>Items can be directly added to and removed from a combo box.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what happens if we take the first List Box example above, and replace two of its&nbsp;<code><strong>JList<\/strong><\/code>s with&nbsp;<code><strong>JComboBox<\/strong><\/code>es:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [8,9,11,57,61,62,69,70,71,75,76,77,78,79,80,81,82,83,84,85,86,87,132,133,134,135,136,137,138,139,140,141,142,146,148]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Font;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swing.JComboBox;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.ListSelectionModel;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\nclass ComboBoxesPanel extends JPanel\n{\n  public ComboBoxesPanel()\n  {\n    setLayout(new BorderLayout());\n    add(new TextPanel(), BorderLayout.NORTH);\n    add(new InputPanel(), BorderLayout.CENTER);\n  }\n  \n  void setTextFont()\n  {\n    m_text.setFont(new Font(m_name, m_style, m_size));\n    \/\/ Note: No repaint() necessary here, in this case.\n  }\n  \n  \/\/\/\/\/\/\/ Private data \/\/\/\/\/\n  private String m_name = &quot;SanSerif&quot;; \/\/ Current font name\n  private int m_style = Font.PLAIN; \/\/ Current font style\n  private int m_size = 14; \/\/ Current font point size\n  \n  private JLabel m_text = \n      new JLabel(\n      &quot;The quick brown fox jumps over the lazy dog&quot;);\n  \n  \/\/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class TextPanel extends JPanel\n  {\n    public TextPanel()\n    {\n      setBackground(Color.white);\n      add(m_text);\n      setTextFont();\n    }\n  }\n  \n  class InputPanel extends JPanel \n      implements ActionListener, ListSelectionListener\n  {\n    public InputPanel()\n    {\n      m_fontNameList = new JComboBox(m_fontNames);\n      m_fontNameList.addActionListener(this);\n      add(m_fontNameList);\n      m_fontStyleList = new JList(m_fontStyles);\n      m_fontStyleList.setSelectionMode(\n          ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\n      m_fontStyleList.addListSelectionListener(this);\n      add(m_fontStyleList);\n      m_fontSizeList = new JComboBox(m_fontSizes);\n      m_fontSizeList.setEditable(true);\n      m_fontSizeList.addActionListener(this);\n      add(m_fontSizeList);\n    }\n    \n    public void actionPerformed(ActionEvent ev)\n    {\n      JComboBox source = (JComboBox) ev.getSource();\n      if (source == m_fontNameList)\n      {\n        setFontName();\n      }\n      else if (source == m_fontSizeList)\n      {\n        setFontSize();\n      }\n      setTextFont();\n    }\n    \n    public void valueChanged(ListSelectionEvent ev)\n    {\n      JList source = (JList) ev.getSource();\n      if (source == m_fontStyleList)\n      {\n        setFontStyle();\n      }\n      setTextFont();\n    }\n    \n    private void setFontName()\n    {\n      String name = \n          (String) m_fontNameList.getSelectedItem();\n      m_name = name;\n    }\n    \n    private void setFontStyle()\n    {\n      Object&#x5B;] styles = \n          m_fontStyleList.getSelectedValues();\n      int stylesSet = 0;\n      for (int i = 0; i &lt; styles.length; i++)\n      {\n        String style = (String) styles&#x5B;i];\n        if (style.equals(&quot;Plain&quot;))\n        {\n          stylesSet |= Font.PLAIN;\n        }\n        else if (style.equals(&quot;Bold&quot;))\n        {\n          stylesSet |= Font.BOLD;\n        }\n        else if (style.equals(&quot;Italic&quot;))\n        {\n          stylesSet |= Font.ITALIC;\n        }\n      }\n      m_style = stylesSet;\n    }\n    \n    private void setFontSize()\n    {\n      String size = \n          (String) m_fontSizeList.getSelectedItem();\n      try\n      {\n        m_size = Integer.parseInt(size);\n      }\n      catch (NumberFormatException ex)\n      {\n        \/\/ Since the combo box is editable, we need to catch\n        \/\/ any invalid numbers, and then do nothing\n      }\n    }\n    \n    \/\/\/\/\/ Private data \/\/\/\/\/\n    private JComboBox m_fontNameList; \/\/ Font names\n    private JList m_fontStyleList;    \/\/ Font styles\n    private JComboBox m_fontSizeList; \/\/ Font sizes\n  }\n  \n  private static final String&#x5B;] m_fontNames =\n  {\n    &quot;Serif&quot;, &quot;SanSerif&quot;, &quot;Monospaced&quot;, \n    &quot;Dialog&quot;, &quot;DialogInput&quot;\n  };\n  private static final String&#x5B;] m_fontStyles =\n  {\n    &quot;Plain&quot;, &quot;Bold&quot;, &quot;Italic&quot;\n  };\n  private static final String&#x5B;] m_fontSizes =\n  {\n    &quot;6&quot;, &quot;8&quot;, &quot;10&quot;, &quot;12&quot;, &quot;14&quot;, \n    &quot;16&quot;, &quot;18&quot;, &quot;20&quot;, &quot;22&quot;, &quot;24&quot;\n  };\n}\n\nclass ComboBoxesFrame extends JFrame\n{\n  public ComboBoxesFrame()\n  {\n    setTitle(&quot;ComboBoxes&quot;);\n    setSize(400, 300);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new ComboBoxesPanel() );\n  }\n}\n\npublic class ComboBoxes\n{\n  public static void main(String&#x5B;] args)\n  {\n    ComboBoxesFrame frame = new ComboBoxesFrame();\n    frame.setVisible(true);\n  }\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=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ComboBoxes.gif\" alt=\"\" class=\"wp-image-1023\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:22px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Note the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>We can&#8217;t replace the style list box with a combo box, because we need multiple selection support.<\/li><li>The combo box for the font name&nbsp;<em>is not editable<\/em>;&nbsp; we only support the set of names listed.<\/li><li>The combo box for the font size&nbsp;<em><strong>is<\/strong>&nbsp;editable<\/em>, because the user may wish to choose a size other than the ones supplied.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"List_Models\"><\/span>List Models<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">One problem with simple&nbsp;<code><strong>JList<\/strong><\/code>s is that, surprisingly, they have no support for dynamically adding or removing items from the list.&nbsp; If you want to provide this kind of functionality, you must use a <code><strong>ListModel<\/strong><\/code>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Interface_ListModel\"><\/span>Interface ListModel<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;class is implemented using a <em>Model-View-Controller <\/em>architecture.&nbsp;&nbsp; The model for a <code><strong>JList<\/strong><\/code> stores the data for the display, and must implement the&nbsp;<code><strong>javax.swing.ListModel<\/strong><\/code>&nbsp;interface, which consists of the following methods:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><th>Method<\/th><th>Description<\/th><\/tr><tr><td><strong><code>public void addListDataListener( ListDataListener&nbsp;l)<\/code><\/strong><\/td><td>Adds a listener to the list that&#8217;s notified each time a change to the data model occurs.<\/td><\/tr><tr><td><strong><code>public Object getElementAt(int&nbsp;index)<\/code><\/strong><\/td><td>Returns the value at the specified index.&nbsp;<\/td><\/tr><tr><td><strong><code>public int getSize()<\/code><\/strong><\/td><td>Returns the length of the list.<\/td><\/tr><tr><td><strong><code>public void removeListDataListener( ListDataListener&nbsp;l)<\/code><\/strong><\/td><td>Removes a listener from the list that&#8217;s notified each time a change to the data model occurs.&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<code>ListDataListener<\/code>&nbsp;interface must be implemented by any class that wishes to receive indications of changes to the data in the&nbsp;<code>ListModel<\/code>.&nbsp; The other two methods clearly allow one to determine the number of items in the list, and to obtain the element at a particular index in the list.&nbsp; Notice that there is still no way to add or remove items using a pure list model.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Class_AbstractListModel\"><\/span>Class AbstractListModel<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The abstract class&nbsp;<code><strong>AbstractListModel<\/strong><\/code>&nbsp;implements the <code><strong>ListModel<\/strong><\/code> interface, but only implements support for the <code><strong>ListDataListener<\/strong><\/code> methods.&nbsp; It is the superclass for a number of subclasses, and provides support for firing&nbsp;<code><strong>ListDataEvent<\/strong><\/code>s.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Class_DefaultListModel\"><\/span>Class DefaultListModel<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The concrete class&nbsp;<code><strong>DefaultListModel<\/strong><\/code>&nbsp;extends&nbsp;<code><strong>AbstractListModel<\/strong><\/code>, and adds support for adding and removing items from the list model.&nbsp; It provides a large number of methods, loosely basing many of them on the&nbsp;<code><strong>Vector<\/strong><\/code>&nbsp;class.&nbsp; The most immediately relevant methods 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 addElement(Object&nbsp;obj)<\/strong><\/code><\/td><td>Adds the specified component to the end of this list.&nbsp;<\/td><\/tr><tr><td><code><strong>public Object get(int&nbsp;index)<\/strong><\/code><\/td><td>Returns the element at the specified position in this list.&nbsp;<\/td><\/tr><tr><td><code><strong>public int getSize()<\/strong><\/code><\/td><td>Returns the number of components in this list.&nbsp;<\/td><\/tr><tr><td><code><strong>public Object remove(int&nbsp;index)<\/strong><\/code><\/td><td>Removes the element at the specified position in this list. Returns the element that was removed from the list.&nbsp;<\/td><\/tr><tr><td><code><strong>public void clear()<\/strong><\/code><\/td><td>Removes all of the elements from this list. The list will be empty after this call returns (unless it throws an exception).&nbsp;<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"List_Selections\"><\/span>List Selections<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Not only does&nbsp;<code>JList<\/code>&nbsp;delegate responsibility for data management to a list model,&nbsp;<em><strong>it also delegates responsibility for tracking of selected items to a list selection model<\/strong><\/em>&nbsp;&#8212; specifically, a class that implements the <code><strong>ListSelectionModel<\/strong><\/code> interface.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">List selection models provide support for three selection modes:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em><strong>Single selection mode<\/strong>&nbsp;<\/em>&#8212; allows only a single item in the list to be selected at any given time.<\/li><li><em><strong>Single interval selection mode<\/strong><\/em>&nbsp;&#8212; allows multiple selections, but the selections must be contiguous.<\/li><li><em><strong>Multiple interval selection mode<\/strong><\/em>&nbsp;&#8212; allows multiple contiguous intervals of selected items.<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The default selection mode for&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;is&nbsp;<em><strong>multiple interval selection<\/strong><\/em>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Example_of_List_Model_and_List_Selection\"><\/span>Example of List Model and List Selection<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Here is an example of the use of a <strong>ListModel<\/strong> to add to and remove items from a list model for a list.&nbsp; It uses an instance of&nbsp;<code><strong>DefaultListModel<\/strong><\/code>&nbsp;as the model for a single&nbsp;<code><strong>JList<\/strong><\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In addition, it provides a simple example of how to use list selection.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the code:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [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,77]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.Font;\nimport java.awt.GridLayout;\n\nimport java.awt.event.ActionEvent;\nimport java.awt.event.ActionListener;\n\nimport javax.swing.DefaultListModel;\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\npublic class ModifiableListTest extends JFrame\n{\n  public ModifiableListTest()\n  {\n    setTitle(&quot;Modifiable List Test&quot;);\n    setSize(300, 350);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    \n    m_list.setFont(new Font(&quot;SansSerif&quot;, Font.BOLD, 14));\n    \n    Container contentPane = getContentPane();\n    JPanel outerPane = new JPanel();\n    outerPane.add(new ControlPanel());\n    contentPane.add(outerPane, BorderLayout.WEST);\n    contentPane.add(\n        new JScrollPane(m_list), BorderLayout.CENTER);\n  }\n  \n  private void addAnimals()\n  {\n    DefaultListModel model = \n        (DefaultListModel) m_list.getModel();\n    for (int i = 0; i &lt; m_animals.length; i++)\n    {\n      model.addElement(m_animals&#x5B;i]);\n    }\n  }\n  \n  private void addFishes()\n  {\n    DefaultListModel model = \n        (DefaultListModel) m_list.getModel();\n    for (int i = 0; i &lt; m_fishes.length; i++)\n    {\n      model.addElement(m_fishes&#x5B;i]);\n    }\n  }\n  \n  private int removeSelectedItems()\n  {\n    DefaultListModel model = \n        (DefaultListModel) m_list.getModel();\n    int&#x5B;] selectedItems = m_list.getSelectedIndices();\n    for (int i = 0; i &lt; selectedItems.length; i++)\n    {\n      model.removeElementAt(selectedItems&#x5B;i] - i);\n    }\n    \/\/ Return count of remaining elements\n    return model.getSize();\n  }\n  \n  private void removeAllItems()\n  {\n    DefaultListModel model = \n        (DefaultListModel) m_list.getModel();\n    model.removeAllElements();\n  }\n  \n  \/\/ Private data for ModifiableListTest class\n  private JList m_list = new JList( new DefaultListModel() );\n  \n  private static final String&#x5B;] m_animals =\n  {\n    &quot;Ardvaark&quot;, &quot;Beaver&quot;, &quot;Opossum&quot;, \n    &quot;Squirrel&quot;, &quot;Moose&quot;, &quot;Rabbit&quot;\n  };\n  \n  private static final String&#x5B;] m_fishes =\n  {\n    &quot;Skate&quot;, &quot;Tuna&quot;, &quot;Salmon&quot;, &quot;Trout&quot;, \n    &quot;Shark&quot;, &quot;Halibut&quot;, &quot;Eel&quot;\n  };\n  \n  \/\/\/\/\/\/ Inner classes \/\/\/\/\/\/\/\n  \n  private class ControlPanel extends JPanel \n      implements ActionListener\n  {\n    public ControlPanel()\n    {\n      setLayout( new GridLayout(4, 1) );\n                          \/\/ 4 rows, 1 column\n      m_addAnimalsButton.addActionListener(this);\n      add(m_addAnimalsButton);\n      m_addFishesButton.addActionListener(this);\n      add(m_addFishesButton);\n      m_removeSelected.addActionListener(this);\n      add(m_removeSelected);\n      m_removeAll.addActionListener(this);\n      add(m_removeAll);\n    }\n    \n    public void actionPerformed(ActionEvent e)\n    {\n      JButton button = (JButton) e.getSource();\n      if (button == m_addAnimalsButton)\n      {\n        m_addAnimalsButton.setEnabled(false); \n                    \/\/ We can only add them once\n        addAnimals();\n      }\n      else if (button == m_addFishesButton)\n      {\n        m_addFishesButton.setEnabled(false); \n                    \/\/ We can only add them once\n        addFishes();\n      }\n      else if (button == m_removeSelected)\n      {\n        int remaining = removeSelectedItems();\n        if (remaining == 0)\n        {\n          m_addAnimalsButton.setEnabled(true); \n                                  \/\/ Reenable\n          m_addFishesButton.setEnabled(true); \n                                  \/\/ Reenable\n        }\n      }\n      else if (button == m_removeAll)\n      {\n        removeAllItems();\n        m_addAnimalsButton.setEnabled(true); \n                                  \/\/ Reenable\n        m_addFishesButton.setEnabled(true); \n                                  \/\/ Reenable\n      }\n    }\n    \n    \/\/ Private data for ControlPanel inner class\n    private JButton m_addAnimalsButton = \n                  new JButton(&quot;Add Animals&quot;);\n    private JButton m_addFishesButton = \n                  new JButton(&quot;Add Fishes&quot;);\n    private JButton m_removeSelected = \n                  new JButton(&quot;Remove Selected Items&quot;);\n    private JButton m_removeAll = \n                  new JButton(&quot;Remove All Items&quot;);\n  }\n  \n  \/**\n   * Main entry point for program\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    ModifiableListTest frame = new ModifiableListTest();\n    frame.setVisible(true);\n  }\n}\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">When run, this produces a frame that looks like this:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList1.gif\" alt=\"\" class=\"wp-image-1038\"\/><figcaption>Initial View<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList2.gif\" alt=\"\" class=\"wp-image-1039\"\/><figcaption>After clicking on &#8220;Add Animals&#8221;<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList3.gif\" alt=\"\" class=\"wp-image-1040\"\/><figcaption>After clicking on &#8220;Add Fishes&#8221;<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList4.gif\" alt=\"\" class=\"wp-image-1041\"\/><figcaption>After selecting a number of items<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList5.gif\" alt=\"\" class=\"wp-image-1042\"\/><figcaption>After clicking &#8220;Remove Selected Items&#8221;<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"350\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ModifiableList6.gif\" alt=\"\" class=\"wp-image-1043\"\/><figcaption>After clicking on &#8220;Remove All Items&#8221;<\/figcaption><\/figure><\/div>\n\n\n\n<div style=\"height:19px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"List_Renderers\"><\/span>List Renderers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s an example of how you might wish to use a list:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\n\nimport javax.swing.JFrame;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\npublic class JListColorSelector1 extends JFrame\n{\n  public JListColorSelector1()\n  {\n    setTitle(&quot;JListColorSelector1&quot;);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    setSize(400, 300);\n    getContentPane().add( new JListPanel() );\n  }\n  \n  private static Color&#x5B;] COLORS =\n  {\n    Color.BLACK, Color.BLUE, \n    Color.CYAN, Color.DARK_GRAY,\n    Color.GRAY, Color.GREEN, \n    Color.LIGHT_GRAY, Color.MAGENTA,\n    Color.ORANGE, Color.PINK, \n    Color.RED, Color.WHITE, \n    Color.YELLOW\n  };\n  \n  \/\/\/\/ Inner classes \/\/\/\/\n  class JListPanel extends JPanel \n      implements ListSelectionListener\n  {\n    JListPanel()\n    {\n      setLayout( new BorderLayout() );\n      \n      JPanel listPanel = new JPanel();\n      m_list.setSelectedIndex(0);\n      m_list.addListSelectionListener(this);\n      listPanel.add( new JScrollPane(m_list) );\n      add(listPanel, BorderLayout.WEST);\n      \n      add(m_colorPanel, BorderLayout.CENTER);\n      Color color = (Color) m_list.getSelectedValue();\n      m_colorPanel.setBackground(color);\n    }\n    \n    public void valueChanged(ListSelectionEvent e)\n    {\n      JList source = (JList) e.getSource();\n      Color color = (Color) source.getSelectedValue();\n      m_colorPanel.setBackground(color);\n      m_colorPanel.repaint();\n    }\n    \n    private JList  m_list = new JList(COLORS);\n    private JPanel m_colorPanel = new JPanel();\n  }\n\n  \/**\n   * Main entry point for program\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    JListColorSelector1 frame = \n        new JListColorSelector1();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which produces the following output:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ListRe1.jpg\" alt=\"\" class=\"wp-image-1049\" srcset=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ListRe1.jpg 400w, https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/ListRe1-300x225.jpg 300w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">It works: As you select an item in the list, the background color of the right-hand side changes to match the selected color.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, the actual display of the&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;leaves something to be desired.&nbsp; We are adding instances of the Color class to the&nbsp;<code><strong>JList<\/strong><\/code>, and the default display in the&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;is generated from the <code><strong>Color<\/strong><\/code> class&#8217;s <code><strong>toString()<\/strong><\/code> method, which produces an ugly, debug-style output.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Color-Rendered_List\"><\/span>A Color-Rendered List<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">All is not lost.&nbsp; We can control what is displayed in a&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;by the use of a <code><strong>ListCellRenderer<\/strong><\/code>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><strong>ListCellRenderer<\/strong><\/code> is an interface which is declared as follows (stripped down to its essentials):<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage javax.swing;\n\nimport java.awt.Component;\n\npublic interface ListCellRenderer\n{\n    Component getListCellRendererComponent(\n        JList list,\n        Object value,\n        int index,\n        boolean isSelected,\n        boolean cellHasFocus);\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;ve installed a cell renderer for a list, the renderer&#8217;s <code><strong>getListCellRendererComponent()<\/strong><\/code> method is called for each cell in the list. It returns a component that paints the cell contents.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s how you can change the previous example to cause the <code><strong>JList<\/strong><\/code> to display more appropriately:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [45]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\n\nimport javax.swing.JFrame;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\npublic class JListColorSelector2 extends JFrame\n{\n  public JListColorSelector2()\n  {\n    setTitle(&quot;JListColorSelector2&quot;);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    setSize(400, 300);\n    getContentPane().add( new JListPanel() );\n  }\n  \n  private static Color&#x5B;] COLORS =\n  {\n    Color.BLACK, Color.BLUE, \n    Color.CYAN, Color.DARK_GRAY,\n    Color.GRAY, Color.GREEN, \n    Color.LIGHT_GRAY, Color.MAGENTA,\n    Color.ORANGE, Color.PINK, \n    Color.RED, Color.WHITE,\n    Color.YELLOW\n  };\n  \n  \/\/\/\/ Inner classes \/\/\/\/\n  class JListPanel extends JPanel \n      implements ListSelectionListener\n  {\n    JListPanel()\n    {\n      setLayout( new BorderLayout() );\n      \n      JPanel listPanel = new JPanel();\n      m_list.setSelectedIndex(0);\n      m_list.setCellRenderer( new ColorRenderer() );\n      m_list.addListSelectionListener(this);\n      listPanel.add( new JScrollPane(m_list) );\n      add(listPanel, BorderLayout.WEST);\n      \n      add(m_colorPanel, BorderLayout.CENTER);\n      Color color = (Color) m_list.getSelectedValue();\n      m_colorPanel.setBackground(color);\n    }\n    \n    public void valueChanged(ListSelectionEvent e)\n    {\n      JList source = (JList) e.getSource();\n      Color color = (Color) source.getSelectedValue();\n      m_colorPanel.setBackground(color);\n      m_colorPanel.repaint();\n    }\n    \n    private JList  m_list = new JList(COLORS);\n    private JPanel m_colorPanel = new JPanel();\n  }\n  \n  \/**\n   * Main entry point for program\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    JListColorSelector2 frame = \n        new JListColorSelector2();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [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]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Component;\n\nimport java.util.HashMap;\n\nimport javax.swing.DefaultListCellRenderer;\nimport javax.swing.ListCellRenderer;\nimport javax.swing.JList;\n\npublic class ColorRenderer \n    extends DefaultListCellRenderer\n{\n  public Component getListCellRendererComponent(\n      JList list,\n      Object value,\n      int index,\n      boolean isSelected,\n      boolean cellHasFocus\n      )\n  {\n    \/\/ Call the superclass&#039;s version first\n    super.getListCellRendererComponent(\n        list, value, index, isSelected, cellHasFocus);\n    \n    \/\/ For this list cell, we expect a value of type Color\n    if (value instanceof Color)\n    {\n      Color color = (Color) value;\n      String colorName = (String) m_colorMap.get(color);\n      if (colorName != null)\n      {\n        \/\/ Make the text be the color name text\n        setText(colorName);\n        \/\/ Make the text stand out against the background color\n        Color foreground = new Color(255 - color.getRed(),\n                                     255 - color.getGreen(),\n                                     255 - color.getBlue()\n                                    );\n        \/\/ Avoid gray foreground on a gray background!\n        if (color == Color.GRAY)\n          foreground = Color.WHITE;\n        setForeground(foreground);\n      }\n      \/\/ Set the background color of the list cell \n      \/\/ to match its color.\n      setBackground(color);\n    }\n    \n    return this;\n  }\n  \n  \/\/\/ Private data \/\/\/\n  \/\/ This is a mapping of Color to color name text.\n  private static final Object&#x5B;]&#x5B;] COLOR_NAMES =\n  {\n    { Color.BLACK, &quot;Black&quot; },\n    { Color.BLUE, &quot;Blue&quot; },\n    { Color.CYAN, &quot;Cyan&quot; },\n    { Color.DARK_GRAY, &quot;Dark Gray&quot; },\n    { Color.GRAY, &quot;Gray&quot; },\n    { Color.GREEN, &quot;Green&quot;},\n    { Color.LIGHT_GRAY, &quot;Light Gray&quot; },\n    { Color.MAGENTA, &quot;Magenta&quot; },\n    { Color.ORANGE, &quot;Orange&quot; },\n    { Color.PINK, &quot;Pink&quot; },\n    { Color.RED, &quot;Red&quot; },\n    { Color.WHITE, &quot;White&quot; },\n    { Color.YELLOW, &quot;Yellow&quot; }\n  };\n  \n  private static HashMap m_colorMap = new HashMap();\n  \n  static\n  {\n    for (int color =0; color &lt; COLOR_NAMES.length; color++)\n    {\n      m_colorMap.put(COLOR_NAMES&#x5B;color]&#x5B;0], \n                     COLOR_NAMES&#x5B;color]&#x5B;1]);\n    }\n  }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This produces the following:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"400\" height=\"300\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Color-2.jpg\" alt=\"\" class=\"wp-image-1050\" srcset=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Color-2.jpg 400w, https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Color-2-300x225.jpg 300w\" sizes=\"(max-width: 400px) 100vw, 400px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:26px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">which is much more reasonable, in terms of a&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;display (albeit a little garish!).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the definition of&nbsp;<code><strong>DefaultListCellRenderer<\/strong><\/code>&nbsp;is:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>public class DefaultListCellRenderer extends JLabel<\/strong>\n         <strong> implements ListCellRenderer, Serializable<\/strong><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">which indicates that it is is a&nbsp;<code><strong>JLabel<\/strong><\/code>&nbsp;&#8212; a Component that can be used directly, and which can handle foreground and background colors, text displays, etc.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Font_List\"><\/span>A Font List<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s another example.&nbsp; We wish to display a&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;that will eventually display the selected font in its own rendition.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, let&#8217;s implement such an application in the &#8220;dumb&#8221; way:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GraphicsEnvironment;\n\nimport javax.swing.BorderFactory;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\npublic class JListFontSelector1 extends JFrame\n{\n  public JListFontSelector1()\n  {\n    setTitle(&quot;JListFontSelector1&quot;);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    getContentPane().add( new JListFontPanel() );\n    pack();\n  }\n  \n  \/\/\/\/ Inner classes \/\/\/\/\n  class JListFontPanel extends JPanel \n      implements ListSelectionListener\n  {\n    JListFontPanel()\n    {\n      setLayout( new BorderLayout() );\n      \n      JPanel listPanel = new JPanel();\n      m_list.setSelectedIndex(0);\n      m_list.addListSelectionListener(this);\n      listPanel.add( new JScrollPane(m_list) );\n      add(listPanel, BorderLayout.SOUTH);\n      \n      JPanel fontPanel = new JPanel();\n      fontPanel.setPreferredSize( new Dimension(500, 50) );\n      fontPanel.setBackground(Color.WHITE);\n      fontPanel.setBorder( \n          BorderFactory.createCompoundBorder(\n            BorderFactory.createEmptyBorder(5, 5, 5, 5),\n            BorderFactory.createLineBorder(Color.BLUE) \n            ) );\n      String fontName = \n          (String) m_list.getSelectedValue();\n      m_fontLabel.setFont( \n          new Font(fontName, Font.PLAIN, 16) );\n      fontPanel.add(m_fontLabel);\n      add(fontPanel, BorderLayout.NORTH);\n    }\n    \n    public void valueChanged(ListSelectionEvent e)\n    {\n      JList source = (JList) e.getSource();\n      String fontName = (String) source.getSelectedValue();\n      m_fontLabel.setFont( \n          new Font(fontName, Font.PLAIN, 16) );\n    }\n    \n    private JList  m_list = new JList(FONT_NAMES);\n    private JLabel m_fontLabel = \n        new JLabel(\n        &quot;The quick brown fox jumps over the lazy dog&quot;);\n  }\n  \n  private static final String&#x5B;] FONT_NAMES =\n      GraphicsEnvironment.getLocalGraphicsEnvironment()\n                         .getAvailableFontFamilyNames();\n  \n  \/**\n   * Main entry point for program\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    JListFontSelector1 frame = new JListFontSelector1();\n    frame.setVisible(true);\n  }\n}\n\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">which displays as follows:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"508\" height=\"241\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi3.jpg\" alt=\"\" class=\"wp-image-1055\" srcset=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi3.jpg 508w, https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi3-300x142.jpg 300w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:22px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Font-Rendered_List\"><\/span>A Font-Rendered List<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Now, to display the&nbsp;<code><strong>JList<\/strong><\/code>&nbsp;in the appropriate font, we use a <code><strong>FontListCellRenderer<\/strong><\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [39]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.GraphicsEnvironment;\n\nimport javax.swing.BorderFactory;\nimport javax.swing.JFrame;\nimport javax.swing.JLabel;\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.JScrollPane;\n\nimport javax.swing.event.ListSelectionEvent;\nimport javax.swing.event.ListSelectionListener;\n\npublic class JListFontSelector2 extends JFrame\n{\n  public JListFontSelector2()\n  {\n    setTitle(&quot;JListFontSelector2&quot;);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    getContentPane().add( new JListFontPanel() );\n    pack();\n  }\n  \n  \/\/\/\/ Inner classes \/\/\/\/\n  class JListFontPanel extends JPanel \n      implements ListSelectionListener\n  {\n    JListFontPanel()\n    {\n      setLayout( new BorderLayout() );\n      \n      JPanel listPanel = new JPanel();\n      m_list.setSelectedIndex(0);\n      m_list.setCellRenderer( new FontRenderer() );\n      m_list.addListSelectionListener(this);\n      listPanel.add( new JScrollPane(m_list) );\n      add(listPanel, BorderLayout.SOUTH);\n      \n      JPanel fontPanel = new JPanel();\n      fontPanel.setPreferredSize( new Dimension(500, 50) );\n      fontPanel.setBackground(Color.WHITE);\n      fontPanel.setBorder( \n          BorderFactory.createCompoundBorder(\n            BorderFactory.createEmptyBorder(5, 5, 5, 5),\n            BorderFactory.createLineBorder(Color.BLUE) \n            ) );\n      String fontName = \n          (String) m_list.getSelectedValue();\n      m_fontLabel.setFont( \n          new Font(fontName, Font.PLAIN, 16) );\n      fontPanel.add(m_fontLabel);\n      add(fontPanel, BorderLayout.NORTH);\n    }\n    \n    public void valueChanged(ListSelectionEvent e)\n    {\n      JList source = (JList) e.getSource();\n      String fontName = (String) source.getSelectedValue();\n      m_fontLabel.setFont( \n          new Font(fontName, Font.PLAIN, 16) );\n    }\n    \n    private JList  m_list = new JList(FONT_NAMES);\n    private JLabel m_fontLabel = \n        new JLabel(\n        &quot;The quick brown fox jumps over the lazy dog&quot;);\n  }\n  \n  private static final String&#x5B;] FONT_NAMES =\n      GraphicsEnvironment.getLocalGraphicsEnvironment()\n                         .getAvailableFontFamilyNames();\n  \n  \/**\n   * Main entry point for program\n   *\/\n  public static void main(String&#x5B;] args)\n  {\n    JListFontSelector2 frame = new JListFontSelector2();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [25,26,27,28,29,30,31,32,33,34,39,40,41,42,43,44,45,50,51,52,53,54]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Component;\nimport java.awt.Dimension;\nimport java.awt.Font;\nimport java.awt.FontMetrics;\nimport java.awt.Graphics;\n\nimport javax.swing.JList;\nimport javax.swing.JPanel;\nimport javax.swing.ListCellRenderer;\n\npublic class FontRenderer extends JPanel \n    implements ListCellRenderer\n{\n  public Component getListCellRendererComponent(\n      JList list,\n      Object value,\n      int index,\n      boolean isSelected,\n      boolean cellHasFocus\n      )\n  {\n    String fontName = (String) value;\n    \/\/ Set a tooltip on this panel for the font name\n    setToolTipText(fontName);\n    \n    m_font = new Font(fontName, Font.PLAIN, 14);\n    m_background = isSelected ? \n      list.getSelectionBackground() : list.getBackground();\n    m_foreground = isSelected ? \n      list.getSelectionForeground() : list.getForeground();\n    return this;\n  }\n  \n  public void paintComponent(Graphics g)\n  {\n    String text = m_font.getFamily();\n    FontMetrics fm = g.getFontMetrics(m_font);\n    g.setColor(m_background);\n    g.fillRect(0, 0, getWidth(), getHeight());\n    g.setColor(m_foreground);\n    g.setFont(m_font);\n    g.drawString(text, 0, fm.getAscent());\n  }\n  \n  public Dimension getPreferredSize()\n  {\n    String text = m_font.getFamily();\n    Graphics g = getGraphics();\n    FontMetrics fm = g.getFontMetrics(m_font);\n    return new Dimension(\n        fm.stringWidth(text), fm.getHeight());\n  }\n  \n  \/\/\/ Private data \/\/\/\n  private Font m_font;\n  private Color m_background;\n  private Color m_foreground;\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=\"508\" height=\"233\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi4.jpg\" alt=\"\" class=\"wp-image-1056\" srcset=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi4.jpg 508w, https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FontLi4-300x138.jpg 300w\" sizes=\"(max-width: 508px) 100vw, 508px\" \/><\/figure><\/div>\n\n\n\n<div style=\"height:32px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">which is much improved.&nbsp;&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that it also shows those fonts which do not produce visible text (some show no visible name; some show only boxes).&nbsp; So that you can tell which font they represent, I added a &#8220;tool tip&#8221; which shows the font name if you simply move the mouse over that entry in the list.This shows that the <code><strong>FontListCellRenderer<\/strong><\/code> does not have to extend from <code><strong>DefaultListCellRenderer<\/strong><\/code>, and that it does not have to extend from <code><strong>JLabel<\/strong><\/code>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When you wish to provide the user with a set of choices that is larger than, say, three or four choices, it is often better to avoid check boxes or radio buttons, because they take up too much space.&nbsp; A better solution is a list box, or a combo box. List Boxes Here&#8217;s an example [&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-1007","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":"When you wish to provide the user with a set of choices that is larger than, say, three or four choices, it is often better to avoid check boxes or radio buttons, because they take up too much space.&nbsp; A better solution is a list box, or a combo box. List Boxes Here&#8217;s an example&hellip;","_links":{"self":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/1007","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=1007"}],"version-history":[{"count":30,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/1007\/revisions"}],"predecessor-version":[{"id":1061,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/1007\/revisions\/1061"}],"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=1007"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}