アキはフリーランスのプログラマーです >> Java >> Eclipse
Sponsored link

このエントリーを含むはてなブックマーク このエントリーを含むECナビ人気ニュース

BorderLayoutのCenterの伸びをカスタム(Draw2D/GEF - Java Eclipse)

単純に、LabelFigureを5箇所に追加してみました。

左が普通のBorderLayout

真ん中は、カスタムで元のFigureのサイズのまま

右は、カスタムでFigureのサイズを幅・高さ共に拡張したものです。


Draw2DのBorderLayoutは、なぜかCenterのWidthのみ、サイズは拡張されます。

両方するか、しないかの方が、わかりやすいと思いますが。

ラベルが挿入されることを意識したのだと思います。


 しかし、CenterのFigureサイズをどうするか制御出来た方が便利だと思い

他の方法が見つからなかったので、わたしはこの方法を使っています。


あといくつか、動作のサンプル画像を載せておきます。

コード解説

StretchCenterHeightとStretchCenterWidth

ネーミングのセンスはさておき、以下のように、

stretchCenterWidthとstretchCenterHeightのboolean変数を作成しました。

一応、デフォルトで普通のBorderLayoutと同じ動きをするようにしてます。


	private boolean stretchCenterWidth=true;
	private boolean stretchCenterHeight=false;
	
public boolean isStretchCenterHeight() {
		return stretchCenterHeight;
	}

	public void setStretchCenterHeight(boolean stretchCenterHeight) {
		this.stretchCenterHeight = stretchCenterHeight;
	}

	public boolean isStretchCenterWidth() {
		return stretchCenterWidth;
	}

	public void setStretchCenterWidth(boolean stretchCenterWidth) {
		this.stretchCenterWidth = stretchCenterWidth;
	}

layout()

layoutでは元々、childFigureのHeightが、小さければ拡張するようになってました。

これを、制御できるようにと、Widthには適用してみました。


childSize = center.getPreferredSize(
					Math.max(0, area.width),
					Math.max(0, area.height));
			
			if(!stretchCenterHeight){
			if (childSize.height < area.height) {
				area.y += (area.height - childSize.height) / 2;
				area.height = childSize.height;
			}
			}
			
			if(!stretchCenterWidth){
				if (childSize.width < area.width) {
					area.x += (area.width - childSize.width) / 2;
					area.width = childSize.width;
				}
				}

呼び出し

あとは、BorderLayoutの変わりに、CustomLayoutを作成して、

拡張するかどうかを指定します。

CustomBorderLayout layout=new CustomBorderLayout();
		layout.setStretchCenterWidth(true);
		layout.setStretchCenterHeight(true);

コードフル

コードはCVSからダウンロードできます。


CustomBorderLayoutTest

以前、BorderLayoutの解説で使ったコードとほとんど同じです。

/*
 * Created on 2005/08/02
 * Author aki@www.xucker.jpn.org
 * License Apache2.0 or Common Public License
 */
package example.draw2d;

import org.eclipse.draw2d.BorderLayout;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.Panel;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * 
 *
 */
public class CustomBorderLayoutTest {

    public CustomBorderLayoutTest(Shell shell) {
        
		shell.setBounds(0,0,150,150);
		shell.setLayout(new FillLayout(SWT.VERTICAL));
		
		FigureCanvas canvas = new FigureCanvas(shell);
		Panel panel=new Panel();
		panel.setBackgroundColor(ColorConstants.orange);
		canvas.setContents(panel);
		
		//BorderLayout layout=new BorderLayout();
		CustomBorderLayout layout=new CustomBorderLayout();
		layout.setStretchCenterWidth(true);
		layout.setStretchCenterHeight(true);
		//layout.setHorizontalSpacing(5);
		//layout.setVerticalSpacing(5);
		
		panel.setLayoutManager(layout);
		
		set(panel,"top",BorderLayout.TOP);
		set(panel,"bottom",BorderLayout.BOTTOM);
		set(panel,"center",BorderLayout.CENTER);
		set(panel,"left",BorderLayout.LEFT);
		set(panel,"right",BorderLayout.RIGHT);
		
		
    }
    public void set(Figure parent,String label,Object constants){
        Label labelFigure=new Label(label);
        labelFigure.setBorder(new LineBorder());
        parent.add(labelFigure,constants);
    }
    
