JavaFX instanceof ScrollPaneSkin失败

时间:2017-01-03 23:56:55

标签: java javafx

现在我想起一个简单的问题:

我有一个包含(其中包括)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> ,导致了“无法找到符号” - 错误。

我在这里想念的是什么?

2 个答案:

答案 0 :(得分:2)

好的,我自己解决了。问题很简单,原因是$4。正如我刚刚发现的那样,$4指向匿名内部类ScrollPaneSkin,显然无法从外部访问。这意味着目标实际上不是ScrollPaneSkin的实例,而是该内部类的实例。唯一的解决方法是使用event.getTarget.getClass().getName()并进行字符串比较。 (解决方案取自here

答案 1 :(得分:1)

对于在ScrollPaneSkin中创建的匿名内部类,

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,包含主(外)类foo
  •   
  • foo$bar.class,包含指定的内部类foo.bar
  •   
  • foo$1.class,包含匿名内部类(方法foo.zark的本地)
  •   

由于ScrollPaneSkincom.sun不支持的公共API,因此基于它编写代码可能不是一个好主意,因为它可能很脆弱并且由于ScrollPaneSkin的内部实现而容易出错,可以从Java更改为版本。关于你如何完成你想要完成的任务,我没有进一步的建议。