The sources for the Blox tutorial demos.
/*
 *    BloxDemoMenu - 
 */
package blox.tutorial;

import com.physpics.tools.RunDemos;

public class BloxDemoMenu extends RunDemos {
    public BloxDemoMenu() {
        super();
    }
    public static void main(String[] args) {
        BloxDemoMenu menu = new BloxDemoMenu();
        menu.addDemo("blox.tutorial.BloxHorizontalDemo");
        menu.addDemo("blox.tutorial.BloxTest");
        menu.addDemo("blox.tutorial.BloxVerticalDemo");
        menu.addDemo("blox.tutorial.FirstBloxExample");
        menu.addDemo("blox.tutorial.FirstBloxLongForm");
        menu.addDemo("blox.tutorial.Nausithoe");
        menu.addDemo("blox.tutorial.OrientedMatrices");
        menu.addDemo("blox.tutorial.SimpleMatrix");
        menu.showMenu();
    }
}

BloxHorizontalDemo.java


package blox.tutorial;

import com.physpics.tools.ui.blox.Blox;
import com.physpics.tools.ui.blox.BloxLayout;
import java.awt.*;
import javax.swing.*;

/** Illustrate creating a horizontal layout with Blox*/
public class BloxHorizontalDemo {
    static final Color THIN_RED_LINE = new Color(0x44ff0000, true);
    static final Color THIN_BLUE_LINE = new Color(0x440000ff, true);
    
    /**
     * Construct a Component to demonstrate vertical alignment 
     * in Horizontal Bloxes. The Component will be a JPanel containing an
     * inner text or some other Component.
     * 
     * (The outer component is actually a horizontal Blox; tht way we can
     * use vertical alignment within it to p;ace the inner component.)
     * 
     * @param height the height of the outer Component 
     * @param alignY the alignmentY value for the inner Component.
     *          This value will also drive the background color 
     *          of the inner component.
     * @param inside if null, the inner component is a JLabel; if not null
     *          the value itself will be the inner component.
     * @return A Component as described.
     */
    static Blox horBlox(int height, double alignY, JComponent inside) {
        // create or tailor the inside component
        if (inside == null)
            inside = new JLabel("al.Y="+alignY);
        inside.setAlignmentY((float) alignY); 
        inside.setBackground(Color.YELLOW);
        inside.setOpaque(true);

        // create the outer Blox
        Blox outer = new Blox(BloxLayout.X_AXIS){
            //override paintChilden amd have it
            //  paint the red line after kids
            @Override
            public void paintChildren(Graphics g) {
                super.paintChildren(g);
                int w = getWidth();
                int bl = getBaseline(w, getHeight());
                if (bl == -1) return;
                g.setColor(THIN_RED_LINE);
                g.drawLine(0, bl, w, bl);
            }
        };
        outer.setAlignmentY((float)(alignY*alignY));

        // set height of outer Blox by setting its preferred and max sizes
        Insets vins = outer.getInsets();
        Dimension insideSize = inside.getPreferredSize();
        outer.setPreferredSize(new Dimension(
                insideSize.width +vins.left+vins.right, 
                height+vins.top+vins.bottom));
        outer.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
        
        // add the inner object to the outerBlox
        outer.addMany(
                Blox.color(Color.getHSBColor((float)(alignY*.8+.2), .3f, .9f)),
                Blox.glue(), 
                inside, 
                Blox.glue()); // glue centers the inside
        return outer;
    }
    
    static int nnm = 0; 
    
    static Blox simpleComponents(boolean alignBases) {
        Blox val = new Blox(BloxLayout.X_AXIS){
            @Override
            public void paintChildren(Graphics g) {
                super.paintChildren(g);
                int w = getWidth();
                int bl = getBaseline(w, getHeight());
                if (bl == -1) return;
                g.setColor(THIN_BLUE_LINE);
                g.drawLine(0, bl-1, w, bl-1);
                g.drawLine(0, bl+1, w, bl+1);
            }
        };
        return val.addMany(
//                Blox.name("" + nnm++),
//                Blox.debug(true),
                Blox.baseAlign(alignBases),
                horBlox(50, .20, null),
                new JTextField("JTF"){{
                    setHorizontalAlignment(JTextField.CENTER);
                    setEditable(false);
                }},
                horBlox(70, .80, null),
                new JPanel(){{
                    setPreferredSize(new Dimension(10,10));
                    setBackground(Color.ORANGE);
                    setOpaque(true);
                }}
        );
    }
    public static JFrame[] openWindows() {
        JFrame j1,j2, j3;
        j1 = simpleComponents(true).openWindow("align bases");
        j2 = simpleComponents(false).openWindow("no base align");
        j3 = Blox.createVerticalBlox(
                Blox.glue(),
                horBlox(30,.3, null),
                Blox.glue()
        ).openWindow("horBlox");

        return new JFrame[]{j1, j2, j3};
    }

