使用通用对象类型的 TableColumn 的 CellValueFactory?
CellValueFactory of a TableColumn using a generic Object type?
错误:类型不匹配:无法从 SimpleStringProperty
转换为 ObservableValue<Object>
。
我正在尝试创建一个 TreeTableView,其中包含一个管理各种数据类型的列。这意味着每一行可以使用三种左右数据类型中的一种(String
、int
、StringProperty
或 ObjectProperty< LocalDate >
。
鉴于我的数据类型是 "Object",那么 setCellValueFactory( cellDataFeatures -> { return ...; })
需要一个 ObservableValue< Object >
。我不知所措地试图从 CellValueFactory 回调的属性中获取所需的 ObservableValue。 :(
This post 建议使用 ReadOnlyStringWrapper
但我想保留可编辑的值(在大多数情况下)。我还找到了有关 #asObject()
方法的建议,该方法在 StringProperty 中不可用。
/*-------------------------+------------+
| columnPeople | columnData |
+-------------------------+------------+
| | |
| + Bob Rozz ============ | 33 ======= |
| + SKILLS | |
| + testskill 1 | 0.7 |
| | 3/14/2017 |
| + testskill 2 | |
| | 0.9 |
| | 3/11/2017 |
| | |
| + Bob Dilly =========== | 34 ======= |
| + SKILLS | |
| + testskill 1 | 0.6 |
| | 3/10/2017 |
| + testskill 2 | |
| | 0.5 |
| | 3/17/2017 |
+-------------------------+------------+
*/
注意 1: 尚未处理 setCellFactory(...)
。
Note2: 就目前而言,我意识到这个例子是不切实际的。作为所需功能的示例,它完全独立于我的项目。
package testGenericTableTreeColumn;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TextFieldTreeTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Pair;
import javafx.util.converter.DefaultStringConverter;
public class testGenericTableTreeColumn extends javafx.application.Application {
class Skill {
private StringProperty name = new SimpleStringProperty( "" );
public final String getName(){ return this.name.get(); }
public final void setName( String v ){ name.set(v); return; }
public StringProperty nameProperty(){ return this.name; }
private SimpleFloatProperty value = new SimpleFloatProperty( 0f );
public final String getValue(){ return this.name.get(); }
public final void setValue( String v ){ name.set(v); return; }
public StringProperty valueProperty(){ return this.name; }
private SimpleObjectProperty< LocalDate > date = new SimpleObjectProperty< LocalDate >( LocalDate.now() );//LocalDate date = LocalDate.now();
public final String getDate(){ return this.name.get(); }
public final void setDate( String v ){ name.set(v); return; }
public StringProperty dateProperty(){ return this.name; }
public Skill( String name ){
java.util.Random r = new java.util.Random();
this.name .set( name ); //this.name = name;
this.value .set( 100 * ( r.nextFloat() )); //this.value = 100 * ( r.nextFloat() );
this.date .get().minusWeeks( r.nextInt(10) ); //date.minusWeeks( r.nextInt(10) );
return;
}
}
class Person {
private StringProperty name = new SimpleStringProperty( "" );
public final String getName() { return this.name.get(); }
public final void setName( String v ){ name.set(v); return; }
public StringProperty nameProperty() { return this.name; }
private IntegerProperty age = new SimpleIntegerProperty( 0 );
public final int getAge() { return this.age.get(); }
public final void setAge( int v ) { age.set(v); return; }
public IntegerProperty ageProperty() { return this.age; }
public List< Skill > skills = new ArrayList<>();
public Person( String name, int age ){
this.name .set( name );
this.age .set( age );
skills.add( new Skill( "testskill 1" ));
skills.add( new Skill( "testskill 2" ));
return;
}
}
public TreeTableView< Pair< Object, Object >> table = new TreeTableView<>();
@Override public void start( Stage primaryStage ){
TreeItem< Pair< Object, Object >> itemRoot = new TreeItem<>( new Pair<>( "PEOPLE", null ));
this.table.setRoot( itemRoot );
Person person1 = new Person( "Bob Rozz" ,33 );
Person person2 = new Person( "Bob Dilly" ,34 );
List< Person > people = new ArrayList<>();
people.add( person1 );
people.add( person2 );
/*-------------------------+------------+
| columnPeople | columnData |
+-------------------------+------------+
| | |
| + Bob Rozz ============ | 33 ======= |
| + SKILLS | |
| + testskill 1 | 0.7 |
| | 3/14/2017 |
| + testskill 2 | |
| | 0.9 |
| | 3/11/2017 |
| | |
| + Bob Dilly =========== | 34 ======= |
| + SKILLS | |
| + testskill 1 | 0.6 |
| | 3/10/2017 |
| + testskill 2 | |
| | 0.5 |
| | 3/17/2017 |
+-------------------------+------------+
*/
for ( Person person : people ){
TreeItem< Pair< Object, Object >> treeItemPerson = new TreeItem<>( new Pair< Object, Object >( person.nameProperty(), person.ageProperty() ));
TreeItem< Pair< Object, Object >> treeItemSkills = new TreeItem<>( new Pair< Object, Object >( "Skills" , null ));
itemRoot .getChildren().add( treeItemPerson );
treeItemPerson .getChildren().add( treeItemSkills );
for ( Skill skill : person.skills ){
TreeItem< Pair< Object, Object >> treeItemSkillName = new TreeItem<>( new Pair< Object, Object >( null, skill.nameProperty () ));
TreeItem< Pair< Object, Object >> treeItemSkillValue = new TreeItem<>( new Pair< Object, Object >( null, skill.valueProperty () ));
TreeItem< Pair< Object, Object >> treeItemSkillDate = new TreeItem<>( new Pair< Object, Object >( null, skill.dateProperty () ));
treeItemSkills .getChildren().add( treeItemSkillName );
treeItemSkillName .getChildren().add( treeItemSkillDate );
treeItemSkillName .getChildren().add( treeItemSkillValue );
}
}
TreeTableColumn< Pair< Object, Object>, String > colName = new TreeTableColumn<>("People"); colName.setMinWidth(100);
colName.setCellValueFactory( cellDataFeatures -> {
// Could be a String, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getKey();
//String
if ( item instanceof String ){
/* ERROR */ return ( String ) item; //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//StringProperty
if ( item instanceof StringProperty ){
/* ERROR */ return (( StringProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
});
TreeTableColumn< Pair< Object, Object>, Object > colData = new TreeTableColumn<>("Skills"); colData.setMinWidth(200);
colData.setCellValueFactory( cellDataFeatures -> {
//itemKey : Could be a String, IntegerProperty, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getValue();
//String
if ( item instanceof String ){
/* ERROR */ return (String) item; //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//IntegerProperty
if ( item instanceof IntegerProperty ){
/* ERROR */ return (( IntegerProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleIntegerProperty to ObservableValue< Object >
}
//StringProperty
if ( item instanceof StringProperty ){
/* ERROR */ return (( StringProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//ObjectProperty< LocalDate >
if ( item instanceof ObjectProperty< ? >){
Object value = (( ObjectProperty<?> ) item ).getBean();
if ( value instanceof LocalDate ){
//@TODO LocalDate cell
}
}
});
/*
//colData.setCellFactory( new Callback< TreeTableColumn< Person, Object >, TreeTableCell< Person, Object >>());
colData.setCellFactory( column -> {
TreeTableCell< Object, Object > cell = new TreeTableCell< Object, Object >(){
@Override protected void updateItem( Object newValue, boolean empty ){
this.setEditable( false );
super.updateItem( newValue, empty );
if ( empty || newValue == null ){
setText ( null );
setGraphic ( null );
return;
}
if ( newValue instanceof String ){
return;
}
this.setEditable( true );
if ( newValue instanceof LocalDate ){
return;
}
return;
} // updateItem( ... );
};
});
// */
// Type safety: A generic array of Table... is created for a varargs
// parameter
// -> @SuppressWarnings("unchecked") to start method!
table.getColumns().addAll( colName, colData );
// Output in console the selected table view's cell value/class to check
// that the data type is correct.
// SystemOutTreeTableViewSelectedCell.set(tableView);
/*
// To check that table view is correctly refreshed on data changed..
final Button agePlusOneButton = new Button("Age +1");
agePlusOneButton.setOnAction((ActionEvent e) -> {
Person<?> person = tableView.getSelectionModel().getSelectedItem();
try {
person.setAge(person.getAge() + 1);
} catch (NullPointerException npe ){
//
}
});
*/
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll( table );
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().addAll(vbox);
primaryStage.setWidth(600);
primaryStage.setHeight(750);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
错误:
Description Resource Path Location Type
Type mismatch: cannot convert from IntegerProperty to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 300 Java Problem
Type mismatch: cannot convert from String to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 295 Java Problem
Type mismatch: cannot convert from String to ObservableValue<String> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 278 Java Problem
Type mismatch: cannot convert from StringProperty to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 305 Java Problem
Java版本:
java version "1.8.0_121" Java(TM)
SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
对于 TreeTableColumn<S,T>
,cellValueFactory
的类型为 Callback<CellDataFeatures<S,T>, ObservableValue<S,T>>
,它本质上是一个采用 CellDataFeatures<S,T>
和 return 实例的函数ObservableValue<S,T>
.
你的colName
是TreeTableColumn<Pair<Object, Object>, String>
,所以S
是Pair<Object, Object>
,T
是String
。所以 colName
的 cellValueFactory
是一个接受 CellDataFeatures<Pair<Object, Object>>
实例(你称之为 cellDataFeatures
)和 returning ObservableValue<String>
.[= 的函数49=]
您的实施存在多个问题。第一个是如果声明为 Object
的 item
不是 String
或 StringProperty
的实例,那么代码实际上永远不会到达 [=32] =] 语句。所以这甚至不是一个有效的 lambda 表达式。
第二个问题是如果item
是一个String
实例(第一个if
语句),你return一个String
,它不是一个 ObservableValue<String>
,所以你 return 输入错误的类型。
所以至少可以编译的实现是
TreeTableColumn< Pair< Object, Object>, String > colName = new TreeTableColumn<>("People"); colName.setMinWidth(100);
colName.setCellValueFactory( cellDataFeatures -> {
// Could be a String, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getKey();
//String
if ( item instanceof String ){
return new SimpleStringProperty(( String ) item);
}
//StringProperty
if ( item instanceof StringProperty ){
return (( StringProperty ) item );
}
// must return something: you probably don't want to return null though, so you should fix this as needed.
return null ;
});
同样,对于 colData
,您的代码路径永远不会到达 return 语句,因此您没有定义有效的 lambda 表达式。在这种情况下,colData
是一个 TreeTableColumn<Pair<Object, Object>, Object>
,因此 T
是 Object
,并且 return 类型必须是 ObservableValue<Object>
。您的各种 if
块尝试 return String
、IntegerProperty
、StringProperty
(或待定的东西),其中 none ObservableValue<Object>
的实例。
实际编译的实现是
TreeTableColumn< Pair< Object, Object>, Object > colData = new TreeTableColumn<>("Skills"); colData.setMinWidth(200);
colData.setCellValueFactory( cellDataFeatures -> {
//itemKey : Could be a String, IntegerProperty, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getValue();
//String
if ( item instanceof String ){
return new SimpleObjectProperty<>( item );
}
//IntegerProperty
if ( item instanceof IntegerProperty ){
return new SimpleObjectProperty<>(((IntegerProperty) item).getValue());
}
//StringProperty
if ( item instanceof StringProperty ){
return new SimpleObjectProperty<>(((IntegerProperty) item).getValue());
}
//ObjectProperty< LocalDate >
if ( item instanceof ObjectProperty< ? >){
Object value = (( ObjectProperty<?> ) item ).getBean();
if ( value instanceof LocalDate ){
//@TODO LocalDate cell
}
}
// TODO return something appropriate here
return null ;
});
错误:类型不匹配:无法从 SimpleStringProperty
转换为 ObservableValue<Object>
。
我正在尝试创建一个 TreeTableView,其中包含一个管理各种数据类型的列。这意味着每一行可以使用三种左右数据类型中的一种(String
、int
、StringProperty
或 ObjectProperty< LocalDate >
。
鉴于我的数据类型是 "Object",那么 setCellValueFactory( cellDataFeatures -> { return ...; })
需要一个 ObservableValue< Object >
。我不知所措地试图从 CellValueFactory 回调的属性中获取所需的 ObservableValue。 :(
This post 建议使用 ReadOnlyStringWrapper
但我想保留可编辑的值(在大多数情况下)。我还找到了有关 #asObject()
方法的建议,该方法在 StringProperty 中不可用。
/*-------------------------+------------+
| columnPeople | columnData |
+-------------------------+------------+
| | |
| + Bob Rozz ============ | 33 ======= |
| + SKILLS | |
| + testskill 1 | 0.7 |
| | 3/14/2017 |
| + testskill 2 | |
| | 0.9 |
| | 3/11/2017 |
| | |
| + Bob Dilly =========== | 34 ======= |
| + SKILLS | |
| + testskill 1 | 0.6 |
| | 3/10/2017 |
| + testskill 2 | |
| | 0.5 |
| | 3/17/2017 |
+-------------------------+------------+
*/
注意 1: 尚未处理 setCellFactory(...)
。
Note2: 就目前而言,我意识到这个例子是不切实际的。作为所需功能的示例,它完全独立于我的项目。
package testGenericTableTreeColumn;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TextFieldTreeTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Pair;
import javafx.util.converter.DefaultStringConverter;
public class testGenericTableTreeColumn extends javafx.application.Application {
class Skill {
private StringProperty name = new SimpleStringProperty( "" );
public final String getName(){ return this.name.get(); }
public final void setName( String v ){ name.set(v); return; }
public StringProperty nameProperty(){ return this.name; }
private SimpleFloatProperty value = new SimpleFloatProperty( 0f );
public final String getValue(){ return this.name.get(); }
public final void setValue( String v ){ name.set(v); return; }
public StringProperty valueProperty(){ return this.name; }
private SimpleObjectProperty< LocalDate > date = new SimpleObjectProperty< LocalDate >( LocalDate.now() );//LocalDate date = LocalDate.now();
public final String getDate(){ return this.name.get(); }
public final void setDate( String v ){ name.set(v); return; }
public StringProperty dateProperty(){ return this.name; }
public Skill( String name ){
java.util.Random r = new java.util.Random();
this.name .set( name ); //this.name = name;
this.value .set( 100 * ( r.nextFloat() )); //this.value = 100 * ( r.nextFloat() );
this.date .get().minusWeeks( r.nextInt(10) ); //date.minusWeeks( r.nextInt(10) );
return;
}
}
class Person {
private StringProperty name = new SimpleStringProperty( "" );
public final String getName() { return this.name.get(); }
public final void setName( String v ){ name.set(v); return; }
public StringProperty nameProperty() { return this.name; }
private IntegerProperty age = new SimpleIntegerProperty( 0 );
public final int getAge() { return this.age.get(); }
public final void setAge( int v ) { age.set(v); return; }
public IntegerProperty ageProperty() { return this.age; }
public List< Skill > skills = new ArrayList<>();
public Person( String name, int age ){
this.name .set( name );
this.age .set( age );
skills.add( new Skill( "testskill 1" ));
skills.add( new Skill( "testskill 2" ));
return;
}
}
public TreeTableView< Pair< Object, Object >> table = new TreeTableView<>();
@Override public void start( Stage primaryStage ){
TreeItem< Pair< Object, Object >> itemRoot = new TreeItem<>( new Pair<>( "PEOPLE", null ));
this.table.setRoot( itemRoot );
Person person1 = new Person( "Bob Rozz" ,33 );
Person person2 = new Person( "Bob Dilly" ,34 );
List< Person > people = new ArrayList<>();
people.add( person1 );
people.add( person2 );
/*-------------------------+------------+
| columnPeople | columnData |
+-------------------------+------------+
| | |
| + Bob Rozz ============ | 33 ======= |
| + SKILLS | |
| + testskill 1 | 0.7 |
| | 3/14/2017 |
| + testskill 2 | |
| | 0.9 |
| | 3/11/2017 |
| | |
| + Bob Dilly =========== | 34 ======= |
| + SKILLS | |
| + testskill 1 | 0.6 |
| | 3/10/2017 |
| + testskill 2 | |
| | 0.5 |
| | 3/17/2017 |
+-------------------------+------------+
*/
for ( Person person : people ){
TreeItem< Pair< Object, Object >> treeItemPerson = new TreeItem<>( new Pair< Object, Object >( person.nameProperty(), person.ageProperty() ));
TreeItem< Pair< Object, Object >> treeItemSkills = new TreeItem<>( new Pair< Object, Object >( "Skills" , null ));
itemRoot .getChildren().add( treeItemPerson );
treeItemPerson .getChildren().add( treeItemSkills );
for ( Skill skill : person.skills ){
TreeItem< Pair< Object, Object >> treeItemSkillName = new TreeItem<>( new Pair< Object, Object >( null, skill.nameProperty () ));
TreeItem< Pair< Object, Object >> treeItemSkillValue = new TreeItem<>( new Pair< Object, Object >( null, skill.valueProperty () ));
TreeItem< Pair< Object, Object >> treeItemSkillDate = new TreeItem<>( new Pair< Object, Object >( null, skill.dateProperty () ));
treeItemSkills .getChildren().add( treeItemSkillName );
treeItemSkillName .getChildren().add( treeItemSkillDate );
treeItemSkillName .getChildren().add( treeItemSkillValue );
}
}
TreeTableColumn< Pair< Object, Object>, String > colName = new TreeTableColumn<>("People"); colName.setMinWidth(100);
colName.setCellValueFactory( cellDataFeatures -> {
// Could be a String, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getKey();
//String
if ( item instanceof String ){
/* ERROR */ return ( String ) item; //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//StringProperty
if ( item instanceof StringProperty ){
/* ERROR */ return (( StringProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
});
TreeTableColumn< Pair< Object, Object>, Object > colData = new TreeTableColumn<>("Skills"); colData.setMinWidth(200);
colData.setCellValueFactory( cellDataFeatures -> {
//itemKey : Could be a String, IntegerProperty, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getValue();
//String
if ( item instanceof String ){
/* ERROR */ return (String) item; //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//IntegerProperty
if ( item instanceof IntegerProperty ){
/* ERROR */ return (( IntegerProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleIntegerProperty to ObservableValue< Object >
}
//StringProperty
if ( item instanceof StringProperty ){
/* ERROR */ return (( StringProperty ) item ); //ERROR: Type mismatch: cannot convert from SimpleStringProperty to ObservableValue< Object >
}
//ObjectProperty< LocalDate >
if ( item instanceof ObjectProperty< ? >){
Object value = (( ObjectProperty<?> ) item ).getBean();
if ( value instanceof LocalDate ){
//@TODO LocalDate cell
}
}
});
/*
//colData.setCellFactory( new Callback< TreeTableColumn< Person, Object >, TreeTableCell< Person, Object >>());
colData.setCellFactory( column -> {
TreeTableCell< Object, Object > cell = new TreeTableCell< Object, Object >(){
@Override protected void updateItem( Object newValue, boolean empty ){
this.setEditable( false );
super.updateItem( newValue, empty );
if ( empty || newValue == null ){
setText ( null );
setGraphic ( null );
return;
}
if ( newValue instanceof String ){
return;
}
this.setEditable( true );
if ( newValue instanceof LocalDate ){
return;
}
return;
} // updateItem( ... );
};
});
// */
// Type safety: A generic array of Table... is created for a varargs
// parameter
// -> @SuppressWarnings("unchecked") to start method!
table.getColumns().addAll( colName, colData );
// Output in console the selected table view's cell value/class to check
// that the data type is correct.
// SystemOutTreeTableViewSelectedCell.set(tableView);
/*
// To check that table view is correctly refreshed on data changed..
final Button agePlusOneButton = new Button("Age +1");
agePlusOneButton.setOnAction((ActionEvent e) -> {
Person<?> person = tableView.getSelectionModel().getSelectedItem();
try {
person.setAge(person.getAge() + 1);
} catch (NullPointerException npe ){
//
}
});
*/
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll( table );
Scene scene = new Scene(new Group());
((Group) scene.getRoot()).getChildren().addAll(vbox);
primaryStage.setWidth(600);
primaryStage.setHeight(750);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
错误:
Description Resource Path Location Type
Type mismatch: cannot convert from IntegerProperty to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 300 Java Problem
Type mismatch: cannot convert from String to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 295 Java Problem
Type mismatch: cannot convert from String to ObservableValue<String> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 278 Java Problem
Type mismatch: cannot convert from StringProperty to ObservableValue<Object> testGenericTableTreeColumn.java /testGenericTableTreeColumn/src/testGenericTableTreeColumn line 305 Java Problem
Java版本:
java version "1.8.0_121" Java(TM)
SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
对于 TreeTableColumn<S,T>
,cellValueFactory
的类型为 Callback<CellDataFeatures<S,T>, ObservableValue<S,T>>
,它本质上是一个采用 CellDataFeatures<S,T>
和 return 实例的函数ObservableValue<S,T>
.
你的colName
是TreeTableColumn<Pair<Object, Object>, String>
,所以S
是Pair<Object, Object>
,T
是String
。所以 colName
的 cellValueFactory
是一个接受 CellDataFeatures<Pair<Object, Object>>
实例(你称之为 cellDataFeatures
)和 returning ObservableValue<String>
.[= 的函数49=]
您的实施存在多个问题。第一个是如果声明为 Object
的 item
不是 String
或 StringProperty
的实例,那么代码实际上永远不会到达 [=32] =] 语句。所以这甚至不是一个有效的 lambda 表达式。
第二个问题是如果item
是一个String
实例(第一个if
语句),你return一个String
,它不是一个 ObservableValue<String>
,所以你 return 输入错误的类型。
所以至少可以编译的实现是
TreeTableColumn< Pair< Object, Object>, String > colName = new TreeTableColumn<>("People"); colName.setMinWidth(100);
colName.setCellValueFactory( cellDataFeatures -> {
// Could be a String, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getKey();
//String
if ( item instanceof String ){
return new SimpleStringProperty(( String ) item);
}
//StringProperty
if ( item instanceof StringProperty ){
return (( StringProperty ) item );
}
// must return something: you probably don't want to return null though, so you should fix this as needed.
return null ;
});
同样,对于 colData
,您的代码路径永远不会到达 return 语句,因此您没有定义有效的 lambda 表达式。在这种情况下,colData
是一个 TreeTableColumn<Pair<Object, Object>, Object>
,因此 T
是 Object
,并且 return 类型必须是 ObservableValue<Object>
。您的各种 if
块尝试 return String
、IntegerProperty
、StringProperty
(或待定的东西),其中 none ObservableValue<Object>
的实例。
实际编译的实现是
TreeTableColumn< Pair< Object, Object>, Object > colData = new TreeTableColumn<>("Skills"); colData.setMinWidth(200);
colData.setCellValueFactory( cellDataFeatures -> {
//itemKey : Could be a String, IntegerProperty, StringProperty, or ObjectProperty< LocalDate >
Object item = cellDataFeatures.getValue().getValue().getValue();
//String
if ( item instanceof String ){
return new SimpleObjectProperty<>( item );
}
//IntegerProperty
if ( item instanceof IntegerProperty ){
return new SimpleObjectProperty<>(((IntegerProperty) item).getValue());
}
//StringProperty
if ( item instanceof StringProperty ){
return new SimpleObjectProperty<>(((IntegerProperty) item).getValue());
}
//ObjectProperty< LocalDate >
if ( item instanceof ObjectProperty< ? >){
Object value = (( ObjectProperty<?> ) item ).getBean();
if ( value instanceof LocalDate ){
//@TODO LocalDate cell
}
}
// TODO return something appropriate here
return null ;
});