现在我想起一个简单的问题:
我有一个包含(其中包括)ScrollPane的JavaFX应用程序,我需要捕获该ScrollPane的MouseClicked事件。这本身实际上没有问题,除了我只需要处理事件,如果事件目标是Rectangle,ToggleButton或ScrollPaneSkin的实例。我知道,这实际上也很容易。现在,我有以下代码:
@FXML
void scrollPaneOnMouseClicked(MouseEvent event) {
System.out.println(event.getTarget().getClass().getName());
System.out.println(event.getTarget() instanceof ScrollPaneSkin);
if (event.getTarget() instanceof RoomRectangle || event.getTarget() instanceof ToggleButton || event.getTarget() instanceof ScrollPaneSkin) {
// handle
}
}
除非event.getTarget() instanceof ScrollPaneSkin
表示System.out.println(event.getTarget().getClass().getName());
输出com.sun.javafx.scene.control.skin.ScrollPaneSkin$4
(并且调试器确认了这一点),否则event.getTarget() instanceof ScrollPaneSkin$4
会显示为false。
我也尝试了{% load staticfiles %}
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google</title>
<meta name="description" content="Blueprint: Horizontal Drop-Down Menu" />
<meta name="keywords" content="horizontal menu, microsoft menu, drop-down menu, mega menu, javascript, jquery, simple menu" />
<meta name="author" content="Codrops" />
<link rel="shortcut icon" type="image/png" href="{{STATIC_URL}}/favicon.ico"/>
<link type="text/javascript" href="{% static 'MMR/js/topnavbar.js' %}">
<!-- top nav scripts-->
</head>
<body>
{% include 'MMR/topnavbar.html' %}
{% block content %}
{% endblock %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="static/MMR/js/cbpHorizontalMenu.min.js"></script>
<script>
$(function() {
cbpHorizontalMenu.init();
});
</script>
</body>
</html>
,导致了“无法找到符号” - 错误。
我在这里想念的是什么?
答案 0 :(得分:2)
好的,我自己解决了。问题很简单,原因是$4
。正如我刚刚发现的那样,$4
指向匿名内部类ScrollPaneSkin
,显然无法从外部访问。这意味着目标实际上不是ScrollPaneSkin
的实例,而是该内部类的实例。唯一的解决方法是使用event.getTarget.getClass().getName()
并进行字符串比较。 (解决方案取自here)
答案 1 :(得分:1)
ScrollPaneSkin$4
可能是name mangling的实例。这可能是您的代码event.getTarget() instanceof ScrollPaneSkin
不起作用的原因(因为目标实际上是匿名内部类的实例,而不是皮肤本身)。
匿名类的范围仅限于其父类,因此编译器必须为内部类生成“限定”的公共名称,以避免在同一个名称(内部或非内部)存在的情况下发生冲突命名空间。类似地,匿名类必须为它们生成“假”公共名称(因为匿名类的概念仅存在于编译器中,而不是运行时)。所以,编译以下java程序
public class foo { class bar { public int x; } public void zark () { Object f = new Object () { public String toString() { return "hello"; } }; } }
将生成三个.class文件:
foo.class
,包含主(外)类foofoo$bar.class
,包含指定的内部类foo.barfoo$1.class
,包含匿名内部类(方法foo.zark的本地)
由于ScrollPaneSkin
是com.sun
不支持的公共API,因此基于它编写代码可能不是一个好主意,因为它可能很脆弱并且由于ScrollPaneSkin的内部实现而容易出错,可以从Java更改为版本。关于你如何完成你想要完成的任务,我没有进一步的建议。