Scala中的JavaFX2和setCellValueFactory()?

Scala中的JavaFX2和setCellValueFactory()?,java,scala,javafx-2,javafx,Java,Scala,Javafx 2,Javafx,我试图遵循以下JavaFX2指南: 我使用Scala而不是Java,对我来说是这样的: <TableView fx:id="test"> <columns> <TableColumn prefWidth="75.0" text="Message" /> </columns> </TableView> 我遇到的问题是,setCellValueFactory行导致: 错误:类类型是必需的,但 jav

我试图遵循以下JavaFX2指南:

我使用Scala而不是Java,对我来说是这样的:

<TableView fx:id="test">
     <columns>
         <TableColumn prefWidth="75.0" text="Message" />
     </columns>
</TableView>
我遇到的问题是,
setCellValueFactory
行导致:

错误:类类型是必需的,但 javafx.scene.control.cell.PropertyValueFactory[com.myapp.models.Foo, _]已找到c.setCellValueFactory(新属性ValueFactoryFoo,u0)

我不明白我该如何使用这种方法。如果我用
字符串
替换
,那么我得到:

错误:类型不匹配;发现: javafx.scene.control.cell.PropertyValueFactory[com.myapp.models.Foo,String] 必修的: javafx.util.Callback[javafx.scene.control.TableColumn.CellDataFeatures[com.myapp.models.Foo,?0],javafx.beans.value.observeValue[?0]] 其中类型?0 c.setCellValueFactory(新属性ValueFactoryFoo, (字符串)


如果我删除
setCellValueFactory
行,我可以确认一切正常--我只是看不到表中的任何内容--正如预期的那样,只是空白行。

我建议尝试使用长格式的
PropertyValueFactory

(很抱歉,我不熟悉用Java编写的Scala)


TL;DR:在java中,很容易在类型参数方面悄悄绕过类型安全性。 Scala不允许您这样做,除非执行显式强制转换。 此外,使用
Table.getColumns
检索列意味着我们将丢失单元格类型。 解决方案:将
TableColumn
实例强制转换为适当的类型,或者手动实例化该列

第一个问题在于
Table.getColumns
的签名:它返回一个
可观察列表[TableColumn[S,]]
(请参见())。 因此,您的
c
val被键入为
TableColumn[Foo,quo]
。 这意味着您将丢失单元格内容的类型(由第二个类型参数表示)

这里唯一的解决方案是使用强制转换正确键入列(
c
):

val c = test.getColumns.get(0).asInstanceOf[TableColumn[Foo, String]]
c.setCellValueFactory(new PropertyValueFactory[Foo, String]("message"))
这是非常合乎逻辑的:您有一个列列表,其中每个列可以包含不同类型的对象。对于包含不同类型对象的scala列表,我们将面临同样的困境,所有这些对象都是先验未知的:只有强制转换(或类型匹配,这是伪装的强制转换)才能让您在编译时返回特定类型

还请注意,在web上的许多JavaFx示例中,人们并不通过
Table.getColumns
检索列。相反,他们手动实例化它们,然后立即对其调用
setCellValueFactory
。 这样做可以解决您的问题(不需要强制转换),因为您将自己指定类型参数:

val c = new TableColumn[Foo, String] // See ma, no cast!
c.setCellValueFactory(new PropertyValueFactory[Foo, String]("message"))
现在,您可能会看到一些java示例,并注意到它们在实例化它们的
TableColumn
时实际上没有提供任何类型参数:

TableColumn c  = new TableColumn();    
c.setCellValueFactory( new PropertyValueFactory<Foo,String>("name"));
在这种情况下,编译器会发出类型不匹配错误:

error: method setCellValueFactory in class TableColumn<S,T> cannot be applied to given types;
...
错误:类TableColumn中的方法setCellValueFactory无法应用于给定类型;
...

这就像在scala中,
c
被类型化为TableColumn[Foo,_]

时一样,您也可以发布Foo类吗?这并不能解决问题:如果类型与
PropertyValueFactory[Foo,String]
不匹配,则类型与
回调[TableColumn.CellDataFeatures[Foo,String]不匹配,observeValue[String]
@RégisJean-Gilles。隐马尔可夫模型。。我并不是说这能解决问题。我们建议试试看。
val c = new TableColumn[Foo, String] // See ma, no cast!
c.setCellValueFactory(new PropertyValueFactory[Foo, String]("message"))
TableColumn c  = new TableColumn();    
c.setCellValueFactory( new PropertyValueFactory<Foo,String>("name"));
TableColumn<Foo, ?> name  = new TableColumn("Name");
name.setCellValueFactory( new PropertyValueFactory<Room,String>("name"));
error: method setCellValueFactory in class TableColumn<S,T> cannot be applied to given types;
...