- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试为 java 创建一个 GUI 库,并计划通过使用 java 8 lambda 表达式使其成为事件驱动来使其具有高度可扩展性。
我目前有两种类型的事件。第一个,GuiEvent,不是通用的。然而,第二个确实指定了一个通用参数:ComponentEvent<T extends GuiComponent<?, ?>>
以便稍后,您可以使用以下 lambda 来捕获事件:
button.onEvent((event) -> {
// event.component is supposed to be of the type ComponentEvent<Button>
System.out.println("Test button pressed! " + ((Button) event.component).getText());
}, ActionEvent.class);
onEvent
看起来像下面这样:
public <EVENT extends ComponentEvent<?>> O onEvent(EventListener<EVENT> listener, Class<EVENT> clazz) {
return onEvent(listener, clazz, Side.CLIENT);
}
它是 GuiComponent<O extends GuiComponent<O, T>, T extends NativeGuiComponent> ...
的一部分在我们的例子中,因为我们正在监听的组件是一个按钮,可以简化为 Button<Button, NativeButton>
所以派生类型 O
是Button
.
正如预期的那样,它没有参数化 ComponentEvent<?>
因此 event.component
的类型是正确的 GuiComponent<?, ?>
这使得强制转换。
现在我尝试了几种方法来参数化ComponentEvent
从这个开始:
public <EVENT extends ComponentEvent<O>> O onEvent(EventListener<EVENT> listener, Class<EVENT> clazz) {
return onEvent(listener, clazz, Side.CLIENT);
}
这使情况变得更糟,因为它现在显示编译警告:
Type safety: Unchecked invocation onEvent(EventListener<ComponentEvent.ActionEvent>,
Class<ComponentEvent.ActionEvent>) of the generic method
onEvent(EventListener<EVENT>, Class<EVENT>) of type
GuiComponent<Button,NativeButton>
出于某些奇怪的原因,将类变量更改为 ActionEvent.class.asSubclass(Button.class)
编译,为我提供了 event.component
的正确类型但它当然会因稍后的 ClassCastException 而崩溃......
编辑:这是所有涉及的类定义的列表:
基类 GuiComponent:
public abstract class GuiComponent<O extends GuiComponent<O, T>,
T extends NativeGuiComponent> implements Identifiable,
EventListener<GuiEvent>, PacketHandler {
private SidedEventBus<ComponentEvent<?>> eventListenerList = new SidedEventBus<ComponentEvent<?>>(this::dispatchNetworkEvent);
...
public <EVENT extends ComponentEvent<?>> O onEvent(EventListener<EVENT> listener, Class<EVENT> clazz, Side side) {
eventListenerList.add(listener, clazz, side);
return (O) this;
}
public <EVENT extends ComponentEvent<?>> O onEvent(EventListener<EVENT> listener, Class<EVENT> clazz) {
return onEvent(listener, clazz, Side.CLIENT);
}
...
按钮,参数化
public class Button extends GuiComponent<Button, NativeButton> {
示例图形用户界面
Gui testGUI = new Gui("testgui")
.add(new Button("testbutton2", "I'm EAST")
.setMaximumSize(Integer.MAX_VALUE, 120)
.onEvent((event) -> {
System.out.println("Test button pressed! " + Side.get());
}, ActionEvent.class), Anchor.EAST)
.add(new Button("testbutton3", "I'm CENTER"))
.add(new Button("testbutton4", "I'm SOUTH"), Anchor.SOUTH)
.add(new GuiContainer("container").setLayout(new FlowLayout())
.add(new Button("testbutton5", "I'm the FIRST Button and need lots of space"))
.add(new Label("testlabel1", "I'm some label hanging around").setBackground(new Background(Color.white)))
.add(new Button("testbutton7", "I'm THIRD"))
.add(new Button("testbutton8", "I'm FOURTH"))
, Anchor.NORTH)
.onGuiEvent((event) -> {
System.out.println("Test GUI initialized! " + event.player.getDisplayName() + " " + event.position);
}, BindEvent.class)
.onGuiEvent((event) -> {
System.out.println("Test GUI closed!");
}, UnBindEvent.class);
guiFactory.registerGui(testGUI, id);
组件和 Action 事件:
public abstract class ComponentEvent<T extends GuiComponent<?, ?>> extends CancelableEvent implements SidedEvent {
public final T component;
public ComponentEvent(T component) {
this.component = component;
}
public static class ActionEvent<T extends GuiComponent<?, ?>> extends ComponentEvent<T> {
public ActionEvent(T component) {
super(component);
}
}
...
最佳答案
好吧,通过这个模型和解释,我认为问题的症结在于:
ActionEvent.class
不够丰富,无法表示这一点(因为它不会通知运行时/编译器事件的组件类型)。你需要传递一个 Class<ActionEvent<Button>>
但这对于类文字是不可能的。在这种情况下,典型的方法是使用更丰富的类型捕获机制。 Guava's TypeToken
是一个实现:
button.onEvent((event) -> {
System.out.println("Test button pressed! " + event.component.getText());
}, new TypeToken<ActionEvent<Button>>(){});
onEvent 在哪里:
public <E extends ComponentEvent<O>> O onEvent(EventListener<E> listener, TypeToken<E> eventType) {
//register listener
}
此模式捕获 Event
的完全解析泛型类型,并使其在运行时可供检查。
如果您担心创建 TypeToken
的负担对于调用者,有很多方法可以将很多复杂性转移到您的库代码中。这是一个这样做的例子:
button.onEvent((event) -> {
System.out.println("Test button pressed! " + event.component.getText());
}, ActionEvent.type(Button.class));
//then in ActionEvent
public static <C> TypeToken<ActionEvent<C>> type(Class<C> componentType) {
return new TypeToken<ActionEvent<C>>(){}.where(new TypeParameter<C>(){}, componentType);
}
当然,最简单的方法是首先停止在组件类型上键入事件。您只需将两个参数传递给处理程序即可完成此操作:
button.onEvent((event, component) -> {
System.out.println("Test button pressed! " + component.getText());
}, ActionEvent.class);
public <E extends ComponentEvent> O onEvent(EventListener<E, O> listener, Class<E> eventType) {
//register listener
}
关于Java 嵌套泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28818604/
所以我试图设置“内容”类的高度,但它似乎不起作用。我对嵌套 DIV 非常陌生,我已经尝试了我在谷歌搜索中发现的修复程序,但似乎没有任何效果。帮助?
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
好的,所以我一直在四处寻找,但找不到这个问题的答案。但是,我需要将一个 View 嵌套在另一个 View 中。 我有一个 $layout 正在使用我拥有的 default.layout Blade 文
基本上,我的问题很简单,但它需要知道 Struts 1.1 并且还活着的人。 我尝试构建的伪代码看起来像这样: IF element.method1 = true THEN IF element
我正在尝试将 Excel 嵌套 IF 语句转换为代码语言,但我不确定我是否正确执行此操作,希望能得到一些帮助 这是Excel语句: =IF(D3="Feather",IF(OR(I3>1000,R3=
如果我们创建两个或三个评论并对其进行多次回复,则“有用”链接在单击时会导致问题,它会对具有相同编号的索引执行 ng-click 操作,从而显示具有相同索引的所有文本。如何解决此嵌套问题,以便在单击链接
我在项目中使用Scala,想与Stripe集成,但它只提供Java API。例如,要创建 session ,我使用: val params = new util.HashMap[String, Any
以下代码有一个 Div,其中连续包含四个较小的 Div。四个 Div 中的每一个还包含一个较小的 Div,但此 Div 未显示。我尝试了各种显示和位置组合,看看 div 是否会出现。 classGoa
我在这里有一个问题,循环是: for (i=0; i < n; ++i) for (j = 3; j < n; ++j) { ...
我正在尝试编写代码来显示具有奇数宽度的形状。形状完成后,将其放置在外部形状内。用户将能够输入用于形状的字符和行数。我希望生成一个形状,并通过 for 循环生成一个外部形状。 ***** .
$(".globalTabs").each(function(){ var $globalTabs = $(this); var parent = $globalTabs.parent
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve th
所以我在这个问题上遇到了一些麻烦,因为变量 i。我只是不确定在第二个 while 循环中如何处理它。对于我的外循环,我知道它将运行 log_4(n^2) 次迭代。对于内部 while 循环,我计算的迭
我似乎找不到在枚举上应用多个 if/then 逻辑的工作方式。 anyOf 不应用条件逻辑,而是表示如果其中任何一个匹配则很好。 allOf 再次不应用条件逻辑,而是测试属性/必填字段的超集。 这是一
如何访问 ReaderT 的内部 monad。 在我的例子中,我有类型: newtype VCSSetupAction a = VCSSetupAction (ReaderT (Maybe VCSCo
这个问题在这里已经有了答案: Add leading zeroes/0's to existing Excel values to certain length (7 个回答) 7年前关闭。 我正在寻
我已经绑定(bind)了很多 AND/OR 函数的组合并且没有运气。 这是我需要创建的: 在 B 列中,我有公司 ID,范围从两个数字字符到六个数字字符。 我需要在 B 列中的每个公司 ID 之前的每
我是 VBA 新手,在尝试编写的宏中使用 If 语句时遇到了一些困难。每个月我都会收到一份 Excel 报告,其中列出了我们公司的哪些员工执行了某些任务。我正在编写的宏旨在将每个员工的数据复制并粘贴到
如果在 B 列中找到单元格 A1 中的值,则使用文本 321 填充除非在 C 列中找到单元格 A1 中的值,在这种情况下填充文本 121反而。如果单元格 A1 的内容不在 B 列或 C 列中,则使用
我有几十万个地址。其中一些在整数之后有粒子。如 4356 A Horse Avenue , 其他格式正常4358 Horse Avenue .有些有“A”,有些有“B”。我正在尝试删除整数和粒子之间的
我是一名优秀的程序员,十分优秀!