    public static void main(String[] args) {
        openWindows();
    }
    
}

BloxTest.java


package blox.tutorial;

import com.physpics.tools.ui.blox.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;

/**
 * Simple test for Blox.
 * @author Fred
 */
@SuppressWarnings("serial")
public class BloxTest {
    private static final Dimension DIM20 = new Dimension(20,20);
    private static final Color PALE_TURQUOISE = new Color(0xAA, 0xFF, 0xCC);
    private static final Font DEFAULT_FONT = new JTextArea().getFont();

    static Blox labeledSlider() {
        JLabel lab;
        JSlider sly;
        Blox val = Blox.createHorizontalBlox(
                Blox.baseAlign(false),
                lab = new JLabel("Hue"),
                sly = new JSlider(0, 100, 100)
        );
        lab.setAlignmentY(0.45F);
        sly.setAlignmentY(0.5F);
        return val;
    }
    
    static Blox twoSectionsHorizontal() {
        return Blox.createHorizontalBlox(
            Blox.debug(true),
            Blox.color(Color.GREEN),
            BloxSection.absolute(150),
            new JLabel("label, long"){{
                setBackground(Color.pink);
                setOpaque(true);
            }},
            BloxSection.percent(66),

            new JLabel("left"){{
                setBackground(Color.YELLOW);
                setOpaque(true);
            }},
            Blox.glue(),
            new JLabel("right")
        );
    }
    
    static Blox crossBlox() {
        return Blox.createHorizontalBlox(
            Blox.debug(true),
            Blox.color(Color.GREEN),
            new JLabel("in horizontal"),
            Blox.createVerticalBlox(
                    Blox.debug(true),
                    new JLabel("in vertical")
            )
        );
    }
    static Blox reverseCrossBlox() {
        return Blox.createVerticalBlox(
            Blox.debug(true),
            Blox.name("outer-vert"),
            Blox.color(Color.GREEN),
            new JLabel("in vertical"),
            Blox.createHorizontalBlox(
                    Blox.debug(true),
                    Blox.name("inner-hor"),
                    new JLabel("in horizontal")
            )
        );
    }
    
    static class CenteredLabel extends JLabel {
        static CenteredLabel create(String text){
            CenteredLabel val = new CenteredLabel(text);
            val.setHorizontalAlignment(SwingConstants.CENTER);
            val.setVerticalAlignment(SwingConstants.CENTER);
            val.setBackground(Color.WHITE);
            val.setOpaque(true);
            val.setPreferredSize(DIM20);
            val.setMinimumSize(DIM20);
            return val;
        }
        CenteredLabel(String text) { 
            super(text);
        }
    }
    
    /**
     * Create a box with three JLabels whose strings are 
     * given by the three parameters.
     * @param a Name of 1st JLabel
     * @param b Name of 2nd JLabel
     * @param c Name of 3rd JLabel
     * @return A Blox containing the three JLabels
     */
    private static Blox createRow(String a, String b, String c) {
        Blox val = new Blox(BloxLayout.LINE_AXIS){
            @Override
            public void paintChildren(Graphics g) {
                super.paintChildren(g);
            }
        };
        JLabel left = CenteredLabel.create(a);
        JLabel center = CenteredLabel.create(b);
        JLabel right = CenteredLabel.create(c);

        JComponent brownStrut = Blox.strut(4);
        brownStrut.setBackground(new Color(0xB5651D));
        brownStrut.setOpaque(true);
        brownStrut.setName("brownie");
        
        val.addMany(
            Blox.crossSizeFull(true),
            Blox.color(PALE_TURQUOISE),
            left, Blox.strut(4), center, brownStrut, right);
        return val;
    }
    
    private static Blox matrix(String name) {
        // create the rectangular matrix with chosen orientation
        Blox matbox = new Blox(BloxLayout.PAGE_AXIS).addMany(
            Blox.name("matbox#"+name),
//            Blox.crossSizeFull(true),
            createRow("A", "B", "C").addMany(Blox.name(name+"#ABC")),
            Blox.strut(4),
            createRow("D", "E", "F").addMany(Blox.name(name+"#DEF")),
            Blox.strut(4),
            createRow("G", "H", "I").addMany(Blox.name(name+"#GHI")));
        return matbox;
    }
    
