import  java.awt.*;
import  java.awt.event.*;
import  javax.swing.*;
import  javax.swing.border.*;

/**
 * A GUI application that includes containers using BoxLayout,
 * GridBagLayout, and no layout manager (absolute positioning). 
 * It uses a private helper method to set the gridbag
 * constraints.
 * 
 * @author Sharon Tuttle
 * @version 2015-10-14
 */

public class LayoutTrio2
{
    /**
     * creates a LayoutTrio2Frame
     * 
     * @param args not used here
     */
    
    public static void main(String args[])
    { 
        EventQueue.invokeLater(
            new Runnable()
            {
                public void run()
                {
                    LayoutTrio2Frame mainFrame = new LayoutTrio2Frame();
                    mainFrame.setDefaultCloseOperation( 
                        JFrame.EXIT_ON_CLOSE );    
                    mainFrame.setVisible(true);  
                }
            });
    }
}

/** 
 * A frame with a panel featuring three containers using
 * BoxLayout, GridBagLayout and no layout manager (absolute positioning)
 */

class LayoutTrio2Frame extends JFrame
{
    // data fields
    
    private final static int DEFAULT_WIDTH = 950;
    private final static int DEFAULT_HEIGHT = 250;
    
    /**
     * constructs a LayoutTrio2Frame instance
     */
    
    public LayoutTrio2Frame()
    {    
        this.setTitle("BoxLayout and GridBagLayout and No Layout, oh my!");
        this.setSize(this.DEFAULT_WIDTH, this.DEFAULT_HEIGHT);

        // add LayoutTrio2 panel to frame
        
        LayoutTrio2Panel panel = new LayoutTrio2Panel();
        this.add(panel);
    }
}

/**
 * A panel featuring three containers using BoxLayout, GridBagLayout, and
 * no layout manager (absolute positioning)
 */

class LayoutTrio2Panel extends JPanel
{
    //--------
    // data fields 
    //--------
    
    private final static Font DISPLAY_FONT = new Font(
                                            "Dialog", Font.PLAIN, 20);
    private JPanel middlePanel;  
    
    /**
     * constructs a LayoutTrio2 panel instance
     */
    
    public LayoutTrio2Panel()
    {                        
        // let's set layout for this "master" panel (a 1-row, 3-column grid)
        
        this.setLayout(new GridLayout(1, 3));
                
        // we'll have a Box using BoxLayout in the leftmost "cell"
        //     (set up using a local helper method, setUpLeftBox)
        
        Box leftBox = this.setUpLeftBox();
        this.add(leftBox); 
        
        // we'll have a JPanel using GridBagLayout in the "middle" 
        //     ah - because this is a data field, it can be referenced
        //     directly in this private method, setUpMiddlePanel
        
        this.setUpMiddlePanel();
        this.add(this.middlePanel);
        
        // we'll have a JPanel using no layout manager (absolute positioning) on
        //     the "right" (set up using a local helper method, setUpRightPanel)
        
        JPanel rightPanel = this.setUpRightPanel();
        this.add(rightPanel);
        
    } // end LayoutTrio2Panel constructor  
    
   /**
       sets the gridbag constraints for the given GridBagConstraints
       object as specified, and adds the passed component subject to those
       constraints
       
       @param component the component to have constraints added
       @param thisX the gridx for this component
       @param thisY the gridy for this component
       @param thisWidth the gridwidth for this component
       @param thisHt the gridheight for this component
       @param thisWtx the weightx for this component
       @param thisWty the weighty for this component
       @param thisFill the fill for this component
       @param thisAnchor the anchor for this component
    */
    
    private void addGB(Component component, 
        int thisX, int thisY, int thisWidth, int thisHt, 
        double thisWtx, double thisWty, int thisFill, int thisAnchor)
    {
        GridBagConstraints gbConstraints = new GridBagConstraints();
      
        gbConstraints.gridx = thisX;
        gbConstraints.gridy = thisY;
        gbConstraints.gridwidth = thisWidth;
        gbConstraints.gridheight = thisHt;
        gbConstraints.weightx = thisWtx;
        gbConstraints.weighty = thisWty;
        gbConstraints.fill = thisFill;
        gbConstraints.anchor = thisAnchor;
        
        this.middlePanel.add(component, gbConstraints);
    }
    
    /**
     * creates a Box set up as desired for LayoutTrio2Panel
     * 
     * @return a Box with a border, and with top, middle, and bottom buttons
     */
        
    private Box setUpLeftBox()
    {   
        Box desiredBox = Box.createVerticalBox();
        desiredBox.setBorder(new TitledBorder(new EtchedBorder(), "I'm a box"));
        
        JButton topButton = new JButton("top");
        topButton.setFont(DISPLAY_FONT);
        desiredBox.add(topButton);
        
        JButton midButton = new JButton("middle");
        midButton.setFont(DISPLAY_FONT);
        desiredBox.add(midButton);
        
        JButton bottomButton = new JButton("bottom");
        bottomButton.setFont(DISPLAY_FONT);
        desiredBox.add(bottomButton);
        
        return desiredBox;
    }
    
    /**
     * set up a middle panel as desired by LayoutTrio2Panel, using a
     * GridBagLayout instance to lay out 7 buttons
     */
        
    private void setUpMiddlePanel()
    {   
        this.middlePanel = new JPanel();
        this.middlePanel.setLayout(new GridBagLayout());
                                            
        // add the component subject to gridbag constraints for each of
        //    several buttons (with the help of a local private method) 
        
        this.addGB(new JButton("Top Left"),
                   0, 0, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
                
        this.addGB(new JButton("Top Right"), 
                   2, 0, 2, 2, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
        
        this.addGB(new JButton("Lower Left"),
                   0, 1, 1, 2, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);

        this.addGB(new JButton("Middle Bottom"),
                   2, 2, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
                   
        this.addGB(new JButton("Right Bottom"),
                   3, 2, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);

        this.addGB(new JButton("x"),
                   1, 0, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
        
        this.addGB(new JButton("y"),
                   1, 1, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
        
        this.addGB(new JButton("z"),
                   1, 2, 1, 1, 100, 100,
                   GridBagConstraints.BOTH, GridBagConstraints.CENTER);
    }
    
    /**
     * set up a right-side JPanel as desired by LayoutTrio2Panel
     *
     * @return a panel using no layout manager (absolute positioning)
     *         with two buttons
     */
        
    private JPanel setUpRightPanel()
    {   
        JPanel desiredPanel = new JPanel();
        desiredPanel.setLayout(null);
        
        JButton mooButton = new JButton("moo");
        desiredPanel.add(mooButton);
        mooButton.setBounds(25, 50, 100, 75);
        
        JButton baaButton = new JButton("baa");
        desiredPanel.add(baaButton);
        baaButton.setBounds(225, 75, 75, 100);
        
        return desiredPanel;
    }
}