S-JIS[2013-03-23/2013-03-31] 変更履歴

Eclipse GEF Figure

Eclipseプラグイン開発GEFの図形について。


概要

Figureは、エディター上に表示する図形を描画するクラス。

基本的にはdraw2dの図形やラベル等を使用するが、細かい表現をしたいと思ったらGraphicsに対してゴリゴリ描く必要がある。


浮き上がった四角形の図形の例。

import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.BorderLayout;
import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.SimpleRaisedBorder;
public class MyRaisedFigure extends RectangleFigure {

RectangleFigureを使うと図形の形が四角形になる。

	private Label nameLabel;
	public MyRaisedFigure() {
		{ // border
			SimpleRaisedBorder frameBorder = new SimpleRaisedBorder();
			MarginBorder marginBoder = new MarginBorder(4);
			setBorder(new CompoundBorder(frameBorder, marginBoder));
		}

		{ // layout
			setLayoutManager(new BorderLayout());

			nameLabel = new Label();
			add(nameLabel, BorderLayout.CENTER);
		}
	}

setBorder()によって、Figureの一番外側の線の描き方を指定する。
SimpleRaisedBorderはちょっと盛り上がって見えるような線。
MarginBorderは、内側の領域(ラベルとか)と線の間に空ける間隔を指定するもの。マージンを指定しないと、内側のラベルにぴったり張り付いた線となる。

setLayoutManager()によって、Figure内のコンポーネント(ラベルとか)の配置方法を指定する。
add()によってFigure内にコンポーネントを追加していく。

紛らわしいんだけど、setBorder()でセットするBorderと、setLayoutManager()にセットしているBorderLayoutには、何の関係も無い。
LayoutにはBorderLayoutとかFlowLayoutとか色々な種類があり、たまたまBorderLayoutはBorderという名前が付いているだけ。

	public void setName(String name) {
		nameLabel.setText(name);
	}
}

GEFのFigureはModelの値を表示する役割を負うので、値を受け取って表示に反映させるメソッドを用意する必要がある。


サイズの指定

上記の例でFigureが表示できるが、このFigureの大きさはラベル(に書かれた文字列)によって変化してしまう。

サイズを固定するには以下の様なメソッドを追加する。(もしくは、素直にsetPreferredSize()でサイズを指定する)

import org.eclipse.draw2d.geometry.Dimension;
	@Override
	public Dimension getPreferredSize(int wHint, int hHint) {
		// return super.getPreferredSize(wHint, hHint);
		return new Dimension(80, 48); //固定サイズを返す
	}

この場合、ラベルの文字列がサイズ内に収まらないと、「test...」の様に末尾が「...」になって省略して表示される。


複数行テキストの例

ラベルは1行のテキストしか表示できない。
複数行に亘るテキストを表示したい場合はTextFlowを使う。

import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.text.FlowPage;
import org.eclipse.draw2d.text.ParagraphTextLayout;
import org.eclipse.draw2d.text.TextFlow;
public class MyFigure extends RectangleFigure {

	private TextFlow nameText;
	public MyRaisedFigure() {
〜
		{ // layout
			setLayoutManager(new BorderLayout());

			FlowPage page = new FlowPage();
			nameText = new TextFlow();
			LayoutManager manager = new ParagraphTextLayout(nameText, ParagraphTextLayout.WORD_WRAP_SOFT);
			nameText.setLayoutManager(manager);
			page.add(nameText);

			add(page, BorderLayout.CENTER);
		}
	}

Labelの代わりにTextFlowを使う。
TextFlowを使う場合はFlowPage経由にしないといけないらしい。


さらに、この複数行テキストを中央表示(センタリング)したい場合はBlockFlowを使用する。

import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.text.BlockFlow;
	public MyRaisedFigure() {
〜
		{ // layout
			setLayoutManager(new BorderLayout());

			FlowPage page = new FlowPage();
			nameText = new TextFlow();
			LayoutManager manager = new ParagraphTextLayout(nameText, ParagraphTextLayout.WORD_WRAP_SOFT);
			nameText.setLayoutManager(manager);
			BlockFlow block = new BlockFlow();
			block.setHorizontalAligment(PositionConstants.CENTER);
			block.add(nameText);
			page.add(block);

			add(page, BorderLayout.CENTER);
		}
	}

GEFへ戻る / Eclipseプラグインへ戻る / Eclipseへ戻る / 技術メモへ戻る
メールの送信先:ひしだま