2011-08-19 45 views
4

假设问题:SWT用户控制设计决策

这个SWT设计决定如何做一个自定义复合构件我必须继承Composite?这真的很明智吗?

如果SWT有一个像Win窗体或类似的UserControl类,会不会更好?

当我子类复合我的自定义小部件获取复合接口,即使它不打算被用作客户端合成。那有点不好。一些SWT小部件也是如此,例如Spinner。

有没有一个很好的解决方法呢?

而且,最有趣的是:有谁知道这个设计决策的动机?

+0

您可以使用委派代替继承吗? –

+0

这也是我的想法,以某种方式使用委派会更清洁,可能会扩展控制并具有内部复合。但SWT准则说你只应该扩展Composite或Canvas。在大多数情况下,画布看上去都不太合适。 – Lii

+0

由于我在Swing中进行了大量的开发工作,因此我最终封装了所有使用的Swing组件,因为接口非常庞大而且不好嘲弄。 –

回答

1

你可以创建自己的NonCompositeUserControl类:

public class NonCompositeUserControl extends Composite { 
    @Override 
    public void setLayout(Layout layout) { 
     throw new UnsupportedOperationException("This control is not really a composite") 
    } 
    // similarly for other methods 
} 
+0

是的,你可以添加一个像这样的运行时检查。但是,如果你根本不需要复合子类,它会更清晰,更不容易出错。例如,当您创建另一个小部件时,仍然可以将此类作为父项传递。 – Lii

2

你可以看看源代码org.eclipse.swt.custom.CCombo怎么看这个问题SWT交易内部,如CComboComposite延伸。以下是他们如何处理setLayout(),例如:

/** 
* Sets the layout which is associated with the receiver to be 
* the argument which may be null. 
* <p> 
* Note: No Layout can be set on this Control because it already 
* manages the size and position of its children. 
* </p> 
* 
* @param layout the receiver's new layout or null 
* 
* @exception SWTException <ul> 
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 
* </ul> 
*/ 
public void setLayout (Layout layout) { 
    checkWidget(); 
    return; 
} 
+0

哎呀,当有人称这种方法时,他们甚至不会抛出。你甚至不知道你做错了什么。 – Lii

+0

我的观点是,这对我来说似乎是一个有问题的设计。因为您公开地继承了不应该用作Composite的小部件上的Composite接口。但也许有一个很好的理由,知道它是什么会很有趣。 – Lii