	public static void main(String[] args) {
		Display display=new Display();
		Shell shell=new Shell(display);
		
		
		CustomBorderLayoutTest app=new CustomBorderLayoutTest(shell);
		
		
		shell.open();
		
		while(!shell.isDisposed()){			
			if (!display.readAndDispatch ()){
					display.sleep ();
				  }
		}
		display.dispose();
	}
}

CustomBorderLayout

ほとんど、BorderLayoutと同じです。

package example.draw2d;

import org.eclipse.draw2d.AbstractLayout;
import org.eclipse.draw2d.BorderLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;


	/*******************************************************************************
	 * Copyright (c) 2000, 2005 IBM Corporation and others.
	 * All rights reserved. This program and the accompanying materials
	 * are made available under the terms of the Eclipse Public License v1.0
	 * which accompanies this distribution, and is available at
	 * http://www.eclipse.org/legal/epl-v10.html
	 *
	 * Contributors:
	 *     IBM Corporation - initial API and implementation
	 *******************************************************************************/

public class CustomBorderLayout extends BorderLayout{
	/**
	 * Constant to be used as a constraint for child figures
	 */
	public static final Integer CENTER = new Integer(PositionConstants.CENTER);
	/**
	 * Constant to be used as a constraint for child figures
	 */
	public static final Integer TOP = new Integer(PositionConstants.TOP);
	/**
	 * Constant to be used as a constraint for child figures
	 */
	public static final Integer BOTTOM = new Integer(PositionConstants.BOTTOM);
	/**
	 * Constant to be used as a constraint for child figures
	 */
	public static final Integer LEFT = new Integer(PositionConstants.LEFT);
	/**
	 * Constant to be used as a constraint for child figures
	 */
	public static final Integer RIGHT = new Integer(PositionConstants.RIGHT);

	private IFigure center, left, top, bottom, right;
	private int vGap = 0, hGap = 0;

	
	private boolean stretchCenterWidth=true;
	private boolean stretchCenterHeight=false;
	/**
	 * @see org.eclipse.draw2d.AbstractHintLayout#calculateMinimumSize(IFigure, int, int)
	 */
	protected Dimension calculateMinimumSize(IFigure container, int wHint, int hHint) {
		int minWHint = 0, minHHint = 0;
		if (wHint < 0) {
			minWHint = -1;
		}
		if (hHint < 0) {
			minHHint = -1;
		}
		Insets border = container.getInsets();
		wHint = Math.max(minWHint, wHint - border.getWidth());
		hHint = Math.max(minHHint, hHint - border.getHeight());
		Dimension minSize = new Dimension();
		int middleRowWidth = 0, middleRowHeight = 0;
		int rows = 0, columns = 0;

		if (top != null  && top.isVisible()) {
			Dimension childSize = top.getMinimumSize(wHint, hHint);
			hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
			minSize.setSize(childSize);
			rows += 1;
		}
		if (bottom != null && bottom.isVisible()) {
			Dimension childSize = bottom.getMinimumSize(wHint, hHint);
			hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
			minSize.width = Math.max(minSize.width, childSize.width);
			minSize.height += childSize.height;
			rows += 1;
		}
		if (left != null && left.isVisible()) {
			Dimension childSize = left.getMinimumSize(wHint, hHint);
			middleRowWidth = childSize.width;
			middleRowHeight = childSize.height;
			wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
			columns += 1;
		}
		if (right != null  && right.isVisible()) {
			Dimension childSize = right.getMinimumSize(wHint, hHint);
			middleRowWidth += childSize.width;
			middleRowHeight = Math.max(childSize.height, middleRowHeight);
			wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
			columns += 1;
		}
		if (center != null && center.isVisible()) {
			Dimension childSize = center.getMinimumSize(wHint, hHint);
			middleRowWidth += childSize.width;
			middleRowHeight = Math.max(childSize.height, middleRowHeight);
			columns += 1;
		}

		rows += columns > 0 ? 1 : 0;
		// Add spacing, insets, and the size of the middle row
		minSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
		minSize.width = Math.max(minSize.width, middleRowWidth) + border.getWidth() 
						+ ((columns - 1) * hGap);
		
		return minSize;
	}

