{"id":861,"date":"2021-01-11T20:17:47","date_gmt":"2021-01-11T20:17:47","guid":{"rendered":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/?page_id=861"},"modified":"2021-01-11T21:14:37","modified_gmt":"2021-01-11T21:14:37","slug":"layout-management","status":"publish","type":"page","link":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/","title":{"rendered":"Layout Management"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_83 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-6a06f6437f579\" 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-6a06f6437f579\"  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\/layout-management\/#FlowLayout\" >FlowLayout<\/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\/layout-management\/#Adding_Buttons\" >Adding Buttons<\/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\/layout-management\/#Layout_Managers\" >Layout Managers<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#The_LayoutManager_Interface\" >The LayoutManager Interface<\/a><\/li><li class='ez-toc-page-1 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\/layout-management\/#The_LayoutManager2_Interface\" >The LayoutManager2 Interface<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#Components_Containers\" >Components &amp; Containers<\/a><ul class='ez-toc-list-level-4' ><li class='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\/layout-management\/#The_Component_Class\" >The Component Class<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#The_Container_Class\" >The Container Class<\/a><\/li><\/ul><\/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\/layout-management\/#BorderLayout\" >BorderLayout<\/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\/layout-management\/#GridLayout\" >GridLayout<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#Insets\" >Insets<\/a><\/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\/layout-management\/#Nested_Layouts\" >Nested Layouts<\/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\/layout-management\/#First_attempt\" >First attempt<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#Second_Attempt\" >Second Attempt<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/course-topics\/swing-gui-components\/layout-management\/#A_Calculator\" >A Calculator<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n<p>Before you can learn how to use the various GUI components provided by the Swing library, you need to learn how those GUI components are typically&nbsp;<em><strong>laid out<\/strong><\/em>&nbsp;within GUI containers.<\/p>\n\n\n\n<p>Unlike with GUIs such as Microsoft Windows, which typically uses absolute pixel positioning to place its components, Java uses&nbsp;<strong><em>layout managers<\/em><\/strong>&nbsp;to control how things are laid out.<\/p>\n\n\n\n<p>A major reason for using layout managers is that it can avoid the problems of the same code producing different results on different platforms.<\/p>\n\n\n\n<p>You can use absolute pixel positioning for laying out components if you wish, but it is strongly discouraged.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"FlowLayout\"><\/span>FlowLayout<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Consider what we did back in our discussion of events, when we created a number of&nbsp;<code>JFrame<\/code>&nbsp;with a number of&nbsp;<code>JButtons<\/code>.&nbsp;<\/p>\n\n\n\n<p>Here&#8217;s an example:<\/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\/FlowButtons.gif\" alt=\"\" class=\"wp-image-865\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:22px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>and here&#8217;s the program that produced the above frame:<\/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.Color;\nimport java.awt.Container;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass FlowButtons1Panel extends JPanel\n{\n  public FlowButtons1Panel()\n  {\n    setBackground(Color.lightGray);\n    add(m_yellow);\n    add(m_blue);\n    add(m_red);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_yellow = new JButton(&quot;Yellow&quot;);\n  private JButton m_blue = new JButton(&quot;Blue&quot;);\n  private JButton m_red = new JButton(&quot;Red&quot;);\n}\n\nclass FlowButtons1Frame extends JFrame\n{\n  public FlowButtons1Frame()\n  {\n    setTitle(&quot;FlowButtons&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new FlowButtons1Panel() );\n  }\n}\n\npublic class FlowButtons1\n{\n  public static void main(String&#x5B;] args)\n  {\n    FlowButtons1Frame frame = new FlowButtons1Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>Notice that the buttons are nicely centered, horizontally.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Adding_Buttons\"><\/span>Adding Buttons<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Now, let&#8217;s see what happens is we add more buttons:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [18,19,20,21,28,29,30,31]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Container;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass FlowButtons2Panel extends JPanel\n{\n  public FlowButtons2Panel()\n  {\n    setBackground(Color.lightGray);\n    add(m_yellow);\n    add(m_blue);\n    add(m_red);\n    add(m_orange);\n    add(m_cyan);\n    add(m_pink);\n    add(m_white);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_yellow = new JButton(&quot;Yellow&quot;);\n  private JButton m_blue = new JButton(&quot;Blue&quot;);\n  private JButton m_red = new JButton(&quot;Red&quot;);\n  private JButton m_orange = new JButton(&quot;Orange&quot;);\n  private JButton m_cyan = new JButton(&quot;Cyan&quot;);\n  private JButton m_pink = new JButton(&quot;Pink&quot;);\n  private JButton m_white = new JButton(&quot;White&quot;);\n}\n\nclass FlowButtons2Frame extends JFrame\n{\n  public FlowButtons2Frame()\n  {\n    setTitle(&quot;FlowButtons&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new FlowButtons2Panel() );\n  }\n}\n\npublic class FlowButtons2\n{\n  public static void main(String&#x5B;] args)\n  {\n    FlowButtons2Frame frame = new FlowButtons2Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>Here&#8217;s what we get:<\/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\/FlowButtons2.gif\" alt=\"\" class=\"wp-image-868\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:21px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Again, notice that the buttons are still nicely centered, horizontally, and when there&#8217;s no more room left on the first row, the additional buttons are automatically placed in a second row.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Furthermore, if the user resizes the frame, the buttons stay centered:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img decoding=\"async\" width=\"182\" height=\"181\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FlowButtons3.gif\" alt=\"\" class=\"wp-image-869\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:38px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Layout_Managers\"><\/span>Layout Managers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>What&#8217;s happening here?&nbsp;&nbsp;<\/p>\n\n\n\n<p>We&#8217;re using something called a&nbsp;<em><strong>layout manager<\/strong><\/em>.&nbsp; In this case, we&#8217;re using a particular layout manager &#8212;&nbsp;<code><strong>FlowLayout<\/strong><\/code>.&nbsp;&nbsp; But how did we end up using it?<\/p>\n\n\n\n<p>It turns out that&nbsp;<code><strong>FlowLayout<\/strong><\/code>&nbsp;is the default layout manager for a&nbsp;<code><strong>JPanel<\/strong><\/code>, so we get it for free in our examples above.<\/p>\n\n\n\n<p>We can be explicit about using the&nbsp;<code><strong>FlowLayout<\/strong><\/code>&nbsp;manager.&nbsp; We can also change its default behavior.&nbsp; For example, we can specify that it left-align, instead of centering, and specify the gap between the components, in both the horizontal and vertical direction:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [5,16,17,18,19,20,21]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.FlowLayout;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass FlowButtons3Panel extends JPanel\n{\n  public FlowButtons3Panel()\n  {\n    setBackground(Color.lightGray);\n    setLayout(\n        new FlowLayout(FlowLayout.LEFT, \/\/ Alignment \n                       20, \/\/ Horizontal gap\n                       0   \/\/ Vertical gap\n                      )\n             );\n    add(m_yellow);\n    add(m_blue);\n    add(m_red);\n    add(m_orange);\n    add(m_cyan);\n    add(m_pink);\n    add(m_white);\n  }\n\n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_yellow = new JButton(&quot;Yellow&quot;);\n  private JButton m_blue = new JButton(&quot;Blue&quot;);\n  private JButton m_red = new JButton(&quot;Red&quot;);\n  private JButton m_orange = new JButton(&quot;Orange&quot;);\n  private JButton m_cyan = new JButton(&quot;Cyan&quot;);\n  private JButton m_pink = new JButton(&quot;Pink&quot;);\n  private JButton m_white = new JButton(&quot;White&quot;);\n}\n\nclass FlowButtons3Frame extends JFrame\n{\n  public FlowButtons3Frame()\n  {\n    setTitle(&quot;FlowButtons&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new FlowButtons3Panel() );\n  }\n}\n\npublic class FlowButtons3\n{\n  public static void main(String&#x5B;] args)\n  {\n    FlowButtons3Frame frame = new FlowButtons3Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>which produces the following results:<\/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\/FlowButtons4.gif\" alt=\"\" class=\"wp-image-870\"\/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"174\" height=\"175\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/FlowButtons5.gif\" alt=\"\" class=\"wp-image-871\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:29px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_LayoutManager_Interface\"><\/span>The LayoutManager Interface<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>A class that extends from&nbsp;<code><strong>java.awt.Container<\/strong><\/code>&nbsp;is responsible for laying out the components that are contained within it.&nbsp;&nbsp; Such classes delegate the responsibility of how components are laid out to a&nbsp;<em><strong>layout manager<\/strong><\/em>.&nbsp; A layout manager is responsible for:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Calculating the preferred and minimum sizes for a container<\/li><li>Laying out the components contained in a container.<\/li><\/ul>\n\n\n\n<p>A layout manager class implements the methods required by the <strong><code>LayoutManager<\/code><\/strong> interface:<\/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 addLayoutComponent(String&nbsp;name, Component&nbsp;comp)<\/strong><\/code><\/td><td>Adds the specified component with the specified name to the layout.<\/td><\/tr><tr><td><code><strong>public void removeLayoutComponent(Component&nbsp;comp)<\/strong><\/code><\/td><td>Removes the specified component from the layout.<\/td><\/tr><tr><td><code><strong>public Dimension preferredLayoutSize(Container&nbsp;parent)<\/strong><\/code><\/td><td>Calculates the preferred size dimensions for the specified panel given the components in the specified parent container.<\/td><\/tr><tr><td><code><strong>public Dimension minimumLayoutSize(Container&nbsp;parent)<\/strong><\/code><\/td><td>Calculates the minimum size dimensions for the specified panel given the components in the specified parent container.<\/td><\/tr><tr><td><code><strong>public void layoutContainer(Container&nbsp;parent)<\/strong><\/code><\/td><td>Lays out the container in the specified panel.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><code><strong>FlowLayout<\/strong><\/code>&nbsp;and&nbsp;<code><strong>GridLayout<\/strong><\/code>&nbsp;(to be described later) implement the <code><strong>LayoutManager<\/strong><\/code> interface directly.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_LayoutManager2_Interface\"><\/span>The LayoutManager2 Interface<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Some layout managers attach&nbsp;<em><strong>constraints<\/strong><\/em>&nbsp;to components that determine how the components are to be laid out.&nbsp; As we&#8217;ll see soon,&nbsp;<code><strong>BorderLayout<\/strong><\/code>&nbsp;is an example of such a layout manager.&nbsp;&nbsp;<\/p>\n\n\n\n<p>The&nbsp;<code><strong>LayoutManager2<\/strong><\/code>&nbsp;interface is for such constraint-applying layout managers;&nbsp; it extends from the&nbsp;<code><strong>LayoutManager<\/strong><\/code>&nbsp;interface, and adds 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><code><strong>public void addLayoutComponent(Component&nbsp;comp, Object&nbsp;constraints)<\/strong><\/code><\/td><td>Adds the specified component to the layout, using the specified constraint object.<\/td><\/tr><tr><td><code><strong>public Dimension maximumLayoutSize(Container&nbsp;target)<\/strong><\/code><\/td><td>Returns the maximum size of this component.<\/td><\/tr><tr><td><code><strong>public float getLayoutAlignmentX(Container&nbsp;target)<\/strong><\/code><\/td><td>Returns the alignment along the x axis. This specifies how the component would like to be aligned relative to other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 is aligned the furthest away from the origin, 0.5 is centered, etc.<\/td><\/tr><tr><td><code><strong>public float getLayoutAlignmentY(Container&nbsp;target)<\/strong><\/code><\/td><td>Returns the alignment along the y axis. This specifies how the component would like to be aligned relative to other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 is aligned the furthest away from the origin, 0.5 is centered, etc.<\/td><\/tr><tr><td><code><strong>public void invalidateLayout(Container&nbsp;target)<\/strong><\/code><\/td><td>Invalidates the layout, indicating that if the layout manager has cached information it should be discarded.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The&nbsp;<code><strong>BorderLayout<\/strong><\/code>,&nbsp;<code><strong>BoxLayout<\/strong><\/code>,&nbsp;<code><strong>CardLayout<\/strong><\/code>, and&nbsp;<code><strong>GridBagLayout<\/strong><\/code>&nbsp;layout managers all implement the&nbsp;<code><strong>LayoutManager2<\/strong><\/code>&nbsp;interface.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Components_Containers\"><\/span>Components &amp; Containers<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Component_Class\"><\/span>The Component Class<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p><code><strong>Component<\/strong><\/code>s implement two methods that affect their interactions with layout managers:<\/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 Dimension getPreferredSize()<\/strong><\/code><\/td><td>Gets the preferred size of this component.<\/td><\/tr><tr><td><code><strong>public Dimension getMinimumSize()<\/strong><\/code><\/td><td>Gets the minimum size of this component.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Each&nbsp;<code><strong>Component<\/strong><\/code>&nbsp;within a&nbsp;<code><strong>Container<\/strong><\/code>&nbsp;tells the&nbsp;<code><strong>Container<\/strong><\/code>&#8216;s layout manager what size it would prefer to be, and what minimum size it needs to be.&nbsp;&nbsp; Typically, a layout manager will cycle through the&nbsp;<code><strong>Component<\/strong><\/code>s within the&nbsp;<code><strong>Container<\/strong><\/code>&nbsp;to determine the preferred and minimum sizes for the container itself.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_Container_Class\"><\/span>The Container Class<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p><code><strong>Container<\/strong><\/code>s implement a number of methods that affect their interactions with layout managers:<\/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 Component add(Component&nbsp;comp)<\/strong><\/code><\/td><td>Adds the specified component to the end of this container.<\/td><\/tr><tr><td><code><strong>public Component add(Component&nbsp;comp, int&nbsp;index)<\/strong><\/code><\/td><td>Adds the specified component to this container at the given position.&nbsp; The index is the position at which to insert the component, or&nbsp;<code>-1<\/code>&nbsp;to insert the component at the end.<\/td><\/tr><tr><td><code><strong>public void add(Component&nbsp;comp, Object&nbsp;constraints)<\/strong><\/code><\/td><td>Adds the specified component to the end of this container. Also notifies the layout manager to add the component to this container&#8217;s layout using the specified constraints object.<\/td><\/tr><tr><td><code><strong>public void add(Component&nbsp;comp, Object&nbsp;constraints, int&nbsp;index)<\/strong><\/code><\/td><td>Adds the specified component to this container with the specified constraints at the specified index. Also notifies the layout manager to add the component to the this container&#8217;s layout using the specified constraints object.<\/td><\/tr><tr><td><code><strong>protected void addImpl(Component&nbsp;comp, Object&nbsp;constraints, int&nbsp;index)<\/strong><\/code><\/td><td>Adds the specified component to this container at the specified index. This method also notifies the layout manager to add the component to this container&#8217;s layout using the specified constraints object.This is the method to override if a program needs to track every add request to a container. An overriding method should usually include a call to the superclass&#8217;s version of the method:<code>super.addImpl(comp, constraints, index)<\/code><\/td><\/tr><tr><td><code><strong>public Component getComponent(int&nbsp;n)<\/strong><\/code><\/td><td>Gets the nth component in this container.<\/td><\/tr><tr><td><code><strong>public Component[] getComponents()<\/strong><\/code><\/td><td>Gets all the components in this container.<\/td><\/tr><tr><td><code><strong>public int getComponentCount()<\/strong><\/code><\/td><td>Gets the number of components in this panel.<\/td><\/tr><tr><td><code><strong>public Insets getInsets()<\/strong><\/code><\/td><td>Determines the insets of this container, which indicate the size of the container&#8217;s border.<br>A&nbsp;<code>Frame<\/code>&nbsp;object, for example, has a top inset that corresponds to the height of the frame&#8217;s title bar.<\/td><\/tr><tr><td><code><strong>public void remove(int&nbsp;index)<\/strong><\/code><\/td><td>Removes the component, specified by&nbsp;<code>index<\/code>, from this container.<\/td><\/tr><tr><td><code><strong>public void remove(Component&nbsp;comp)<\/strong><\/code><\/td><td>Removes the specified component from this container.<\/td><\/tr><tr><td><code><strong>public void removeAll()<\/strong><\/code><\/td><td>Removes all the components from this container.<\/td><\/tr><tr><td><code><strong>public LayoutManager getLayout()<\/strong><\/code><\/td><td>Gets the layout manager for this container.<\/td><\/tr><tr><td><code><strong>public void setLayout(LayoutManager&nbsp;mgr)<\/strong><\/code><\/td><td>Sets the layout manager for this container.<\/td><\/tr><tr><td><code><strong>public void doLayout()<\/strong><\/code><\/td><td>Causes this container to lay out its components. Most programs should not call this method directly, but should invoke the&nbsp;<code>validate<\/code>&nbsp;method instead.<\/td><\/tr><tr><td><code><strong>public void invalidate()<\/strong><\/code><\/td><td>Invalidates the container. The container and all parents above it are marked as needing to be laid out. This method can be called often, so it needs to execute quickly.<\/td><\/tr><tr><td><code><strong>public void validate()<\/strong><\/code><\/td><td>Validates this container and all of its subcomponents.<br>AWT uses&nbsp;<code>validate<\/code>&nbsp;to cause a container to lay out its subcomponents again after the components it contains have been added to or modified.<\/td><\/tr><tr><td><code><strong>protected void validateTree()<\/strong><\/code><\/td><td>Recursively descends the container tree and recomputes the layout for any subtrees marked as needing it (those marked as invalid). Synchronization should be provided by the method that calls this one:&nbsp;<code>validate<\/code>.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"BorderLayout\"><\/span>BorderLayout<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>The&nbsp;<code><strong>BorderLayout<\/strong><\/code>&nbsp;layout manager is one of the most useful layout managers provided in the JDK.&nbsp; It lays out components according to the points of the compass:&nbsp;&nbsp;<code><strong>NORTH<\/strong><\/code>,&nbsp;<code><strong>SOUTH<\/strong><\/code>,&nbsp;<code><strong>EAST<\/strong><\/code>,&nbsp;<code><strong>WEST<\/strong><\/code>, and&nbsp;<code><strong>CENTER<\/strong><\/code>.&nbsp;<\/p>\n\n\n\n<p>Here&#8217;s an example that shows its use:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [3,16,17,18,19,20,21]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass BorderButtons1Panel extends JPanel\n{\n  public BorderButtons1Panel()\n  {\n    setBackground(Color.lightGray);\n    setLayout( new BorderLayout() );\n    add(m_north,  BorderLayout.NORTH);\n    add(m_south,  BorderLayout.SOUTH);\n    add(m_east,   BorderLayout.EAST);\n    add(m_west,   BorderLayout.WEST);\n    add(m_center, BorderLayout.CENTER);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_north = new JButton(&quot;North&quot;);\n  private JButton m_south = new JButton(&quot;South&quot;);\n  private JButton m_east = new JButton(&quot;East&quot;);\n  private JButton m_west = new JButton(&quot;West&quot;);\n  private JButton m_center = new JButton(&quot;Center&quot;);\n}\n\nclass BorderButtons1Frame extends JFrame\n{\n  public BorderButtons1Frame()\n  {\n    setTitle(&quot;BorderButtons&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new BorderButtons1Panel() );\n  }\n}\n\npublic class BorderButtons1\n{\n  public static void main(String&#x5B;] args)\n  {\n    BorderButtons1Frame frame = new BorderButtons1Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>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\/BorderButtons.gif\" alt=\"\" class=\"wp-image-879\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Note that the buttons&#8217;&nbsp;<em>preferred sizes<\/em>&nbsp;appear to be completely ignored by the&nbsp;<code>BorderLayout<\/code>&nbsp;layout manager.&nbsp; Actually, what happens is that:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The&nbsp;<strong><em>North<\/em><\/strong>&nbsp;and&nbsp;<strong><em>South<\/em><\/strong>&nbsp;regions pay attention to the component&#8217;s preferred&nbsp;<strong><em>height<\/em><\/strong>, and stretch out the component to fill the region horizontally<\/li><li>The&nbsp;<strong><em>East<\/em><\/strong>&nbsp;and&nbsp;<strong><em>West<\/em><\/strong>&nbsp;regions pay attention to the component&#8217;s preferred&nbsp;<strong><em>width<\/em><\/strong>, and stretch out the component to fill the region vertically.&nbsp;&nbsp;<\/li><li>The&nbsp;<strong><em>Center<\/em><\/strong>&nbsp;region gets what&#8217;s left over, regardless of the component&#8217;s preferred size, and the component gets stretched both horizontally and vertically.<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"GridLayout\"><\/span>GridLayout<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Some would claim that&nbsp;<code><strong>GridLayout<\/strong><\/code>&nbsp;is perhaps the easiest layout manager to use.&nbsp;&nbsp;<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [5,16,17,18,19]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.GridLayout;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass GridButtons1Panel extends JPanel\n{\n  public GridButtons1Panel()\n  {\n    setBackground(Color.lightGray);\n    setLayout( new GridLayout(1, 3) ); \/\/ rows, cols\n    add(m_button1);\n    add(m_button2);\n    add(m_button3);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_button1 = new JButton(&quot;1&quot;);\n  private JButton m_button2 = new JButton(&quot;2&quot;);\n  private JButton m_button3 = new JButton(&quot;3&quot;);\n}\n\nclass GridButtons1Frame extends JFrame\n{\n  public GridButtons1Frame()\n  {\n    setTitle(&quot;GridButtons&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new GridButtons1Panel() );\n  }\n}\n\npublic class GridButtons1\n{\n  public static void main(String&#x5B;] args)\n  {\n    GridButtons1Frame frame = new GridButtons1Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>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\/Gridla20.jpg\" alt=\"\" class=\"wp-image-884\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:19px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Note in particular that every cell in a <strong>GridLayout<\/strong> panel is the same size as every other cell.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Insets\"><\/span>Insets<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>Every component has a set of&nbsp;<strong><em>insets<\/em><\/strong>.&nbsp; Insets specify the <em>widths of the component&#8217;s margins<\/em>.&nbsp; Insets include:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>top inset<\/li><li>left inset<\/li><li>bottom inset<\/li><li>right inset<\/li><\/ul>\n\n\n\n<p>For example, a frame&#8217;s insets include a&nbsp;<strong><em>top inset<\/em><\/strong>&nbsp;that compensates for the frame&#8217;s titlebar, and insets all around that compensate for the border (which we can use to resize the frame).<\/p>\n\n\n\n<p>A panel contained within a frame has its own insets.&nbsp; Indeed, any component has its own&nbsp; insets.&nbsp; Usually, however, you only have to worry about insets for containers &#8212; unless you&#8217;re designing a new GUI component.<\/p>\n\n\n\n<p>Layout managers are supposed to respect a container&#8217;s insets and never lay out a component in the inset margins.&nbsp; The layout managers supplied with the JDK all respect this.&nbsp; If you write a layout manager, you should write it to respect insets, too.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong><em><u>Note:<\/u><\/em><\/strong>&nbsp;It seems that the use of insets is now deprecated, in favor of borders.&nbsp; We&#8217;ll discuss borders, which are much richer and provide much greater flexibility, shortly.<\/p><\/blockquote>\n\n\n\n<p>Here&#8217;s an example that shows how to set insets for a container:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [6,25,26,27,28,29,30]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\nimport java.awt.Insets;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass BorderButtonsInsetsPanel extends JPanel\n{\n  public BorderButtonsInsetsPanel()\n  {\n    setBackground(Color.GREEN);\n    setLayout(new BorderLayout());\n    add(m_north, BorderLayout.NORTH);\n    add(m_south, BorderLayout.SOUTH);\n    add(m_east, BorderLayout.EAST);\n    add(m_west, BorderLayout.WEST);\n    add(m_center, BorderLayout.CENTER);\n  }\n  \n  \/\/ Override this method to specify the panel&#039;s\n  \/\/ insets (top, left, bottom, right).\n  public Insets getInsets()\n  {\n    return new Insets(5, 10, 15, 20);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_north = new JButton(&quot;North&quot;);\n  private JButton m_south = new JButton(&quot;South&quot;);\n  private JButton m_east = new JButton(&quot;East&quot;);\n  private JButton m_west = new JButton(&quot;West&quot;);\n  private JButton m_center = new JButton(&quot;Center&quot;);\n}\n\nclass BorderButtonsInsetsFrame extends JFrame\n{\n  public BorderButtonsInsetsFrame()\n  {\n    setTitle(&quot;BorderButtonsInsets&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new BorderButtonsInsetsPanel() );\n  }\n}\n\npublic class BorderButtonsInsets\n{\n  public static void main(String&#x5B;] args)\n  {\n    BorderButtonsInsetsFrame frame = \n                  new BorderButtonsInsetsFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>which produces the following interesting effect:<\/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\/BorderButtonsInsets.gif\" alt=\"\" class=\"wp-image-888\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:17px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Note that the inset margins do not have to be the same all the way around.&nbsp; I&#8217;ve emphasized this in the above example, which makes it look a little strange.&nbsp; However, this can be used to advantage in some situations to improve the look of a GUI application.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Nested_Layouts\"><\/span>Nested Layouts<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p>By themselves,&nbsp;<code><strong>FlowLayout<\/strong><\/code>&nbsp;and&nbsp;<code><strong>BorderLayout<\/strong><\/code>&nbsp;provide very simple layout support.&nbsp; Real applications require more sophisticated support.&nbsp;&nbsp;<\/p>\n\n\n\n<p>For example, suppose you wish to have a frame with several buttons at the bottom:<\/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\/NestedLayouts.gif\" alt=\"\" class=\"wp-image-892\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:29px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>How can we accomplish this?<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"First_attempt\"><\/span>First attempt<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>You might think that you could use a&nbsp;<code><strong>BorderLayout<\/strong><\/code>, and simply add the three buttons all to the <strong>South<\/strong>.&nbsp;&nbsp; So your code might look like:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [15,16,17]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass NestedLayouts1Panel extends JPanel\n{\n  public NestedLayouts1Panel()\n  {\n    setLayout(new BorderLayout());\n    add(m_yellow, BorderLayout.SOUTH);\n    add(m_blue, BorderLayout.SOUTH);\n    add(m_red, BorderLayout.SOUTH);\n  }\n\n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_yellow = new JButton(&quot;Yellow&quot;);\n  private JButton m_blue = new JButton(&quot;Blue&quot;);\n  private JButton m_red = new JButton(&quot;Red&quot;);\n}\n\nclass NestedLayouts1Frame extends JFrame\n{\n  public NestedLayouts1Frame()\n  {\n    setTitle(&quot;NestedLayouts&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new NestedLayouts1Panel() );\n  }\n}\n\npublic class NestedLayouts1\n{\n  public static void main(String&#x5B;] args)\n  {\n    NestedLayouts1Frame frame = new NestedLayouts1Frame();\n    frame.setVisible(true);\n  }\n}\n\n<\/pre><\/div>\n\n\n<p>but the results look 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=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/NestedLayoutsBad.gif\" alt=\"\" class=\"wp-image-893\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:24px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Notice that only the last component to be added to the <strong>South<\/strong> is the one that actually resides there.<\/p>\n\n\n\n<p>That clearly doesn&#8217;t work!<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Second_Attempt\"><\/span>Second Attempt<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>So what to do?&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n\n\n\n<p><em><strong>Here&#8217;s a better approach:<\/strong><\/em>&nbsp; You can create a separate panel, with a&nbsp;<code><strong>FlowLayout<\/strong><\/code>&nbsp;(the default layout manager for a&nbsp;<code><strong>JPanel<\/strong><\/code>), and add it to the south of the main panel, which uses a&nbsp;<code><strong>BorderLayout<\/strong><\/code>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [16,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Color;\nimport java.awt.Container;\n\nimport javax.swing.JButton;\nimport javax.swing.JFrame;\nimport javax.swing.JPanel;\n\nclass NestedLayouts2Panel extends JPanel\n{\n  public NestedLayouts2Panel()\n  {\n    setLayout(new BorderLayout());\n    add(new ButtonsPanel(), BorderLayout.SOUTH);\n  }\n}\n\nclass ButtonsPanel extends JPanel\n{\n  public ButtonsPanel()\n  {\n    setBackground(Color.pink);\n    add(m_yellow);\n    add(m_blue);\n    add(m_red);\n  }\n  \n  \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n  private JButton m_yellow = new JButton(&quot;Yellow&quot;);\n  private JButton m_blue = new JButton(&quot;Blue&quot;);\n  private JButton m_red = new JButton(&quot;Red&quot;);\n}\n\nclass NestedLayouts2Frame extends JFrame\n{\n  public NestedLayouts2Frame()\n  {\n    setTitle(&quot;NestedLayouts&quot;);\n    setSize(300, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new NestedLayouts2Panel() );\n  }\n}\n\npublic class NestedLayouts2\n{\n  public static void main(String&#x5B;] args)\n  {\n    NestedLayouts2Frame frame = new NestedLayouts2Frame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>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\/NestedLayoutsPink.gif\" alt=\"\" class=\"wp-image-894\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:28px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>I colored the additional panel pink, to indicate its presence.&nbsp; If I hadn&#8217;t, you would have no visual indication that it was there.<\/p>\n\n\n\n<p>This approach of <em>nesting layout managers<\/em> of the appropriate types is very useful, and as a result is used heavily in Java GUIs.&nbsp; Nested layouts can be used to construct some surprisingly complex layouts.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"A_Calculator\"><\/span>A Calculator<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p>Here&#8217;s an example of a simple calculator, laid out using nested panels with <strong>BorderLayout<\/strong> and <strong>GridLayout<\/strong> managers:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; auto-links: false; highlight: [19,21,22,23,45]; title: ; quick-code: false; notranslate\" title=\"\">\npackage swingExamples;\n\nimport java.awt.BorderLayout;\nimport java.awt.Container;\nimport java.awt.GridLayout;\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.JTextField;\n\nclass CalculatorPanel extends JPanel\n{\n  public CalculatorPanel()\n  {\n    setLayout(new BorderLayout());\n    m_display.setEditable(false);\n    add(m_display, BorderLayout.NORTH);\n    add(m_buttonsPanel, BorderLayout.CENTER);\n    add(m_clearButton, BorderLayout.SOUTH);\n    m_clearButton.addActionListener( new ActionListener()\n      {\n        public void actionPerformed(ActionEvent evt)\n        {\n          m_buttonsPanel.clear();\n        }\n      }\n    );\n  }\n\n  \/\/\/\/\/\/ Private data \/\/\/\/\/\/\n  private JTextField m_display = new JTextField(&quot;0&quot;);\n  private ButtonsPanel m_buttonsPanel = new ButtonsPanel();\n  private JButton m_clearButton = new JButton(&quot;Clear&quot;);\n\n  \/\/\/\/\/\/ Inner classes \/\/\/\/\/\n  class ButtonsPanel extends JPanel \n      implements ActionListener\n  {\n    public ButtonsPanel()\n    {\n      setLayout(new GridLayout(4, 4));\n      String buttonLabels = &quot;789\/456*123-0.=+&quot;;\n      for (int i = 0; i &lt; buttonLabels.length(); i++)\n      {\n        addButton(buttonLabels.substring(i, i + 1));\n      }\n    }\n\n    public void clear()\n    {\n      m_arg = 0.0;\n      m_op = &#039;=&#039;;\n      m_start = true;\n      m_display.setText(&quot;&quot;);\n    }\n\n    private void addButton(String label)\n    {\n      JButton button = new JButton(label);\n      add(button);\n      button.addActionListener(this);\n    }\n\n    \/\/ ActionListener required methods\n    public void actionPerformed(ActionEvent evt)\n    {\n      String command = evt.getActionCommand();\n      char commandChar = command.charAt(0);\n      if (&#039;0&#039; &lt;= commandChar &amp;&amp; \n          commandChar &lt;= &#039;9&#039; || commandChar == &#039;.&#039;)\n      {\n        if (m_start)\n        {\n          m_display.setText(command);\n        }\n        else\n        {\n          m_display.setText(m_display.getText() + \n                                commandChar);\n        }\n        m_start = false;\n      }\n      else\n      {\n        if (m_start)\n        {\n          if (commandChar == &#039;-&#039; || commandChar == &#039;+&#039;)\n          {\n            m_display.setText(command);\n            m_start = false;\n          }\n          else\n          {\n            m_op = commandChar;\n          }\n        }\n        else\n        {\n          double x = Double.parseDouble(\n                              m_display.getText());\n          calculate(x);\n          m_op = commandChar;\n          m_start = true;\n        }\n      }\n    }\n\n    private void calculate(double n)\n    {\n      switch (m_op)\n      {\n        case &#039;+&#039;:\n          m_arg += n;\n          break;\n        case &#039;-&#039;:\n          m_arg -= n;\n          break;\n        case &#039;*&#039;:\n          m_arg *= n;\n          break;\n        case &#039;\/&#039;:\n          m_arg \/= n;\n          break;\n        case &#039;=&#039;:\n          m_arg = n;\n      }\n      m_display.setText(&quot;&quot; + m_arg);\n    }\n\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/ Private Data \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n    private boolean m_start = true;\n    private double m_arg = 0.0;\n    private char m_op = &#039;=&#039;;\n  }\n}\n\nclass CalculatorFrame extends JFrame\n{\n  public CalculatorFrame()\n  {\n    setTitle(&quot;Calculator&quot;);\n    setSize(200, 200);\n    setDefaultCloseOperation(EXIT_ON_CLOSE);\n    Container contentPane = getContentPane();\n    contentPane.add( new CalculatorPanel() );\n  }\n}\n\npublic class Calculator\n{\n  public static void main(String&#x5B;] args)\n  {\n    CalculatorFrame frame = new CalculatorFrame();\n    frame.setVisible(true);\n  }\n}\n<\/pre><\/div>\n\n\n<p>which produces:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"alignleft size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"200\" height=\"200\" src=\"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-content\/uploads\/2021\/01\/Calculator.gif\" alt=\"\" class=\"wp-image-895\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:42px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Before you can learn how to use the various GUI components provided by the Swing library, you need to learn how those GUI components are typically&nbsp;laid out&nbsp;within GUI containers. Unlike with GUIs such as Microsoft Windows, which typically uses absolute pixel positioning to place its components, Java uses&nbsp;layout managers&nbsp;to control how things are laid out. [&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-861","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":"Before you can learn how to use the various GUI components provided by the Swing library, you need to learn how those GUI components are typically&nbsp;laid out&nbsp;within GUI containers. Unlike with GUIs such as Microsoft Windows, which typically uses absolute pixel positioning to place its components, Java uses&nbsp;layout managers&nbsp;to control how things are laid out.&hellip;","_links":{"self":[{"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/861","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=861"}],"version-history":[{"count":19,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/861\/revisions"}],"predecessor-version":[{"id":900,"href":"https:\/\/bhiggs.x10hosting.com\/PracticalJavaProgramming\/wp-json\/wp\/v2\/pages\/861\/revisions\/900"}],"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=861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}