TL DR: In java, it is easy to disable type safety by type parameters. Scala will not allow you to do this without performing an explicit cast. In addition, using Table.getColumns to retrieve a column means that we are losing the type of cell. Solutions: TableColumn instance to the appropriate type or create the column instance manually.
The first problem is the signature of Table.getColumns : it returns a ObservableList[TableColumn[S,_]] (see http://docs.oracle.com/javafx/2/api/javafx/scene/control/TableView.html# getColumns ()). So your c val is introduced as TableColumn[Foo,_] . This means that you are losing the type of cell content (indicated by the parameter of the second type).
The only solution here is to enter column ( c ) correctly with cast:
val c = test.getColumns.get(0).asInstanceOf[TableColumn[Foo, String]] c.setCellValueFactory(new PropertyValueFactory[Foo, String]("message"))
This is quite logical: you have a list of columns in which each column can contain objects of a different type. We would encounter the same dilemma with a scala List containing objects of different types, all unknown a priori: only listing (or matching a type that is hidden cast) will allow you to return a specific type at compile time.
Also note that in many JavaFx examples on the Internet, people do not retrieve columns through Table.getColumns . Instead, they copy them manually, and then click setCellValueFactory right after it. Performing the same task will help solve your problem (without any need for a cast), since you yourself will specify parameters like:
val c = new TableColumn[Foo, String] // See ma, no cast! c.setCellValueFactory(new PropertyValueFactory[Foo, String]("message"))
Now you can look at some Java examples and notice that they do not provide the any parameter when creating their TableColumn :
TableColumn c = new TableColumn(); c.setCellValueFactory( new PropertyValueFactory<Foo,String>("name"));
And indeed, it compiles. How so? Well, the sad truth is that the above code is not safer than casting, as it relies on Java backward compatibility for classes that support pre-generics. In other words, since c is typed as simply a TableColumn , rather than a TableColumn<?, String> , for example, the java compiler considers it to be not a general class and does not perform type checking on parameters of type TableColumn . Compare this to what happens if you explicitly set type c to a generic type (but with a cell type of unknwon):
TableColumn<Foo, ?> name = new TableColumn("Name"); name.setCellValueFactory( new PropertyValueFactory<Room,String>("name"));
In this case, the compiler throws a type mismatch error:
error: method setCellValueFactory in class TableColumn<S,T> cannot be applied to given types; ...
It's like in scala when c is typed like TableColumn [Foo, _]