Java tutorial
//Send questions, comments, bug reports, etc. to the authors: //Rob Warner (rwarner@interspatial.com) //Robert Harris (rbrt_harris@yahoo.com) import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.*; /** * This class contains a BorderLayout, which is loosely patterned after the old * AWT BorderLayout. It uses the <code>BorderData</code> class to determine * positioning of controls. To position controls, call <code>control.setLayoutData()</code>, * passing the <code>BorderData</code> of your choice. * * For example: * * <code> * shell.setLayoutData(new BorderLayout()); * Button button = new Button(shell, SWT.PUSH); * button.setLayoutData(BorderData.NORTH); * </code> * * Note that you can add as many controls to the same direction as you like, but * the last one added for the direction will be the one displayed. */ class YetAnotherBorderLayout extends Layout { private Control north; private Control south; private Control east; private Control west; private Control center; /** * Computes the size for this BorderLayout. * * @param composite the composite that contains the controls * @param wHint width hint in pixels for the minimum width * @param hHint height hint in pixels for the minimum height * @param flushCache if true, flushes any cached values * @return Point * @see org.eclipse.swt.widgets.Layout#computeSize(org.eclipse.swt.widgets.Composite, * int, int, boolean) */ protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { getControls(composite); int width = 0, height = 0; // The width is the width of the west control // plus the width of the center control // plus the width of the east control. // If this is less than the width of the north // or the south control, however, use the largest // of those three widths. width += west == null ? 0 : getSize(west, flushCache).x; width += east == null ? 0 : getSize(east, flushCache).x; width += center == null ? 0 : getSize(center, flushCache).x; if (north != null) { Point pt = getSize(north, flushCache); width = Math.max(width, pt.x); } if (south != null) { Point pt = getSize(south, flushCache); width = Math.max(width, pt.x); } // The height is the height of the north control // plus the height of the maximum height of the // west, center, and east controls // plus the height of the south control. height += north == null ? 0 : getSize(north, flushCache).y; height += south == null ? 0 : getSize(south, flushCache).y; int heightOther = center == null ? 0 : getSize(center, flushCache).y; if (west != null) { Point pt = getSize(west, flushCache); heightOther = Math.max(heightOther, pt.y); } if (east != null) { Point pt = getSize(east, flushCache); heightOther = Math.max(heightOther, pt.y); } height += heightOther; // Respect the wHint and hHint return new Point(Math.max(width, wHint), Math.max(height, hHint)); } /** * This does the work of laying out our controls. * * @see org.eclipse.swt.widgets.Layout#layout(org.eclipse.swt.widgets.Composite, * boolean) */ protected void layout(Composite composite, boolean flushCache) { getControls(composite); Rectangle rect = composite.getClientArea(); int left = rect.x, right = rect.width, top = rect.y, bottom = rect.height; if (north != null) { Point pt = getSize(north, flushCache); north.setBounds(left, top, rect.width, pt.y); top += pt.y; } if (south != null) { Point pt = getSize(south, flushCache); south.setBounds(left, rect.height - pt.y, rect.width, pt.y); bottom -= pt.y; } if (east != null) { Point pt = getSize(east, flushCache); east.setBounds(rect.width - pt.x, top, pt.x, (bottom - top)); right -= pt.x; } if (west != null) { Point pt = getSize(west, flushCache); west.setBounds(left, top, pt.x, (bottom - top)); left += pt.x; } if (center != null) { center.setBounds(left, top, (right - left), (bottom - top)); } } protected Point getSize(Control control, boolean flushCache) { return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache); } protected void getControls(Composite composite) { // Iterate through all the controls, setting // the member data according to the BorderData. // Note that we overwrite any previously set data. // Note also that we default to CENTER Control[] children = composite.getChildren(); for (int i = 0, n = children.length; i < n; i++) { Control child = children[i]; BorderData borderData = (BorderData) child.getLayoutData(); if (borderData == BorderData.NORTH) north = child; else if (borderData == BorderData.SOUTH) south = child; else if (borderData == BorderData.EAST) east = child; else if (borderData == BorderData.WEST) west = child; else center = child; } } } //Send questions, comments, bug reports, etc. to the authors: //Rob Warner (rwarner@interspatial.com) //Robert Harris (rbrt_harris@yahoo.com) public class BorderLayoutTest { public static void main(String[] args) { Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new YetAnotherBorderLayout()); Button b1 = new Button(shell, SWT.PUSH); b1.setText("North"); b1.setLayoutData(BorderData.NORTH); Button b2 = new Button(shell, SWT.PUSH); b2.setText("South"); b2.setLayoutData(BorderData.SOUTH); Button b3 = new Button(shell, SWT.PUSH); b3.setText("East"); b3.setLayoutData(BorderData.EAST); Button b4 = new Button(shell, SWT.PUSH); b4.setText("West"); b4.setLayoutData(BorderData.WEST); Button b5 = new Button(shell, SWT.PUSH); b5.setText("Center"); b5.setLayoutData(BorderData.CENTER); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } }