SWT(JFace)体验之模拟BorderLayout布局时间:2022-11-11 16:30:26SWT中没有AWT的BorderLayout布局管理器。下面是SWT下的自定义实现: BorderLayout.java package swt_jface.demo2; 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; public class BorderLayout extends Layout { public static final int NORTH = 0; public static final int SOUTH = 1; public static final int CENTER = 2; public static final int EAST = 3; public static final int WEST = 4; public static class BorderData { public int region = CENTER; public BorderData() { } public BorderData(int region) { this.region = region; } } public Control[] controls = new Control[5]; Point[] sizes; int width; int height; protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { if (sizes == null || flushCache == true) refreshSizes(composite.getChildren()); int w = wHint; int h = hHint; if (w == SWT.DEFAULT) w = width; if (h == SWT.DEFAULT) h = height; return new Point(w, h); } protected void layout(Composite composite, boolean flushCache) { if (flushCache || sizes == null) refreshSizes(composite.getChildren()); Rectangle clientArea = composite.getClientArea(); if (controls[NORTH] != null) { controls[NORTH].setBounds( clientArea.x, clientArea.y, clientArea.width, sizes[NORTH].y); } if (controls[SOUTH] != null) { controls[SOUTH].setBounds( clientArea.x, clientArea.y + clientArea.height - sizes[SOUTH].y, clientArea.width, sizes[SOUTH].y); } if (controls[WEST] != null) { controls[WEST].setBounds( clientArea.x, clientArea.y + sizes[NORTH].y, sizes[WEST].x, clientArea.height - sizes[NORTH].y - sizes[SOUTH].y); } if (controls[EAST] != null) { controls[EAST].setBounds( clientArea.x + clientArea.width - sizes[EAST].x, clientArea.y + sizes[NORTH].y, sizes[EAST].x, clientArea.height - sizes[NORTH].y - sizes[SOUTH].y); } if (controls[CENTER] != null) { controls[CENTER].setBounds( clientArea.x + sizes[WEST].x, clientArea.y + sizes[NORTH].y, clientArea.width - sizes[WEST].x - sizes[EAST].x, clientArea.height - sizes[NORTH].y - sizes[SOUTH].y); } } private void refreshSizes(Control[] children) { for (int i = 0; i < children.length; i++) { Object layoutData = children[i].getLayoutData(); if (layoutData == null || (!(layoutData instanceof BorderData))) continue; BorderData borderData = (BorderData) layoutData; if (borderData.region < 0 || borderData.region > 4) // Invalid. continue; controls[borderData.region] = children[i]; } width = 0; height = 0; if (sizes == null) sizes = new Point[5]; for (int i = 0; i < controls.length; i++) { Control control = controls[i]; if (control == null) { sizes[i] = new Point(0, 0); } else { sizes[i] = control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); } } width = Math.max(width, sizes[NORTH].x); width = Math.max(width, sizes[WEST].x + sizes[CENTER].x + sizes[EAST].x); width = Math.max(width, sizes[SOUTH].x); height = Math.max(Math.max(sizes[WEST].y, sizes[EAST].y), sizes[CENTER].y) + sizes[NORTH].y + sizes[SOUTH].y; } } 测试代码: BorderLayoutSample.java package swt_jface.demo2; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class BorderLayoutSample { Display display = new Display(); Shell shell = new Shell(display); public BorderLayoutSample() { shell.setLayout(new BorderLayout()); Button buttonWest = new Button(shell, SWT.PUSH); buttonWest.setText("West"); buttonWest.setLayoutData(new BorderLayout.BorderData(BorderLayout.WEST)); Button buttonEast = new Button(shell, SWT.PUSH); buttonEast.setText("East"); buttonEast.setLayoutData(new BorderLayout.BorderData(BorderLayout.EAST)); Button buttonNorth = new Button(shell, SWT.PUSH); buttonNorth.setText("North"); buttonNorth.setLayoutData(new BorderLayout.BorderData(BorderLayout.NORTH)); Button buttonSouth = new Button(shell, SWT.PUSH); buttonSouth.setText("South"); buttonSouth.setLayoutData(new BorderLayout.BorderData(BorderLayout.SOUTH)); Text text = new Text(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); text.setText("Center"); text.setLayoutData(new BorderLayout.BorderData(BorderLayout.CENTER)); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } public static void main(String[] args) { new BorderLayoutSample(); } }