错误:类型不匹配:无法从SimpleStringProperty
转换为ObservableValue<Object>
。
我正在尝试使用管理各种数据类型的列创建TreeTableView。这意味着每行可以使用三种类型的数据之一(String
,int
,StringProperty
或ObjectProperty< LocalDate >
。
鉴于我的数据类型是&#34;对象&#34;然后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)
答案 0 :(得分:2)
对于TreeTableColumn<S,T>
,cellValueFactory
的类型为Callback<CellDataFeatures<S,T>, ObservableValue<S,T>>
,它本质上是一个以[{1}}为例并返回CellDataFeatures<S,T>
的函数。
您的ObservableValue<S,T>
为colName
,因此TreeTableColumn<Pair<Object, Object>, String>
为S
,Pair<Object, Object>
为T
。因此,String
的{{1}}是一个功能,可以使用cellValueFactory
个实例(您调用colName
)并返回CellDataFeatures<Pair<Object, Object>>
。
您的实施存在多个问题。第一个是,如果声明为cellDataFeatures
的{{1}}不是ObservableValue<String>
或item
的实例,那么代码实际上永远不会达到{{1}声明。所以这甚至不是一个有效的lambda表达式。
第二个问题是,如果Object
是String
个实例(第一个StringProperty
语句),则会返回return
,而不是item
,所以你回错了类型。
所以至少要编译的实现是
String
同样,对于if
,您的代码路径永远不会到达return语句,因此您尚未定义有效的lambda表达式。在这种情况下,String
为ObservableValue<String>
,因此 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
,返回类型必须为colData
。您的各种TreeTableColumn<Pair<Object, Object>, Object>
阻止尝试返回T
,Object
,ObservableValue<Object>
,(或某些待确定的内容),而这些都不是if
的实例。
实际编译的实现是
String