Draw2D 模拟SWT控件之RadioButton、CheckedBox

如果说Draw2D里内置了Button,我们其实直接用就行了,那么这里的RadioButton就彻底需要我们自己实现了。Draw2D只提供了CheckedBox的实现,鉴于CheckedBox与RadioButton的相似性,参考CheckedBox的实现就很容易模拟出RadioButton的效果了。

 

这两个按钮的实现其实很类似,就是前面显示的图形不一样,一个圆形,一个方形。这么相似,先用一个抽象类来封装一下共同点。

CheckedFigure.java

public abstract class CheckedFigure extends Figure {

	public static final Image CHECKBOX_CHECKED = createImage("icons/checkbox_checked.gif");

	public static final Image CHECKBOX_UNCHECKED = createImage("icons/checkbox_unchecked.gif");

	public static final Image RADIO_CHECKED = createImage("icons/radiobutton_checked.gif");

	public static final Image RADIO_UNCHECKED = createImage("icons/radiobutton_unchecked.gif");

	private static Image createImage(String name) {
		InputStream stream = CheckedFigure.class.getResourceAsStream(name);
		Image image = new Image(null, stream);
		try {
			stream.close();
		} catch (IOException ioe) {
		}
		return image;
	}

	private Image decrotorImage;
	private String text;

	protected boolean selection;

	public CheckedFigure() {
		this("Checkable");
	}

	public CheckedFigure(String text) {
		setText(text);
	}

	/**
	 * @return the decrotorImage
	 */
	public Image getDecrotorImage() {
		return decrotorImage;
	}

	/**
	 * @return the text
	 */
	public String getText() {
		return text;
	}

	/**
	 * @return the selection
	 */
	public boolean isSelection() {
		return selection;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Label#paintFigure(org.eclipse.draw2d.Graphics)
	 */
	@Override
	protected void paintFigure(Graphics graphics) {
		super.paintFigure(graphics);
		Rectangle bound = getBounds();
		int y = bound.y + (bound.height - decrotorImage.getBounds().height) / 2
				+ 1;
		graphics.drawImage(decrotorImage, bound.x, y);
		graphics.drawText(getText(), bound.x + decrotorImage.getBounds().width
				+ 1, y + 1);
	}

	/**
	 * @param decrotorImage
	 *            the decrotorImage to set
	 */
	public void setDecrotorImage(Image decrotorImage) {
		this.decrotorImage = decrotorImage;
	}

	/**
	 * @param selection
	 *            the selection to set
	 */
	public abstract void setSelection(boolean selection);

	/**
	 * @param text
	 *            the text to set
	 */
	public void setText(String text) {
		this.text = text;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.draw2d.Figure#setBounds(org.eclipse.draw2d.geometry.Rectangle
	 * )
	 */
	@Override
	public void setBounds(Rectangle rect) {
		//Ensure that the checked figure has a limited minimum height.
		if (rect.height < FigureConstants.CHECKED_FIGURE_MIN_HEIGHT) {
			rect.height = FigureConstants.CHECKED_FIGURE_MIN_HEIGHT;
		}
		super.setBounds(rect);
	}
}

 其中

FigureConstants.CHECKED_FIGURE_MIN_HEIGHT = 19

 

它是我根据图片的大小和文字的最小高度定的,防止Button被拉得太扁。。。关键的代码是

graphics.drawImage(decrotorImage, bound.x, y);
		graphics.drawText(getText(), bound.x + decrotorImage.getBounds().width
				+ 1, y + 1);

要准备的计算和绘制修饰图片和文字。修饰图片见附件。

下面来实现CheckedBoxFigure,好像多余了。。。Draw2D有了,不过它的跟我们的效果不一样,还是自己写比较一致。

public class CheckBoxFigure extends CheckedFigure {

	public CheckBoxFigure() {
		this("CheckBox");
	}

	public CheckBoxFigure(String text) {
		super(text);
		setDecrotorImage(CHECKBOX_UNCHECKED);
	}
	
	/**
	 * @param selection
	 *            the selection to set
	 */
	@Override
	public void setSelection(boolean selection) {
		this.selection = selection;
		setDecrotorImage(selection?CHECKBOX_CHECKED:CHECKBOX_UNCHECKED);
		repaint();
	}
}

 很简单,继承了CheckedFigure,使用了属于CheckedBox的图形,默认情况下是不选中的。再看RadioButton,我们花了很大代价就是要实现它。

public class RadioButtonFigure extends CheckedFigure {

	public RadioButtonFigure() {
		this("RadioButton");
	}

	public RadioButtonFigure(String text) {
		super(text);
		setDecrotorImage(RADIO_UNCHECKED);
	}


	/**
	 * @param selection
	 *            the selection to set
	 */
	public void setSelection(boolean selection) {
		this.selection = selection;
		setDecrotorImage(selection?RADIO_CHECKED:RADIO_UNCHECKED);
		repaint();
	}
}

 就是修饰图形不一样而已。大家可能要问,既然这么相似,为什么还有单独写一个类,用一个变量标志一下不就得了。呵呵,这里是有用意的,以后再讲。(用在GEF中,model和fiugre一一对应比较好)

 

public void setSelection(boolean selection) {
		this.selection = selection;
		setDecrotorImage(selection?RADIO_CHECKED:RADIO_UNCHECKED);
		repaint();
	}

这里得提供在选中状态修改情况下修改修饰图片的功能,至少我们要提供选中与不选中下按钮的状态不一样把。

看看效果:

你可能感兴趣的:(eclipse)