加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala中的JavaFX 2和setCellValueFactory()?

发布时间:2020-12-16 18:11:41 所属栏目:安全 来源:网络整理
导读:我正在尝试遵循此 JavaFX 2指南: http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE 我使用Scala而不是Java,对我来说它看起来像这样: TableView fx:id="test" columns TableColumn prefWidth="75.0" text="Message" / /columns/TableV
我正在尝试遵循此 JavaFX 2指南:

http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE

我使用Scala而不是Java,对我来说它看起来像这样:

<TableView fx:id="test">
     <columns>
         <TableColumn prefWidth="75.0" text="Message" />
     </columns>
</TableView>

和代码:

val c = test.getColumns.get(0) // Get the first column.
c.setCellValueFactory(new PropertyValueFactory[Foo,_]("message")) // Foo is my model with a single SimpleStringProperty called "message".

val observableFoos = FXCollections.observableList(foos)
test.setItems(observableFoos)

我遇到的问题是setCellValueFactory行导致:

error: class type required but
javafx.scene.control.cell.PropertyValueFactory[com.myapp.models.Foo,
_] found c.setCellValueFactory(new PropertyValueFactoryFoo,_)

我不明白我应该如何使用这种方法.如果我用String替换_,那么我得到:

error: type mismatch; found :
javafx.scene.control.cell.PropertyValueFactory[com.myapp.models.Foo,String]
required:
javafx.util.Callback[javafx.scene.control.TableColumn.CellDataFeatures[com.myapp.models.Foo,?0],javafx.beans.value.ObservableValue[?0]]
where type ?0 c.setCellValueFactory(new PropertyValueFactoryFoo,
String)

我可以确认一切正常,如果我删除setCellValueFactory行 – 我只是没有在表中看到任何内容 – 只是按预期的空白行..

解决方法

TL; DR:在类型参数方面,java很容易默默地绕过类型安全.
除了执行显式演员之外,Scala不会让你这样做.
另外,使用Table.getColumns来检索列意味着我们失去了单元格的类型.
解决方案:将TableColumn实例强制转换为正确的类型,或手动实例化该列.

第一个问题在于Table.getColumns的签名:它返回一个ObservableList [TableColumn [S,_]](参见http://docs.oracle.com/javafx/2/api/javafx/scene/control/TableView.html#getColumns()).
所以你的c val被输入为TableColumn [Foo,_].
这意味着您将丢失单元格内容的类型(由第二个类型参数表示).

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

val c = test.getColumns.get(0).asInstanceOf[TableColumn[Foo,String]]
c.setCellValueFactory(new PropertyValueFactory[Foo,String]("message"))

这是非常合乎逻辑的:您有一个列列表,其中每列可以包含不同类型的对象.我们将面临同样的困境,scala List包含不同类型的对象,所有这些都是先验未知的:只有一个强制转换(或类型上的匹配,这是一个伪装的强制转换)将让你在编译时返回一个特定的类型时间.

另请注意,在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"));

确实它确实编译了.怎么会这样?令人遗憾的事实是,上面的代码并不比执行转换更安全,因为它依赖于java对预先通用的感知类的向后兼容性.
换句话说,因为c的类型只是TableColumn而不是TableColumn<?,String>例如,java编译器将其视为非泛型类,而不执行任何有关TableColumn类型参数的类型检查.
将此与您明确将c的类型设置为泛型类型(但使用unknwon单元格类型)时的情况进行对比:

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;
...

当c类型为TableColumn [Foo,_]时,这就像在scala中一样

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读