    /**
     * Construct a box with a given orientation and contents to exemplify
     * the orientation. The returned box will be vertical with a label 
     * on top describing the orientation. A bottom box will contain 
     * three boxes along one axis each of which contains three boxes
     * on the other axis. In orientation (true,true) the contents will be  
     *      A B C
     *      D E F
     *      G H I
     * @param ltr True for left-to-right
     * @param hor True for horizontal
     * @return a Blox as described.
     */
    private static Blox orientedBlox(boolean ltr, boolean hor) {
        String oName = (hor
                ? (ltr ? "LtoR-Hor" : "RtoL-Hor")
                : (ltr ? "LtoR-Vert" : "RtoL-Vert"));
        Blox matbox = matrix(oName);
        matbox.setAlignmentX(Component.CENTER_ALIGNMENT);

        // create entire box with title above matrix
        JLabel title = new JLabel(oName){{
            setAlignmentX(CENTER_ALIGNMENT);
        }};
        
        // long form constructor so we can implement baseine
        Blox val = new Blox(BloxLayout.Y_AXIS){
            @Override
            public int getBaseline(int w, int h) {
                return 10;
            }
        }.addMany(
            Blox.name(oName),
            Blox.glue(),
            title,
            matbox,
            Blox.glue());
        val.applyComponentOrientation(
                Blox.componentOrientationFactory(ltr, hor));
        return val;
    }

    static Blox multiView() {
            final float baseAlignment = 0.30F;
            
            // contents for "yellowbox" 
            final JLabel f0 = new JLabel("invisible");
            f0.setVisible(false);
            JTextField f1 = new JTextField("field 1");
            f1.setMaximumSize(new Dimension(150, Short.MAX_VALUE));
            JTextField f2 = new JTextField("field 2");
            f2.setAlignmentX(0.9F);
            f2.setMaximumSize(new Dimension(150, Short.MAX_VALUE));
            JTextArea area = new JTextArea("area ", 3, 20);
            JScrollPane scrarea = new JScrollPane(area);
            scrarea.setMinimumSize(new Dimension(300, 50));
            scrarea.setName("scrarea");
            
            // construct "yellowbox"
            Blox yellowbox = new Blox(BloxLayout.Y_AXIS){{
                    setName("yellowbox");
                    setAlignmentY(baseAlignment);
                }
                @Override
                public int getBaseline(int w, int h) {
                    return 100;
                }
            };
            yellowbox.addMany(
                    Blox.color(Color.YELLOW),
                    f0,
                    Blox.crossSizeFull(true),
                    f1,
                    Blox.crossSizeFull(false),
                    f2,
                    new JTextField("field 3") {{ 
                        setColumns(15);   // sets preferred size
                        // maximum above preferred size is ignored
                        setMaximumSize(new Dimension(300,200));
                        setAlignmentX(Component.RIGHT_ALIGNMENT);
                    }},
                    new JTextField("field 4"),
                    scrarea,
                    Blox.strut(10),
                    new JButton("Toggle invisible field 0"){{ 
                        setAlignmentX(0.3F);
                        addActionListener((ActionEvent e) -> {
                            f0.setVisible( ! f0.isVisible());
                        });
                    }},
                    Blox.glue()
            );
            yellowbox.setMaximumSize(new Dimension(300,200));
            yellowbox.setPreferredSize(new Dimension(250,200));
            yellowbox.setMinimumSize(new Dimension(200,200));

            // an outer box containing "yellowbox" and four orientedBoxes
            return Blox.createHorizontalBlox(
                    Blox.name("box-outer"),
                    yellowbox, Blox.strut(20),
                    orientedBlox(true, true), Blox.strut(10),
                    orientedBlox(false, true), Blox.strut(10),
                    orientedBlox(true, false), Blox.strut(10),
                    orientedBlox(false, false), Blox.glue());
    }

    static Blox thinAndMain() {
        return Blox.createVerticalBlox(
                Blox.debug(true),
                BloxSection.thin(),
                    new JLabel("Header area"),
                    Blox.createHorizontalBlox(
                            Blox.name("bltest"),
                            Blox.color(PALE_TURQUOISE),
                            Blox.debug(true),
                            new JLabel("baseline test"){{
                                setBackground(Color.pink);
                                setOpaque(true);
                                setAlignmentY(0.1f);
                            }},
                            Blox.strut(6),
                            new JTextField("text field"){{
                                setFont(new Font("Serif", Font.BOLD, 20));
                                setPreferredSize(new Dimension(91, 40));
                            }},
                            Blox.strut(6),
                            new JButton("button"),
                            Blox.strut(6),
                            matrix("force baseline to use alignment")
                    ),
                BloxSection.absolute(100),
                    Blox.glue(),
                    matrix("abs100"),
                    Blox.glue(),
                BloxSection.main(),
                    Blox.crossSizeFull(true),
                    new JScrollPane(
                        new JTextArea("the main text area"),
                            JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER){{
                                setMinimumSize(DIM20);
                            }},
                    Blox.crossSizeFull(false),
                BloxSection.thin(),
                    new JButton("Submit"){{
                        setAlignmentX(CENTER_ALIGNMENT);
                    }},
                    new JTextField("Copyright "){{
                        setColumns(20);
                        setAlignmentX(RIGHT_ALIGNMENT);
                    }}
        );
    }    
    
    static JScrollPane debugScrollPane(final String where) {
        return new JScrollPane(new JTextArea(1,15)){
            { setName("scroll "+where); }
            @Override
            public int getBaseline(int w, int h) {
                int bl = super.getBaseline(w, h);
                System.out.println("JS baseline at " + where +": " + bl);
                return bl;
            }
        };
    }
    
    static public Blox makeBloxWithoutMargins() {
        return Blox.createVerticalBlox(
                Blox.name("withoutMargins"),
                    Blox.debug(true),
            new JLabel("How do you do it?"),
            Blox.crossSizeFull(true),
            //* make a row:
                debugScrollPane("withOUT margins"),
//            Blox.createHorizontalBlox(  // Chocolate2
//                    Blox.debug(true),
//                Blox.color(new Color(0x7B3F00)), 
//                Blox.strut(8),  // left space
//                new JScrollPane(
//                    new JTextArea(1, 15)),
//                Blox.strut(8)   // right space
//            ),
            Blox.crossSizeFull(false),  
            Blox.createHorizontalBlox(
                new JButton("Submit"),
                new JButton("Cancel")
            )
        );
    }

    static public Blox makeBloxWithMargins() {
        return Blox.createVerticalBlox(
                Blox.name("withMargins"),
                    Blox.debug(true),
            new JLabel("How do you do it?"),
            Blox.crossSizeFull(true),
//                new JScrollPane(
//                    new JTextArea(1, 15)),
            //* make a row:
            Blox.createHorizontalBlox(  // Chocolate2
                    Blox.debug(true),
                Blox.color(new Color(0x7B3F00)), 
                Blox.strut(8),  // left space
                debugScrollPane("with margins"),
                Blox.strut(8)   // right space
            ),
            Blox.crossSizeFull(false),  
            Blox.createHorizontalBlox(
                new JButton("Submit"),
                new JButton("Cancel")
            )
        );
    }

    /**
     * Create a vertical Blox with glue/text/glue.
     * The baseline can be adjusted by choosing different font sizes.
     * @param text  the text to display 
     * @param points integer point size for text
     * @param glue if true, wrap the result 
     *      in a blox with glue at top and bottom
     * @return a Blox as described above
     */
    static public JComponent textInGlue(String text, int points, 
            boolean glue) {
        JTextField tf = new JTextField(text);
        tf.setFont(new Font(DEFAULT_FONT.getFamily(),Font.PLAIN,points));
        tf.setText("base "+tf.getBaseline(10, points));
        
        if ( ! glue) 
            return tf;
        
        return Blox.createVerticalBlox(
                Blox.color(Color.yellow),
            Blox.createGlue(),
            tf,
            Blox.createGlue());
    }
    
    /**
     * a horizontal row where the elements are glue/text/glue.
     * Will the baselines align??
     * @param addGlue if true, wrap each line  
     * in a blox with glue above and below
     * @return  a horizontal row
     */
    static public Blox baselineAndGlue(boolean addGlue) {
        return Blox.createHorizontalBlox(
                Blox.baseAlign(true),
                Blox.crossSizeFull(true),
            textInGlue("small text", 8, addGlue),
            textInGlue("medium text", 16, addGlue),
            textInGlue("big text", 28, addGlue)
        );
    }

    public static JFrame[] openWindows() {
        JFrame j1,j2;
        j1 = baselineAndGlue(false).openWindow("Baselines vs Glue");
        j2 = baselineAndGlue(true).openWindow("Baselines vs Glue");

        return new JFrame[]{j1, j2};
    }

    public static void main(String[] args) {
        openWindows();
    }
}
    

BloxVerticalDemo.java


package blox.tutorial;

import com.physpics.tools.ui.blox.Blox;
import java.awt.*;
import javax.swing.*;

/** Demonstrate creating a vertical layout with Blox */
public class BloxVerticalDemo {
    static final Color ICTERINE = new Color(0xFCF75E); 
    