	/**
	 * @see AbstractLayout#calculatePreferredSize(IFigure, int, int)
	 */
	protected Dimension calculatePreferredSize(IFigure container, int wHint, int hHint) {
		int minWHint = 0, minHHint = 0;
		if (wHint < 0)
			minWHint = -1;
		
		if (hHint < 0)
			minHHint = -1;
		
		Insets border = container.getInsets();
		wHint = Math.max(minWHint, wHint - border.getWidth());
		hHint = Math.max(minHHint, hHint - border.getHeight());
		Dimension prefSize = new Dimension();
		int middleRowWidth = 0, middleRowHeight = 0;
		int rows = 0, columns = 0;

		if (top != null && top.isVisible()) {
			Dimension childSize = top.getPreferredSize(wHint, hHint);
			hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
			prefSize.setSize(childSize);
			rows += 1;
		}
		if (bottom != null && bottom.isVisible()) {
			Dimension childSize = bottom.getPreferredSize(wHint, hHint);
			hHint = Math.max(minHHint, hHint - (childSize.height + vGap));
			prefSize.width = Math.max(prefSize.width, childSize.width);
			prefSize.height += childSize.height;
			rows += 1;
		}
		if (left != null && left.isVisible()) {
			Dimension childSize = left.getPreferredSize(wHint, hHint);
			middleRowWidth = childSize.width;
			middleRowHeight = childSize.height;
			wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
			columns += 1;
		}
		if (right != null && right.isVisible()) {
			Dimension childSize = right.getPreferredSize(wHint, hHint);
			middleRowWidth += childSize.width;
			middleRowHeight = Math.max(childSize.height, middleRowHeight);
			wHint = Math.max(minWHint, wHint - (childSize.width + hGap));
			columns += 1;
		}
		if (center != null && center.isVisible()) {
			Dimension childSize = center.getPreferredSize(wHint, hHint);
			middleRowWidth += childSize.width;
			middleRowHeight = Math.max(childSize.height, middleRowHeight);
			columns += 1;
		}

		rows += columns > 0 ? 1 : 0;
		// Add spacing, insets, and the size of the middle row
		prefSize.height += middleRowHeight + border.getHeight() + ((rows - 1) * vGap);
		prefSize.width = Math.max(prefSize.width, middleRowWidth) + border.getWidth() 
						+ ((columns - 1) * hGap);
		
		return prefSize;
	}

	/**
	 * @see org.eclipse.draw2d.LayoutManager#layout(IFigure)
	 */
	public void layout(IFigure container) {
		Rectangle area = container.getClientArea();
		Rectangle rect = new Rectangle();

		Dimension childSize;
		
		if (top != null && top.isVisible()) {
			childSize = top.getPreferredSize(area.width, -1);
			rect.setLocation(area.x, area.y);
			rect.setSize(childSize);
			rect.width = area.width;
			top.setBounds(rect);
			area.y += rect.height + vGap;
			area.height -= rect.height + vGap;
		}
		if (bottom != null && bottom.isVisible()) {
			childSize = bottom.getPreferredSize(Math.max(area.width, 0), -1);
			rect.setSize(childSize);
			rect.width = area.width;
			rect.setLocation(area.x, area.y + area.height - rect.height);
			bottom.setBounds(rect);
			area.height -= rect.height + vGap;
		}
		if (left != null && left.isVisible()) {
			childSize = left.getPreferredSize(-1, Math.max(0, area.height));
			rect.setLocation(area.x, area.y);
			rect.width = childSize.width;
			rect.height = Math.max(0, area.height);
			left.setBounds(rect);
			area.x += rect.width + hGap;
			area.width -= rect.width + hGap;
		}
		if (right != null && right.isVisible()) {
			childSize = right.getPreferredSize(-1, Math.max(0, area.height));
			rect.width = childSize.width;
			rect.height = Math.max(0, area.height);
			rect.setLocation(area.x + area.width - rect.width, area.y);
			right.setBounds(rect);
			area.width -= rect.width + hGap;
		}
		if (center != null && center.isVisible()) {
			childSize = center.getPreferredSize(
					Math.max(0, area.width),
					Math.max(0, area.height));
			
			if(!stretchCenterHeight){
			if (childSize.height < area.height) {
				area.y += (area.height - childSize.height) / 2;
				area.height = childSize.height;
			}
			}
			
			if(!stretchCenterWidth){
				if (childSize.width < area.width) {
					area.x += (area.width - childSize.width) / 2;
					area.width = childSize.width;
				}
				}
			
			center.setBounds(area);
		}
	}

