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