    static Blox simpleComponents(boolean fullWidth) {
        return Blox.createVerticalBlox(Blox.crossSizeFull(fullWidth),
                new JLabel("JLabel"),
                new JButton("JButton"),
                new JComboBox<>(new Object[]{"JComboBox", "Second Choice"}),
                new JMenuItem("JMenuItem"),
                new JTextField("JTextField"){{
                    setBackground(ICTERINE);
                }},
                new JProgressBar(0,100){{
                    setIndeterminate(true);
                    setBackground(Color.GREEN);
                }},
                new JSlider(-10,10,3),
                new JSpinner(new SpinnerDateModel())
        );
    }

    
    static JTextField aJText(double align) {
        JTextField val = new JTextField("align "+ align);
        val.setAlignmentX((float) align);
        val.setBackground(Color.getHSBColor((float)(align*.6+.2), .3f, .9f));
        return val;
    }
    static Blox varyAlignment() {
        // return a vertical stack of JTextFields
        return Blox.createVerticalBlox(
                aJText(0.0),
                aJText(0.1),
                aJText(0.5),
                aJText(0.65),
                aJText(1.0)
        );
    }
    
    static JTextField textField(int columns) {
        JTextField val = new JTextField(columns);
        val.setBackground(ICTERINE);
        val.setText("columns("+columns+")");
        return val;
    }
    static Blox textWidths() {
        return Blox.createVerticalBlox(
                new JTextField("default width"),
                new JTextField("Dim(75,25)"){{
                    setPreferredSize(new Dimension(75,25));
                }},
                textField(5),
                textField(6),
                textField(7),
                new JTextField("8 at right"){{
                    setHorizontalAlignment(JTextField.RIGHT);
                    setColumns(8);
                }}
        );
    }
    public static JFrame[] openWindows() {
        JFrame j1,j2,j3,j4;

        j1 = simpleComponents(false).openWindow("Default alignments");
        j2 = varyAlignment().openWindow("Various alignments");
        j3 = simpleComponents(true).openWindow("Full widths");
        j4 = textWidths().openWindow("Text widths");
        return new JFrame[]{j1, j2, j3, j4};
    }

    public static void main(String[] args) {
        openWindows();
    }
}

FirstBloxExample.java


package blox.tutorial;
import com.physpics.tools.ui.blox.*;
import java.awt.Color;
import javax.swing.*;

/** A first example of layout with Blox. */
public class FirstBloxExample {
    Color cream = new Color(0xFFFDD0);
    JComponent strut10() {
        return Blox.strut(Blox.pointsToPixels(10));
    }
    JComponent textArea() {
        JTextArea area = new JTextArea(1, 15);
        area.setBackground(cream);
        return new JScrollPane(area);
    }
    JComponent buttons() {
        return
            Blox.createHorizontalBlox( 
                new JButton("Submit"), 
                strut10(),
                new JButton("Cancel")
            );
    }
    
    public Blox makeBlox() {
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            textArea(),
            Blox.createHorizontalBlox(
                new JButton("Submit"),
                new JButton("Cancel")
            )
        );
    } 
        
    public Blox makeBloxWithStrut() {
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            textArea(),
            buttons()
        );
    }   

    public Blox makePinkBlox() {
        return Blox.createVerticalBlox(
            Blox.color(Color.pink),
            new JLabel("How do you do it?"),
            textArea(),
            buttons()
        );
    } 

    public Blox makeBloxCrossFull() {
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            // stretch JTextArea to full width:
            Blox.crossSizeFull(true),       
            textArea(),
            Blox.crossSizeFull(false),       
            buttons()
        );
    } 
        
    public Blox makeBloxWithBorder() {
        JComponent textScroll = textArea();
        textScroll.setBorder(BorderFactory
            .createEmptyBorder(0, 10, 0, 10));
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            Blox.crossSizeFull(true),
            textScroll,
            Blox.crossSizeFull(false),
            buttons()
        );
    }   

    public Blox makeTextRows() {
        return Blox.createVerticalBlox(
            Blox.crossSizeFull(true),
            Blox.createHorizontalBlox(  
                Blox.color(Color.CYAN),
                new JScrollPane(new JTextArea(1, 15))
            )
        );
    }
    
    public Blox makeBloxWithMargins() {
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            Blox.crossSizeFull(true),
            //* make a row:
            Blox.createHorizontalBlox(  
                Blox.color(Color.CYAN),
                strut10(),
                textArea(),
                strut10()
            ),
            Blox.crossSizeFull(false),  
            buttons()
        );
    }
    
    public Blox makeBloxElastic() {
        return Blox.createVerticalBlox(
            new JLabel("How do you do it?"),
            Blox.crossSizeFull(true),
            Blox.createHorizontalBlox(
                // enable crossSizeFull:
                Blox.baseAlign(false),   
                // stretch to full height:
                Blox.crossSizeFull(true),
                strut10(),
                textArea(),
                strut10()
            ),
            Blox.crossSizeFull(false),
            buttons()
        );
    }   
    public static JFrame[] openWindows() {
        JFrame j1, j2, j3, j4, j5, j6, j7, j8, j9;
        FirstBloxExample x1 = new FirstBloxExample();
        j2 = x1.makeBlox().openWindow("Blox #1");
        j3 = x1.makeBloxWithStrut().openWindow("Strut #1");
        j4 = x1.makePinkBlox().openWindow("Pink #1");
        j5 = x1.makeBloxCrossFull().openWindow("crossSizeFull");
        j6 = x1.makeBloxWithBorder().openWindow("Border #1");
        j7 = x1.makeBloxWithMargins().openWindow("Margins #1");
        j8 = x1.makeBloxElastic().openWindow("Elastic #1");
        j9 = x1.makeTextRows().openWindow("text area");
        
        return new JFrame[]{j2, j3, j4, j5, j6, j7, j8, j9};
    }

    public static void main(String[] args) {
        openWindows();
    }
}

