如果说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();
}
这里得提供在选中状态修改情况下修改修饰图片的功能,至少我们要提供选中与不选中下按钮的状态不一样把。
看看效果: