Skip to main content
Engineering LibreTexts

13.6: Containers and Layout Managers

  • Page ID
    15145
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)

    A Container is a component that can contain other components. Because containers can contain other containers, it is possible to create a hierarchical arrangement of components, as we did in the second version of our Converter interface. In its present form, the hierarchy for Converter consists of a JFrame as the top-level container (Fig. [fig-metricgui2]). Contained within the frame is a KeyPad (subclass of JPanel), which contains 12 JButtons. Most GUIs will have a similar kind of containment hierarchy.

    A Container is a relatively simple object whose main task is primarily to hold its components in a particular order. It has methods to add and remove components (Fig. 13.20). As you can see from these methods, a container keeps track of the order of its elements, and it is possible to refer to a component by its index order.

    Layout Managers

    The hard work of organizing and managing the elements within a container is the task of the layout manager. Among other tasks, the layout manager determines

    The overall size of the container.

    The size of each element in the container.

    The spacing between elements.

    The positioning of the elements.

    Although it is possible to manage your own layouts, it is not easy to do. For most applications you are much better off by learning to use one of the AWT’s built-in layouts. Table 13.3 gives a brief summary of the available layouts. We will show examples of FlowLayout, GridLayout, and BorderLayout. Some of the widely used Swing containers have a default layout manager assigned to them (Table 13.4).

    ll
    Manager&Description

    java.awt.BorderLayout & Arranges elements along the north, south, east, west, & and in the center of the container. & Arranges elements in a single row or single column. & Arranges elements like a stack of cards, with one visible at a time. & Arranges elements left to right across the container. & Arranges elements in a grid of variably sized cells (complicated). & Arranges elements into a two-dimensional grid of equally sized cells. & Arranges elements on top of each other.

    To override the default layout for any of the JApplet, JDialog, JFrame, and JWindow containers, you must remember to use the . The correct statement is

    getContentPane().setLayout(new FlowLayout());

    ll
    Container&Layout Manager

    JApplet & BorderLayout (on its content pane) & BoxLayout & BorderLayout (on its content pane) & BorderLayout (on its content pane) & FlowLayout & BorderLayout (on its content pane)

    The GridLayout Manager

    It is simple to remedy the layout problem that affected the keypad in the most recent version of the Converter program. The problem was caused by the fact that as a subclass of JPanel, the KeyPad uses a default FlowLayout, which causes its buttons to be arranged in a row. A more appropriate layout for a numeric keypad would be a two-dimensional grid, which is exactly the kind of layout supplied by the java.awt.GridLayout. Therefore, to fix this problem, we need only set the keypad’s layout to a GridLayout. This takes a single statement, which should be added to the beginning of the KeyPad() constructor:

    setLayout(new GridLayout(4,3,1,1));

    This statement creates a GridLayout object and assigns it as the layout manager for the keypad. It will ensure that the keypad will have four rows and three columns of buttons (Fig. [fig-convertscreen3]). The last two arguments in the constructor affect the relative spacing between the rows and the columns. The higher the number, the larger the spacing. As components are added to the keypad, they will automatically be arranged by the manager into a \(4 \times 3\) grid.

    Note that for a JPanel, the setLayout() method applies to the panel itself. Unlike the top-level containers, such as JFrame, other containers don’t have content panes. The same point would apply when adding components to a JPanel: They are added directly to the panel, not to a content pane. Confusion over this point could be the source of bugs in your programs.

    As its name suggests, the GridLayout layout manager arranges components in a two-dimensional grid. When components are added to the container, the layout manager starts inserting elements into the grid at the first cell in the first row and continues left to right across row 1, then row 2, and so on. If there are not enough components to fill all cells of the grid, the remaining cells are left blank. If an attempt is made to add too many components to the grid, the layout manager will try to extend the grid in some reasonable way in order to accommodate the components. However, despite its effort in such cases, it usually fails to achieve a completely appropriate layout.

    GUI Design Critique

    Although the layout in Figure 13.21 is much improved, there are still some deficiencies. One problem is that the convert button seems to be misplaced. It would seem to make more sense if it were grouped with the keypad rather than with the input text field.

    A more serious problem results from the fact that we are still using a FlowLayout for the program’s main window, the JFrame. Among all of Java’s layouts, FlowLayout gives you the least amount of control over the arrangement of the components. Also, FlowLayout is most sensitive to changes in the size and shape of its container.

    The BorderLayout Manager

    One way to fix these problems is to use a BorderLayout to divide the frame into five areas: north, south, east, west, and center, as shown in Figure [fig-borderlayout-guis]. The BorderLayout class contains two constructors:

    public BorderLayout();
    public BorderLayout(int hgap, int vgap);

    The two parameters in the second version of the constructor allow you to insert spacing between the areas.

    Components are added to a BorderLayout by using the add(Component, String) method found in the Container class. For example, to set the application window to a border layout and to add the keypad to its east area, we would use the following statements:

    getContentPane().setLayout(new BorderLayout(2, 2));
    getContentPane().add(keypad,"East");

    In this version of the add() method, the second parameter must be a capitalized String with one of the names, “North,” “South,” “East,” “West,” or “Center.” The order in which components are added does not matter.

    One limitation of the BorderLayout is that only one component can be added to each area. That means that if you want to add several components to an area, you must first enclose them within a JPanel and then add the entire panel to the area. For example, let’s create a panel to contain the prompt and the text field and place it at the north edge of the frame:

    JPanel inputPanel = new JPanel(); // Create panel
    inputPanel.add(prompt);              // Add label
    inputPanel.add(input);           // Add textfield
                        // Add the panel to the frame
    getContentPane().add(inputPanel,"North");

    The same point would apply if we want to group the keypad with the convert button and place them at the east edge. There are several ways these elements could be grouped. In this example, we give the panel a border layout and put the keypad in the center and the convert button at the south edge:

    JPanel controlPanel= new JPanel(new BorderLayout(0,0));
    controlPanel.add(keypad,"Center");
    controlPanel.add(convert, "South");
                        // Add the panel to the frame
    getContentPane.add(controlPanel,"East"); 

    Given these details about the BorderLayout, a more appropriate design for the converter application is shown in Figure [fig-metricgui3]. Notice that the border layout for the top-level JFrame uses only the center, north, and east areas. Similarly, the border layout for the control panel uses just the center and south areas.

    In a BorderLayout, when one (or more) border area is not used, then one or more of the other areas will be extended to fill the unused area. For example, if West is not used, then North, South, and Center will extend to the left edge of the Container. If North is not used, then West, East, and Center will extend to the top edge. This is true for all areas except Center. If Center is unused, it is left blank.

    Figure [fig-convertscreen5] shows the results we get when we incorporate these changes into the program. The only changes to the program itself occur in the constructor method, which in its revised form is defined as follows:

    public Converter() {
      getContentPane().setLayout(new BorderLayout());
      keypad = new KeyPad(this);
    
      JPanel inputPanel = new JPanel(); // Input panel
      inputPanel.add(prompt);
      inputPanel.add(input);
      getContentPane().add(inputPanel,"North");
    
      JPanel controlPanel= new JPanel(new BorderLayout(0,0)); 
                                      // Control panel
      controlPanel.add(keypad, "Center");
      controlPanel.add(convert, "South");
      getContentPane().add(controlPanel, "East");
                                     // Output display
      getContentPane().add(display,"Center");  
      display.setLineWrap(true);
      display.setEditable(false);
    
      convert.addActionListener(this);
      input.addActionListener(this);
    } // Converter()

    This layout divides the interface into three main panels, an input panel, display panel, and control panel, and gives each panel its own layout. In addition, the control panel contains the keypad panel. Thus, the containment hierarchy for this design is much more complex than in our original design.

    The border layout for the top window uses the north, center, and east regions. What other combinations of areas might be used for these three components?

    Why wouldn’t a flow layout be appropriate for the control panel?


    This page titled 13.6: Containers and Layout Managers is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Ralph Morelli & Ralph Wade via source content that was edited to the style and standards of the LibreTexts platform.