我正在使用用于处理的GUI库,并且有一个类Component
。我有一堆扩展Component
的其他类:Label
,Button
(其中扩展了Label
),Panel
和Icon
。这些类仅构成“逻辑”部分(位置,文本,是否检查它们是否被单击等功能)。
类Panel
内有ArrayList
中的Component
,您可以在其中添加按钮,标签等...
要显示我决定使用类Theme
的组件,该函数内部有一些display(Component component)
重载(一个用于Label
,一个用于Button
, Panel
等)。
在display(Panel panel)
内,有时会显示面板的所有子项,但是出于将它们(子项)视为Button
或Label
的考虑,它会将所有它们为Component
。我该如何解决这个问题?
1)我已经尝试在类display()
,Component
等内部使用方法Button
,虽然部分起作用,但是它带来了一些“编码问题”:要覆盖功能显示,您必须创建一个新类(示例:GreenBackgroundButton扩展Button {})。同样,通过将所有函数放在一个外部类中,您可以使用一个类来控制Program的所有rapihcs,因此您可以使用单个函数displayBackground()
等对所有组件具有相同的背景...
2)instanceof
不能使用,因为如果我必须使用它来投射面板的子代,用户将无法创建自定义组件,因为它们将显示为{{1 }}不是Component
(示例)。
3)我已经尝试过直接转换TextField
,但是正如Showld所示,当我使用标签时,它会产生错误(按预期)。
4)我也尝试过这样的转换:display((Button)panel.getChildren.get(0))
,但是它不起作用,我也不知道为什么。 (我尝试了其所有变体,例如创建外部对象等)
5)如果您需要更多代码,可以询问...
panel.getChildren().get(0).getClass().cast(panel.getChildren().get(0))
public void display(Panel panel) {
println("panel");
if (panel.isVisible()) {
pushMatrix();
translate(panel.getX(), panel.getY());
displayBackground(panel, #AAAAAA);
for (int i = 0; i < panel.getChildren().size(); i++) {
this.display(panel.getChildren().get(i).getClass().cast(panel.getChildren().get(i))); //THIS IS THE LINE WITH THE ISSUE
//println(panel.getChildren().get(i).getClass().cast(panel.getChildren().get(i)));
}
popMatrix();
}
}
我希望在画布上看到面板内部的工作按钮,而不是看到组件。我现在没有任何特别的错误。
答案 0 :(得分:1)
使用instanceof
几乎总是一种技巧,并且可能是不良设计的征兆。
您所描述的内容听起来像是一个名为Abstract Window Toolkit(AWT)的现有Java库,因此您可以考虑“借鉴”他们的某些设计模式。
Component
是一个抽象类,它定义了一个抽象paint()
函数。 paint()
函数接受一个Graphics
参数。一秒钟有更多内容。Button
和Label
扩展了Component
并覆盖了paint()
函数。Graphics
是一个类,其中包含诸如drawRect()
和setBackground()
之类的函数。它封装了共享的绘图代码,类似于我认为您的Theme
类会做的事情。如果我是您,我会考虑对您的图书馆采取类似的方法。
我将尝试解决您的其他一些评论:
示例:GreenBackgroundButton扩展了Button {}
喜欢composition over inheritance的情况是这样的。您无需扩展Button
即可设置背景。而是在setBackground()
类(或Button()
类)中使用Component
函数。
此外,通过将所有函数放在一个外部类中,您可以使用一个类来控制Program的所有rapihcs,因此,您可以使用单个函数displayBackground()等使所有组件具有相同的背景。< / p>
听起来这属于您的Component
类。
此外,请退后一步,我鼓励您避免诱惑over-engineer。您可能会认为您需要一个具有多个继承级别和许多不同类的复杂设计,但是更简单的设计可能会为您提供几乎所需的一切。具体来说,将任何代码提取到Theme
类中并不会带来什么好处。我可能会将所有内容直接放入Button
和Label
之类的组件子类中。