FirstBloxLongForm.java


package blox.tutorial;
import com.physpics.tools.ui.blox.*;
import javax.swing.*;

/**Doing the first Blox example the hard way.  */
public class FirstBloxLongForm {
    public JPanel makeBlox() {
        JPanel val = new JPanel();
        val.setLayout(new BloxLayout(val, 
                BloxLayout.Y_AXIS));
        val.add(new JLabel("How do you do it?"));
        val.add(new JScrollPane(
                new JTextArea(1, 15)));
        JPanel buttons = new JPanel();
        buttons.setLayout(new BloxLayout(buttons, BloxLayout.X_AXIS));
        buttons.add(new JButton("Submit"));
        buttons.add(new JButton("Cancel"));
        
        val.add(buttons);
        return val;
    }   
        public static JFrame[] openWindows() {
        JFrame j1;
        JPanel contents = new FirstBloxLongForm().makeBlox();
        j1 = Blox.createVerticalBlox(contents)
                .openWindow("Long Form Blox One");

        return new JFrame[]{j1};
    }

    public static void main(String[] args) {
        openWindows();
    }
}

Nausithoe.java


package blox.tutorial;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import com.physpics.tools.ui.blox.*;
import com.sun.glass.events.KeyEvent;
import java.awt.Toolkit;

/**
 * Demonstrate how to have four sections meet at a point.
 * @author Fred
 */
public class Nausithoe {
    // app with four quarters done with Bloxes
    JLabel bloxImage;
    BloxSection bloxBlue;
    BloxSection bloxOrange;
    Blox bloxButtons;
    BloxSection buttonsSection;
    JellyButton bloxFirstButton;

    /**
     * Create a Blox with four sections that will meet at a point.
     * @return As described
     */
    public Blox blox() {
        Blox val = Blox.createVerticalBlox(
            Blox.glue(),   // center vertically
            Blox.createHorizontalBlox(
                Blox.crossSizeFull(true),  // full height
                BloxSection.thin(),
                bloxImage = new JLabel(),
                bloxOrange = BloxSection.absolute(100),
                coloredPane(Color.ORANGE)
            ),
            Blox.createHorizontalBlox(
                Blox.crossSizeFull(true),
                bloxBlue = BloxSection.absolute(100),
                coloredPane(Color.BLUE),
                
                buttonsSection = BloxSection.thin(),
                Blox.strut(12),
                bloxFirstButton = bloxButtonCreate(
                            "N. racemosa",
                            "http://thescyphozoan.ucmerced.edu/Syst/Cor"
                                    + "/Nausithoe_racemosa_i.html",
                            "images/NausithoeRacemosa.jpg"),
                Blox.strut(12),
                bloxButtonCreate("N. punctata",
                            "http://www.whoi.edu/page.do?pid=80696&i=13122",
                            "images/graphics-Jellyfish-6_131075.jpg"),
                Blox.strut(12)
            ),
            Blox.glue()    // center vertically
        );

        // click the left button
        bloxFirstButton.ear.actionPerformed(
            new ActionEvent(bloxFirstButton, ActionEvent.ACTION_PERFORMED, null));
              
        return val;
    }   

    
    JellyButton bloxButtonCreate(String name, String link, String file) {
        return new JellyButton(name, link, file, 
            (ActionEvent e)->{ 
                bloxImage.setBackground(Color.GREEN);
                // load image
                bloxImage.setIcon(((JellyButton)e.getSource()).img); 
                
                // set size of blue box based on size of image[index]
                int w = bloxImage.getPreferredSize().width;
                bloxBlue.setExtent(w);
                // set width of orange box based on width of buttons
                w = (int)buttonsSection.getExtent();
                bloxOrange.setExtent(w);
        }).init();
    }
    
