java javafx.scene.control.TableColumn 不能转换为 javafx.scene.control.TableColumn$CellDataFeatures
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32398007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javafx.scene.control.TableColumn cannot be cast to javafx.scene.control.TableColumn$CellDataFeatures
提问by Do Re
I have a problem when it comes to filling a javafx tableview.
我在填充 javafx tableview 时遇到问题。
I am currently working on a GUI based event management tool (for university) and I am stuck trying to fill a Tableview list, that should be in the center of a border pane layout.
我目前正在开发基于 GUI 的事件管理工具(适用于大学),但我一直在尝试填充 Tableview 列表,该列表应该位于边框窗格布局的中心。
This is my code (its pretty long thought, its the main window function):
这是我的代码(它的想法很长,它的主窗口函数):
import java.sql.Date;
import java.sql.SQLException;
import java.util.List;
//--main imports--//
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
//--table imports--//
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.TableColumn;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class MainWindow extends Application {
private static Label tableHeadline;
private static TableView table;
private static TableColumn dateCol;
private static TableColumn nameCol;
private static TableColumn numberOfGuestsCol;
private static TableColumn locationCol;
private static BorderPane layout;
//This is just some test data, this is where the program crashes, I think
final static ObservableList<Event> data = FXCollections.observableArrayList(
new Event("Jacob", "Smith", 30, new Date(10000))
);
//----------------------//
//--Private constants--//
private static final String DATE = "Date";
private static final String NAME = "Name";
private static final String NUMBER_OF_GUESTS = "Number of guests";
private static final String LOCATION = "Location";
//---------------------//
/**The main method, launching the application*/
public static void main(String[] args) {
try {
//--launching the application with given arguments--//
launch(args);}
catch (Exception e) {e.printStackTrace();}
}
/**
* The start-method, that is called first when 'launch' is used
*/
@Override
public void start(Stage primaryWindow) throws Exception {
//--initialize all the objects in the window--//
initializeObjects();
//--get the layout--//
initializeLayout();
//--give functionality to the objects in the window--//
functionalizeObjects();
//--create the new scene--//
Scene main = new Scene(layout);
//--Giving the main window a title and bringing it up front--//
primaryWindow.setMinHeight(DEFAULT_WIN_HEIGHT);
primaryWindow.setMinWidth(DEFAULT_WIN_WIDTH);
primaryWindow.setScene(main);
primaryWindow.show();
//TODO: on window close, save the content of the list to the db
primaryWindow.setOnCloseRequest(null);
}
/**
* Initializes all given elements of the main window by creating and naming them
*/
private static void initializeObjects () {
//--table--//
tableHeadline = new Label (TABLE_HEAD);
tableHeadline.setFont(new Font ("Arial", 20));
table = new TableView<>();
table.setEditable(true);
//--date column--//
dateCol = new TableColumn<Event, Date>(DATE);
dateCol.setCellFactory(
new PropertyValueFactory<>("Date")
);
//--name column--//
nameCol = new TableColumn<Event, String>(NAME);
nameCol.setCellValueFactory(
new PropertyValueFactory<>("name")
);
//--numberOfGuests column--//
numberOfGuestsCol = new TableColumn<Event, Integer>(NUMBER_OF_GUESTS);
numberOfGuestsCol.setMinWidth(150);
numberOfGuestsCol.setCellValueFactory(
new PropertyValueFactory<>("Number of Guests")
);
//--location column--//
locationCol = new TableColumn<Event, String>(LOCATION);
locationCol.setCellValueFactory(
new PropertyValueFactory<>("location")
);
table.setItems(data);
table.getColumns().addAll(nameCol,locationCol,
numberOfGuestsCol,dateCol);
//TODO fill with data from the database
//--end table--//
}
/**
* Assign functionality to the elements of the main window
*/
private static void functionalizeObjects () {
//--new... MenuItem--//
newMItem.setOnAction(e -> {
createReturn = CreatePopup.display();
if (createReturn) {
//--get the user input--//
List<Object> toCreate = CreatePopup.getInput();
//--add a new event according to the user input to the list--//
//This is where new Events should be inserted, but I cannot test this as I do not come that far
final ObservableList<Event>data = FXCollections.ObservableArrayList(
new Event(toCreate(0),toCreate(1),toCreate(2),toCreate(3))
);
}
}
});
});
}
/**
* Initializes the layout of the main window
*/
private static void initializeLayout() {
//--Create a new layout--//
layout = new BorderPane();
layout.setTop(menuBar);
layout.setCenter(table);
}
public static class Event {
private final SimpleStringProperty name;
private final SimpleStringProperty location;
private final SimpleIntegerProperty numberOfGuests;
private final SimpleObjectProperty<Date> date;
private Event(String name, String location, int numOfGuests, Date date) {
this.name = new SimpleStringProperty(name);
this.location = new SimpleStringProperty(location);
this.numberOfGuests = new SimpleIntegerProperty(numOfGuests);
this.date = new SimpleObjectProperty<Date>(date);
}
//--------//
// Getter //
//--------//
public SimpleStringProperty getName() {
return name;
}
public SimpleStringProperty getLocation() {
return location;
}
public SimpleIntegerProperty getNumberOfGuests() {
return numberOfGuests;
}
public SimpleObjectProperty<Date> getDate() {
return date;
}
}
}
This code will give me an error:
这段代码会给我一个错误:
Exception in Application start method
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: javafx.scene.control.TableColumn cannot be cast to javafx.scene.control.TableColumn$CellDataFeatures
at javafx.scene.control.cell.PropertyValueFactory.call(PropertyValueFactory.java:98)
at com.sun.javafx.scene.control.skin.TableRowSkin.getCell(TableRowSkin.java:87)
at com.sun.javafx.scene.control.skin.TableRowSkin.getCell(TableRowSkin.java:53)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.createCell(TableRowSkinBase.java:698)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.recreateCells(TableRowSkinBase.java:692)
at com.sun.javafx.scene.control.skin.TableRowSkinBase.init(TableRowSkinBase.java:146)
at com.sun.javafx.scene.control.skin.TableRowSkin.<init>(TableRowSkin.java:64)
at javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:212)
at javafx.scene.control.Control.impl_processCSS(Control.java:859)
at javafx.scene.Parent.impl_processCSS(Parent.java:1272)
at javafx.scene.Parent.impl_processCSS(Parent.java:1272)
at javafx.scene.Parent.impl_processCSS(Parent.java:1272)
at javafx.scene.control.Control.impl_processCSS(Control.java:855)
at javafx.scene.Node.processCSS(Node.java:9056)
at javafx.scene.Node.processCSS(Node.java:9049)
at javafx.scene.Scene.doCSSPass(Scene.java:545)
at javafx.scene.Scene.access00(Scene.java:159)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2392)
at com.sun.javafx.tk.Toolkit.lambda$runPulse(Toolkit.java:348)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:347)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:374)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit5(QuantumToolkit.java:319)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:139)
at java.lang.Thread.run(Thread.java:745)
I cannot think of any reason for this strange Error. I also searched pretty long now and tried pretty many things, but it still appears on startup.
我想不出这个奇怪错误的任何原因。我现在也搜索了很长时间并尝试了很多东西,但它仍然出现在启动时。
Now I am counting on you, community, please help me!
现在我指望你了,社区,请帮助我!
Thanks in advance for reading the long post..
提前感谢您阅读长篇文章..
回答by James_D
You have
你有
dateCol.setCellFactory(...);
instead of
代替
dateCol.setCellValueFactory(...);
This is a good example of why you should not use raw types in your code, and should avoid API like PropertyValueFactory
in favor of typesafe code.
这是一个很好的例子,说明为什么你不应该在你的代码中使用原始类型,而应该避免使用 API 之类的 API,而使用类型PropertyValueFactory
安全代码。
I.e. you have
即你有
TableView table ;
TableColumn dateCol ;
when you should have something like
当你应该有类似的东西
TableView<Event> table ;
TableColumn<Event, Date> dateCol ;
And then you can do
然后你可以做
dateCol.setCellValueFactory(cellData -> cellData.getValue().getDate());
If you coded it this way, the compiler would have immediately picked up on your error.
如果您以这种方式编码,编译器会立即发现您的错误。
As an aside (perhaps, another aside), you should really make your Event
class follow the correct JavaFX Properties pattern, as described in the tutorial. You may see unexpected behavior if you don't.
顺便说一句(也许是另一边),您真的应该让您的Event
类遵循正确的 JavaFX 属性模式,如教程中所述。如果不这样做,您可能会看到意外行为。
回答by user12421954
For the future people and Java 11 you can may fix this with that:
对于未来的人和 Java 11,您可以通过以下方式解决此问题:
For example, if the Person class is in the com.foo package in the foo.app module, the module-info.java might look like this:
例如,如果 Person 类位于 foo.app 模块的 com.foo 包中,则 module-info.java 可能如下所示:
module foo.app {
opens com.foo to javafx.base;
}
module foo.app {
opens com.foo to javafx.base;
}
or:
或者:
module foo.app {
opens com.foo; <-- place for with your class
}
https://openjfx.io/javadoc/11/javafx.controls/javafx/scene/control/cell/PropertyValueFactory.html
https://openjfx.io/javadoc/11/javafx.controls/javafx/scene/control/cell/PropertyValueFactory.html