SWT BorderLayout
久しぶりに趣味コーディング。SWTにAWTと同じようなBorderLayoutがほしかったので実装してみた。
割と動いてる模様。だけど微妙にコントロール同士がかぶる。計算ミスかな〜。テスト用にコントロール矩形だけ描画するCanvas作って入れて試してみたら、意図通り動作していた。ButtonとかでSWT.BORDERスタイルを設定した時にコントロール領域をはみだすだけっぽい。
ってかソース丸ごと貼り付けるなよ>俺
package net.dotinterface.layout; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; public class BorderLayout extends Layout { public static final String CENTER = "CENTER"; public static final String NORTH = "NORTH"; public static final String WEST = "WEST"; public static final String EAST = "EAST"; public static final String SOUTH = "SOUTH"; protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { // TODO should cache preffered sizes of children Point cs = null, ns = null, ws = null, es = null, ss = null; Control controls = composite.getChildren(); for (int i = 0; i < controls.length; i++) { Point size = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT); Object o = controls[i].getLayoutData(); if (o instanceof String) { String direction = (String) o; if (NORTH.equals(direction)) { ns = size; } else if (WEST.equals(direction)) { ws = size; } else if (EAST.equals(direction)) { es = size; } else if (SOUTH.equals(direction)) { ss = size; } else { cs = size; } } else { cs = size; } } int nw = ns == null ? 0 : ns.x; int ww = ws == null ? 0 : ws.x; int cw = cs == null ? 0 : cs.x; int ew = es == null ? 0 : es.x; int sw = ss == null ? 0 : ss.x; int mw = Math.max(Math.max(nw, ww + cw + ew), sw); int nh = ns == null ? 0 : ns.y; int wh = ws == null ? 0 : ws.y; int ch = cs == null ? 0 : cs.y; int eh = es == null ? 0 : es.y; int sh = ss == null ? 0 : ss.y; int mh = nh + Math.max(Math.max(wh, ch), eh) + sh; return new Point(mw, mh); } protected void layout(Composite composite, boolean flushCache) { Rectangle parentSize = composite.getClientArea(); int pw = parentSize.width; int ph = parentSize.height; // TODO should cache preffered sizes of children Control cc = null, nc = null, wc = null, ec = null, sc = null; Control controls = composite.getChildren(); for (int i = 0; i < controls.length; i++) { Object o = controls[i].getLayoutData(); if (o instanceof String) { String direction = (String) o; if (NORTH.equals(direction)) { if (nc != null) { nc.setVisible(false); } nc = controls[i]; } else if (WEST.equals(direction)) { if (wc != null) { wc.setVisible(false); } wc = controls[i]; } else if (EAST.equals(direction)) { if (ec != null) { ec.setVisible(false); } ec = controls[i]; } else if (SOUTH.equals(direction)) { if (sc != null) { sc.setVisible(false); } sc = controls[i]; } else { if (cc != null) { cc.setVisible(false); } cc = controls[i]; } } else { if (cc != null) { cc.setVisible(false); } cc = controls[i]; } } int cx = 0, cy = 0, cw = pw, ch = ph; if (nc != null) { // NORTH nc.setVisible(true); Point size = nc.computeSize(pw, SWT.DEFAULT); nc.setBounds*1; Text tc = new Text(s, SWT.BORDER); tc.setText("Center"); tc.setLayoutData(BorderLayout.CENTER); Button bw = new Button(s, SWT.BORDER); bw.setText("West"); bw.setLayoutData(BorderLayout.WEST); Button be = new Button(s, SWT.NONE); be.setText("East"); be.setLayoutData(BorderLayout.EAST); Button be2 = new Button(s, SWT.NONE); be2.setText("East2"); be2.setLayoutData(BorderLayout.EAST); Label ls = new Label(s, SWT.BORDER); ls.setText("South"); ls.setLayoutData(BorderLayout.SOUTH); ToolBar tbn = new ToolBar(s, SWT.NONE); ToolItem ti; for (int i = 0; i < 5; i++) { ti = new ToolItem(tbn, SWT.NONE); ti.setText("North" + (i + 1)); } tbn.setLayoutData(BorderLayout.NORTH); s.open(); while (!s.isDisposed()) { if (!d.readAndDispatch()) { d.sleep(); } } d.dispose(); } }
*1:pw - size.x) / 2, 0, size.x, size.y); cy += size.y; ch -= size.y; } if (sc != null) { // SOUTH sc.setVisible(true); Point size = sc.computeSize(pw, SWT.DEFAULT); sc.setBounds((pw - size.x) / 2, ph - size.y, size.x, size.y); ch -= size.y; } if (wc != null) { // WEST wc.setVisible(true); Point size = wc.computeSize(SWT.DEFAULT, ch); wc.setBounds(0, cy + (ch - size.y) / 2, size.x, size.y); cx += size.x; cw -= size.x; } if (ec != null) { // EAST ec.setVisible(true); Point size = ec.computeSize(SWT.DEFAULT, ch); ec.setBounds(pw - size.x, cy + (ch - size.y) / 2, size.x, size.y); cw -= size.x; } if (cc != null) { // CENTER cc.setVisible(true); cc.setBounds(cx, cy, cw, ch); } } public static void main(String[] args) { Display d = new Display(); Shell s = new Shell(d); s.setText("BorderLayout Test"); s.setLayout(new BorderLayout(