    JPanel coloredPane(Color col) {
        JPanel val = new JPanel();
        val.setBackground(col);
        val.setBorder(null);
        return val;
    }
    
    
    //GridBagConstraints             comment               default
    // int gridx*, gridy*          location of top left  0,0   
    // int gridwidth*, gridheight* span                  1,1
    // double weightx, weighty     resize weight         .5,.5
    // int anchor                  alignment             GBConstraints.CENTER
    // int fill                    full-size directions  GBConstraints.BOTH
    // Insets insets               external padding      0,0,0,0
    // int ipadx, ipady            internal padding      0,0
    //       * is a parameter to setGBC
    
    GridBagConstraints setGBC(GridBagConstraints gbc, 
            int row, int col, int rowspan, int colspan) {
        gbc.gridy = row;
        gbc.gridx = col;
        gbc.gridheight = rowspan;
        gbc.gridwidth = colspan;
        return gbc;
    }
    
    // same app implemented with a GridBagLayout
    JLabel gbImage;
    JPanel gbBlueBox;
    JellyButton gbFirstButton;
    JPanel gridbag() {
        JPanel val = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        val.add(gbImage = new JLabel(), setGBC(gbc,0,0,1,1));
        gbFirstButton = gbButtonCreate("N. Racemosa",
                    "http://thescyphozoan.ucmerced.edu/Syst/Cor"
                            + "/Nausithoe_racemosa_i.html",
                    "images/NausithoeRacemosa.jpg");
        gbc.ipadx = 25;
        val.add(gbFirstButton, setGBC(gbc,1,1,1,1));
        JellyButton secondJB = gbButtonCreate("N. punctata",
                    "http://www.whoi.edu/page.do?pid=80696&i=13122",
                    "images/graphics-Jellyfish-6_131075.jpg");
        val.add(secondJB, setGBC(gbc,1,2,1,1));
        gbc.ipadx = 0;
        gbc.fill = GridBagConstraints.BOTH;
        val.add(coloredPane(Color.ORANGE), setGBC(gbc,0,1,1,2));
        val.add(gbBlueBox = coloredPane(Color.BLUE), setGBC(gbc,1,0,1,1));

        // click the left button
        gbFirstButton.ear.actionPerformed(
            new ActionEvent(gbFirstButton, ActionEvent.ACTION_PERFORMED, null));
        return val;
    }
    
    JellyButton gbButtonCreate(String name, String link, String file) {
        return new JellyButton(name, link, file, (ActionEvent e)->{
            Icon img = ((JellyButton)e.getSource()).img;
            gbImage.setIcon(img); // load image
                // set size of blue box Section based on size of image[index]
                int imgW = img.getIconWidth();
                gbBlueBox.setPreferredSize(
                    new Dimension(imgW, gbFirstButton.getPreferredSize().height));
        }).init();
    }
    
    class JellyButton extends JButton {
        Icon img;
        String location;
        ActionListener ear;
        JellyButton(String name, String link, String file, ActionListener aListen) {
            super(name);   // button text
            ear = aListen;
            try {
                img = new ImageIcon(ImageIO.read(getClass().getResource(file)));
            } catch (IOException ex) {
                System.out.println("cannot find " + file);
            }
            location = link;
        }
        JellyButton init() {
            setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.LIGHT_GRAY),
                BorderFactory.createEmptyBorder(2,2,2,2)
            ));
            addActionListener(ear);
            return this;
        }
    }
    
    public static JFrame[] openWindows() {
        Nausithoe naus = new Nausithoe();
        Blox nblox = naus.blox();
        nblox.wrapFrame(null, "Nausithoe");
        nblox.openWindow(null, 332, 130);
        Blox gbagblox = Blox.createVerticalBlox(naus.gridbag());
        gbagblox.openWindow(
                gbagblox.wrapFrame(null, "Nausithoe gridbag"),
                332,130);
        JFrame g = gbagblox.getFrame();
        JMenuBar bar = new JMenuBar();
        JMenu m = new JMenu("File");
        JMenuItem item = new JMenuItem("Hello");
        item.addActionListener(e->{Toolkit.getDefaultToolkit().beep();});
        m.add(item);
        bar.add(m);

        m.setMnemonic(KeyEvent.VK_F);
        item.setMnemonic(KeyEvent.VK_H);
        m.setDisplayedMnemonicIndex(0);
        item.setDisplayedMnemonicIndex(0);
        g.setJMenuBar(bar);
        return new JFrame[]{nblox.getFrame(), g};
    }

    
    public static void main(String[] args) {
        openWindows();
    }
}

OrientedMatrices.java


package blox.tutorial;

import com.physpics.tools.ui.blox.*;
import java.awt.*;
import javax.swing.*;