	/**
	 * @see org.eclipse.draw2d.AbstractLayout#remove(IFigure)
	 */
	public void remove(IFigure child) {
		if (center == child) {
			center = null;
		} else if (top == child) {
			top = null;
		} else if (bottom == child) {
			bottom = null;
		} else if (right == child) {
			right = null;
		} else if (left == child) {
			left = null;
		}
	}

	/**
	 * Sets the location of hte given child in this layout.  Valid constraints:
	 * <UL>
	 * 		<LI>{@link #CENTER}</LI>
	 * 		<LI>{@link #TOP}</LI>
	 * 		<LI>{@link #BOTTOM}</LI>
	 * 		<LI>{@link #LEFT}</LI>
	 * 		<LI>{@link #RIGHT}</LI>
	 * 		<LI><code>null</code> (to remove a child's constraint)</LI>
	 * </UL>
	 * 
	 * <p>
	 * Ensure that the given Figure is indeed a child of the Figure on which this layout has
	 * been set.  Proper behaviour cannot be guaranteed if that is not the case.  Also ensure
	 * that every child has a valid constraint.  
	 * </p>
	 * <p> 
	 * Passing a <code>null</code> constraint will invoke {@link #remove(IFigure)}.
	 * </p>
	 * <p> 
	 * If the given child was assigned another constraint earlier, it will be re-assigned to
	 * the new constraint.  If there is another child with the given constraint, it will be
	 * over-ridden so that the given child now has that constraint.
	 * </p>
	 * 
	 * @see org.eclipse.draw2d.AbstractLayout#setConstraint(IFigure, Object)
	 */
	public void setConstraint(IFigure child, Object constraint) {
		remove(child);
		super.setConstraint(child, constraint);
		if (constraint == null) {
			return;
		}
		
		switch (((Integer) constraint).intValue()) {
			case PositionConstants.CENTER :
				center = child;
				break;
			case PositionConstants.TOP :
				top = child;
				break;
			case PositionConstants.BOTTOM :
				bottom = child;
				break;
			case PositionConstants.RIGHT :
				right = child;
				break;
			case PositionConstants.LEFT :
				left = child;
				break;
			default :
				break;
		}
	}

	/**
	 * Sets the horizontal spacing to be used between the children.  Default is 0.
	 * 
	 * @param gap The horizonal spacing
	 */
	public void setHorizontalSpacing(int gap) {
		hGap = gap;
	}

	/**
	 * Sets the vertical spacing ot be used between the children.  Default is 0.
	 * 
	 * @param gap The vertical spacing
	 */
	public void setVerticalSpacing(int gap) {
		vGap = gap;
	}

	public boolean isStretchCenterHeight() {
		return stretchCenterHeight;
	}

	public void setStretchCenterHeight(boolean stretchCenterHeight) {
		this.stretchCenterHeight = stretchCenterHeight;
	}

	public boolean isStretchCenterWidth() {
		return stretchCenterWidth;
	}

	public void setStretchCenterWidth(boolean stretchCenterWidth) {
		this.stretchCenterWidth = stretchCenterWidth;
	}

	}




このエントリーを含むはてなブックマーク このエントリーを含むECナビ人気ニュース