import javax.swing.border.BevelBorder; import javax.swing.BorderFactory; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.Spring; import javax.swing.SpringLayout; import javax.swing.SwingConstants; /** This class demonstrates that, with SpringLayout, you can have * borders within a grid, using overlapping components */ public class SpringBorders extends JPanel { public SpringBorders() { guiSetup(); } private void guiSetup() { SpringLayout sl = new SpringLayout(); setLayout(sl); // Four by four grid of Labels to display JLabel[] labels = new JLabel[] { new JLabel("One"), new JLabel("Two"), new JLabel("Three"), new JLabel("Four"), new JLabel("Five"), new JLabel("Six"), new JLabel("Seven"), new JLabel("Eight"), new JLabel("Nine"), new JLabel("Ten"), new JLabel("Eleven"), new JLabel("Twelve"), new JLabel("Thirteen"), new JLabel("Fourteen"), new JLabel("Fifteen"), new JLabel("Sixteen")}; for (int i = 0; i < labels.length; i++) { labels[i].setHorizontalAlignment(SwingConstants.CENTER); add(labels[i]); } // Work out maximum width and height. Using springs for this // makes it work even for components with dynamically changing // widths. Could use different springs to get differing sized // rows and columns. Do this early so we pick up the spring // that shows the component's preferred size Spring maxWidth = null; Spring maxHeight = null; for (int i = 0; i < labels.length; i++) { SpringLayout.Constraints con = sl.getConstraints(labels[i]); if (maxWidth == null) { maxWidth = con.getWidth(); } else { maxWidth = Spring.max(maxWidth, con.getWidth()); } if (maxHeight == null) { maxHeight = con.getHeight(); } else { maxHeight = Spring.max(maxHeight, con.getHeight()); } } // Set up X and Y gaps using fixed size pads for (int i = 0; i < 4; i++) { for (int j = 1; j < 4; j++) { int offset = i * 4 + j; sl.putConstraint(SpringLayout.WEST, labels[offset], 5, SpringLayout.EAST, labels[offset - 1]); } } for (int i = 1; i < 4; i++) { for (int j = 0; j < 4; j++) { int offset = i * 4 + j; sl.putConstraint(SpringLayout.NORTH, labels[offset], 5, SpringLayout.SOUTH, labels[offset - 4]); } } // set all widths to the same spring. Ditto heights // Add a stretchable constant to the width or height spring // so that you can expand and contract the grid Spring widthSpring = Spring.sum(maxWidth, Spring.constant(0, 0, 10000)); Spring heightSpring = Spring.sum(maxHeight, Spring.constant( 0, 0, 10000)); for (int i = 0; i < labels.length; i++) { sl.getConstraints(labels[i]).setWidth(widthSpring); sl.getConstraints(labels[i]).setHeight(heightSpring); } // Link bottom right component to parent Component last = labels[labels.length - 1]; sl.getConstraints(this).setConstraint(SpringLayout.EAST, sl.getConstraints(last).getConstraint(SpringLayout.EAST)); sl.getConstraints(this).setConstraint(SpringLayout.SOUTH, sl.getConstraints(last).getConstraint(SpringLayout.SOUTH)); // Add a Border Panel and link up its position JPanel bp = new JPanel(); add(bp); bp.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); SpringLayout.Constraints sc = sl.getConstraints(bp); SpringLayout.Constraints lrc = sl.getConstraints(labels[10]); // Set north and east first because of rules about overconstrained // components sc.setConstraint(SpringLayout.SOUTH, lrc.getConstraint(SpringLayout.SOUTH)); sc.setConstraint(SpringLayout.EAST, lrc.getConstraint(SpringLayout.EAST)); SpringLayout.Constraints ulc = sl.getConstraints(labels[5]); sc.setConstraint(SpringLayout.NORTH, ulc.getConstraint(SpringLayout.NORTH)); sc.setConstraint(SpringLayout.WEST, ulc.getConstraint(SpringLayout.WEST)); } public static void main(String[] s) { JFrame jf = new JFrame(); Container cp = jf.getContentPane(); cp.setLayout(new BorderLayout()); SpringBorders sp = new SpringBorders(); cp.add(sp, BorderLayout.CENTER); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.show(); } }