/** Illustrate the effects of orientation on a Blox layout */
public class OrientedMatrices extends Blox {
    static final Dimension DIM20 = new Dimension(20,20);
    static final Color BKGD = new Color(0xCCFFBB);  // PalePastelGreen
    static final int FOUR_POINTS = Blox.pointsToPixels(4);

    static class CenteredLabel extends JLabel {
        static CenteredLabel create(String text) {    
            CenteredLabel obj = new CenteredLabel(text);
            obj.setBackground(Color.WHITE);
            obj.setOpaque(true);
            obj.setHorizontalAlignment(SwingConstants.CENTER);
            obj.setPreferredSize(DIM20);        
            return obj; 
        }
        CenteredLabel(String text) { 
            super(text);
        }
    }
    
    Blox createRow(String a, String b, String c) {
        return new Blox(BloxLayout.LINE_AXIS)
            .addMany(Blox.color(BKGD), Blox.strut(FOUR_POINTS), 
                CenteredLabel.create(a), Blox.strut(FOUR_POINTS), 
                CenteredLabel.create(b), Blox.strut(FOUR_POINTS), 
                CenteredLabel.create(c), Blox.strut(FOUR_POINTS));
    }
    Blox matrix() {
        return new Blox(BloxLayout.PAGE_AXIS)
            .addMany(
                Blox.color(BKGD), Blox.strut(FOUR_POINTS),
                createRow("A", "B", "C"), Blox.strut(FOUR_POINTS),
                createRow("D", "E", "F"), Blox.strut(FOUR_POINTS),
                createRow("G", "H", "I"), Blox.strut(FOUR_POINTS));
    }
    
    /**
     * Construct a Blox with contents to exemplify an orientation. 
     * The returned box will be vertical with a label 
     * on top describing the orientation and below that a matrix.
     * The matrix has three boxes along one axis,
     * each of which contains three boxes on the other axis. 
     * In orientation (true,true) the matrix looks like
     *      A B C
     *      D E F
     *      G H I
     * @param ltr True for left-to-right
     * @param hor True for horizontal
     * @return a Blox as described.
     */
    Blox matrixDemo(boolean ltr, boolean hor) {
        JLabel heading = new JLabel((ltr ? "LtoR" : "RtoL")
                            + (hor ? "-Hor" : "-Vert"));
        heading.setAlignmentX(Component.CENTER_ALIGNMENT);
        Blox mat = matrix();
        mat.applyComponentOrientation(
                Blox.componentOrientationFactory(ltr, hor));
        return Blox.createVerticalBlox(
                heading,
                Blox.strut(6),
                mat,
                Blox.glue());
    }

    OrientedMatrices() {    // subclass of Blox
        super(BloxLayout.X_AXIS);
    }
    static OrientedMatrices create() {
        OrientedMatrices val = new OrientedMatrices();
        val.addMany(Blox.glue(),
            val.matrixDemo(true, true), Blox.strut(10),
            val.matrixDemo(false, true), Blox.strut(10),
            val.matrixDemo(true, false), Blox.strut(10),
            val.matrixDemo(false, false), Blox.glue()
        );
        return val;
    }
    public static JFrame[] openWindows() {
        JFrame j1;
        j1 = OrientedMatrices.create().openWindow("Four Blox Matrices");
        return new JFrame[]{j1};
    }

    public static void main(String[] args) {
        openWindows();
    }
}

SimpleMatrix.java


package blox.tutorial;
import com.physpics.tools.ui.blox.*;
import java.awt.*;
import javax.swing.*;

/** Illustrate creating a matrix layout with Blox. */
public class SimpleMatrix {
    static final Dimension DIM20 
            = new Dimension(Blox.pointsToPixels(20), 
                    Blox.pointsToPixels(20));
    static final Color BKGD = new Color(0xCCFFBB);
    JLabel centeredLabel(String letter) {
        JLabel lab = new JLabel(letter);
        lab.setHorizontalAlignment(
                SwingConstants.CENTER);
        lab.setPreferredSize(DIM20);
        lab.setBackground(BKGD);
        lab.setOpaque(true);
        return lab;
    }
    Blox row(String a, String b, String c) {
        return Blox.createHorizontalBlox(
            centeredLabel(a), 
            centeredLabel(b), 
            centeredLabel(c)
        );
    }
    Blox matrix() {
        return Blox.createVerticalBlox(
            row("A", "B", "C"), 
            row("D", "E", "F"), 
            row("G", "H", "I")
        );
    }
    public static JFrame[] openWindows() {
        JFrame j1;
        j1 = new SimpleMatrix().matrix()
                .openWindow("Matrix");
        return new JFrame[]{j1};
    }

    public static void main(String[] args) {
        openWindows();
    }
}