gpt4 book ai didi

Scala 中的 JavaFX 2 和 setCellValueFactory()?

转载 作者:搜寻专家 更新时间:2023-11-01 02:13:20 25 4
gpt4 key购买 nike

我正在尝试遵循此 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,我们会面临同样的困境,所有对象都是先验未知的:只有强制转换(或类型匹配,这是伪装的强制转换)才能让您在编译时返回特定类型时间。

另请注意,在网络上的许多 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 的类型时发生的情况进行对比到通用类型(但具有未知的单元格类型):

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

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

关于Scala 中的 JavaFX 2 和 setCellValueFactory()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12771556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com