涉及JavaFX和泛型的误导性堆栈跟踪
在打开带有提示符类型的组合框和使用Java1.8u40连接的StringConverter时,我遇到了以下错误。这可以追溯到执行FXML的团队留下的示例字符串,与控制器中的通用类型组合框相冲突。我们通过确保在initialize()中用正确类型的项替换虚拟列表来修复此问题 然而,虽然我理解这个问题以及如何解决它,但我无法理解堆栈跟踪。。。错误发生在at涉及JavaFX和泛型的误导性堆栈跟踪,java,generics,javafx,javafx-8,Java,Generics,Javafx,Javafx 8,在打开带有提示符类型的组合框和使用Java1.8u40连接的StringConverter时,我遇到了以下错误。这可以追溯到执行FXML的团队留下的示例字符串,与控制器中的通用类型组合框相冲突。我们通过确保在initialize()中用正确类型的项替换虚拟列表来修复此问题 然而,虽然我理解这个问题以及如何解决它,但我无法理解堆栈跟踪。。。错误发生在atController$1.toString(Controller.java:1) 为什么会在第1行报告,控制器本身不是通用的,只有它的字段 有没
Controller$1.toString(Controller.java:1)
- 为什么会在第1行报告,控制器本身不是通用的,只有它的字段
- 有没有编译器生成的魔法
- FXML构建过程如何构建正确类型的组合框,因为泛型只存在于编译类型
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at Controller$1.toString(Controller.java:1)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ComboBoxListViewSkin.java:388)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.access$100(ComboBoxListViewSkin.java:57)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$2$1.updateItem(ComboBoxListViewSkin.java:425)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
at javafx.scene.control.ListCell.indexChanged(ListCell.java:330)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116)
at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1957)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1797)
at com.sun.javafx.scene.control.skin.VirtualFlow.getCellBreadth(VirtualFlow.java:1888)
at com.sun.javafx.scene.control.skin.VirtualFlow.getMaxCellWidth(VirtualFlow.java:2508)
at com.sun.javafx.scene.control.skin.VirtualContainerBase.getMaxCellWidth(VirtualContainerBase.java:94)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$3.computePrefWidth(ComboBoxListViewSkin.java:457)
at javafx.scene.Parent.prefWidth(Parent.java:904)
at javafx.scene.layout.Region.prefWidth(Region.java:1419)
at com.sun.javafx.scene.control.skin.ComboBoxPopupControl.sizePopup(ComboBoxPopupControl.java:199)
at com.sun.javafx.scene.control.skin.ComboBoxPopupControl.positionAndShowPopup(ComboBoxPopupControl.java:173)
at com.sun.javafx.scene.control.skin.ComboBoxPopupControl.show(ComboBoxPopupControl.java:154)
at com.sun.javafx.scene.control.skin.ComboBoxBaseSkin.handleControlPropertyChanged(ComboBoxBaseSkin.java:127)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.handleControlPropertyChanged(ComboBoxListViewSkin.java:159)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyBooleanWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:178)
at javafx.beans.property.ReadOnlyBooleanWrapper$ReadOnlyPropertyImpl.access$100(ReadOnlyBooleanWrapper.java:148)
at javafx.beans.property.ReadOnlyBooleanWrapper.fireValueChangedEvent(ReadOnlyBooleanWrapper.java:144)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.scene.control.ComboBoxBase.setShowing(ComboBoxBase.java:185)
at javafx.scene.control.ComboBoxBase.show(ComboBoxBase.java:391)
at com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior.show(ComboBoxBaseBehavior.java:242)
at com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior.mouseReleased(ComboBoxBaseBehavior.java:197)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:350)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$351(GlassViewEventHandler.java:385)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:384)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
小例子
我使用Integer表示其他一些特定于业务的类型,太复杂了,无法粘贴到这里,值列表实际上是动态的,并且是从数据库加载的
FXML
虽然这个答案并不能解决OP最初的问题,但我还是把它留给了一个有着相同stacktrace的人,他不知道哪里出了问题
您正在控制器中声明一个
组合框
,当您在FXML中将字符串值传递给它时,会出现异常
java.lang.ClassCastException:java.lang.String不能转换为java.lang.Integer
如果您想要一个包含整数值的组合框,那么您需要将整数值传递给您的组合框
<FXCollections fx:factory="observableArrayList">
<Integer fx:value="1" />
<Integer fx:value="2" />
<Integer fx:value="3" />
</FXCollections>
虽然这个答案并不是OP最初问题的解决方案,但我还是把它留给了一个有着相同stacktrace的人,他不知道出了什么问题
您正在控制器中声明一个
组合框
,当您在FXML中将字符串值传递给它时,会出现异常
java.lang.ClassCastException:java.lang.String不能转换为java.lang.Integer
如果您想要一个包含整数值的组合框,那么您需要将整数值传递给您的组合框
<FXCollections fx:factory="observableArrayList">
<Integer fx:value="1" />
<Integer fx:value="2" />
<Integer fx:value="3" />
</FXCollections>
这似乎是一个编译器问题,特别是Eclipse中使用的内部编译器Luna SR1 如果使用JDK编译器编译相同的示例,则在第14行正确报告错误
javac Controller.java
javac ComboBoxTypeMismatch.java
java -cp . ComboBoxTypeMismatch
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at Controller$1.toString(Controller.java:14)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ComboBoxListViewSkin.java:388)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.access$100(ComboBoxListViewSkin.java:57)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$2$1.updateItem(ComboBoxListViewSkin.java:425)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
这似乎是一个编译器问题,特别是Eclipse中使用的内部编译器Luna SR1 如果使用JDK编译器编译相同的示例,则在第14行正确报告错误
javac Controller.java
javac ComboBoxTypeMismatch.java
java -cp . ComboBoxTypeMismatch
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at Controller$1.toString(Controller.java:14)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ComboBoxListViewSkin.java:388)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.access$100(ComboBoxListViewSkin.java:57)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$2$1.updateItem(ComboBoxListViewSkin.java:425)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)
有没有编译器生成的魔法
事实上,这就是原因:
通常,每个文件应该有一个类。这意味着每个.java文件在编译后都会生成一个.class文件
现在,您的文件Controller.java至少包含两个类:Controller
和一个匿名类:newstringconverter(){…}代码>。因此,在编译Controller.java时,输出必须存储在两个文件中
java编译器命名第二个文件的约定是:enclosuringclass$n.class,其中n是封闭类中的第n个匿名类
如果进入bin目录,您将看到两个文件:Controller.class和Controller$1.class(可能还有更多)
为什么在第1行报告这一点,控制器本身不是通用的,只是
它的领域
正如您所说,这似乎是一个特定的编译器版本问题
FXML构建过程如何构建正确格式的组合框
类型作为泛型仅存在于编译类型
什么是泛型药?在代码中声明了组合框
有没有编译器生成的魔法
事实上,这就是原因:
通常,每个文件应该有一个类。这意味着每个.java文件在编译后都会生成一个.class文件
现在,您的文件Controller.java至少包含两个类:Controller
和一个匿名类:newstringconverter(){…}代码>。因此,在编译Controller.java时,输出必须存储在两个文件中
java编译器命名第二个文件的约定是:enclosuringclass$n.class,其中n是封闭类中的第n个匿名类
如果进入bin目录,您将看到两个文件:Controller.class和Controller$1.class(可能还有更多)
为什么在第1行报告这一点,控制器本身不是通用的,只是
它的领域
正如您所说,这似乎是一个特定的编译器版本问题
FXML构建过程如何构建正确格式的组合框
类型作为泛型仅存在于编译类型
什么是泛型药?在您的代码中,您声明的组合框
您的StringConverter对我来说没有任何意义。您想在这里实现什么?这只是一个包含StringConverter的自包含示例,其细节并不重要。真正的应用程序是数万行自定义类型…为什么要将StringConverter附加到一个值已经是字符串的组合框上?字符串值是一个团队仅将FXML设计作为原型留下的示例。。。实际的开发人员希望使用正确的类型,这些类型是数据库中的动态类型,而不是静态类型。问题的重点是理解堆栈跟踪“第1行”和泛型…我不太确定您的项目结构,但当我尝试复制相同的问题时,我得到了一个异常Controller$1.toString(Controller.java:20)
,而不是第1行
您的StringConverter对我来说没有任何意义。您想在这里实现什么?这只是一个包含StringConverter的自包含示例,其细节并不重要。真正的应用是
javac Controller.java
javac ComboBoxTypeMismatch.java
java -cp . ComboBoxTypeMismatch
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at Controller$1.toString(Controller.java:14)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ComboBoxListViewSkin.java:388)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.access$100(ComboBoxListViewSkin.java:57)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$2$1.updateItem(ComboBoxListViewSkin.java:425)
at javafx.scene.control.ListCell.updateItem(ListCell.java:471)