问题
Im a pure newbie. I made my table by adding the columns from database with iteration:
public void captureDataSuper() {
Connection c;
ObservableList<ObservableList> data;
data = FXCollections.observableArrayList();
try {
c = KonekDB.createConnection();
//SQL FOR SELECTING ALL OF CUSTOMER
String SQL = "SELECT * from adminsupervisor";
//ResultSet
ResultSet rs = c.createStatement().executeQuery(SQL);
/**
* ********************************
* TABLE COLUMN ADDED DYNAMICALLY * ********************************
*/
for (int i = 0; i < rs.getMetaData().getColumnCount(); i++) {
//We are using non property style for making dynamic table
final int j = i;
TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i + 1));
//now its editable
col.setCellFactory(TextFieldTableCell.<Adminsupervisor>forTableColumn());
//trying to make effect on database after edited with setOnEditCommit
col.setOnEditCommit(
new EventHandler<CellEditEvent<Adminsupervisor, String>>() {
public void handle(CellEditEvent<Adminsupervisor, String> t) {
((Adminsupervisor) t.getTableView().getItems().get(
t.getTablePosition().getRow())).set(j, t.getNewValue());
}
}
);
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return new SimpleStringProperty(param.getValue().get(j).toString());
}
});
supervisorTable.getColumns().addAll(col);
System.out.println("Column [" + i + "] ");
}
/**
* ******************************
* Data added to ObservableList * ******************************
*/
while (rs.next()) {
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
//Iterate Column
row.add(rs.getString(i));
}
System.out.println("Row [1] added " + row);
data.add(row);
}
//FINALLY ADDED TO TableView
supervisorTable.setItems(data);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}
As you can see, my setOnEditCommit was completely non sense:
col.setOnEditCommit(
new EventHandler<CellEditEvent<Adminsupervisor, String>>() {
public void handle(CellEditEvent<Adminsupervisor, String> t) {
((Adminsupervisor) t.getTableView().getItems().get(
t.getTablePosition().getRow())).set(j, t.getNewValue());
}
}
);
This is the model class Adminsupervisor:
public class Adminsupervisor {
private String id;
private String username;
private String password;
private String userType;
public String getId() {
return id;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getUserType() {
return userType;
}
public void setId(String id) {
this.id = id;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setUserType(String userType) {
this.userType = userType;
}
void set(int j, String newValue) {
for (j = 0; j < 4; j++) {
if (j == 0) {
setId(newValue);
}
if (j == 2) {
setPassword(newValue);
}
if (j == 3) {
setUserType(newValue);
}
if (j == 1) {
setUsername(newValue);
}
}
try {
Connection c = KonekDB.createConnection();
String SQL = "UPDATE adminsupervisor SET "
+ "username=" + username + ","
+ "password=" + password + ","
+ "userType=" + userType + " WHERE id=" + id + "";
//ResultSet
c.createStatement().executeUpdate(SQL);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error on Building Data");
}
}}
I got this stack trace:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: com.sun.javafx.collections.ObservableListWrapper cannot be cast to AdminSide.Adminsupervisor
at AdminSide.PanelAdmin$1.handle(PanelAdmin.java:275)
at AdminSide.PanelAdmin$1.handle(PanelAdmin.java:272)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.control.TableCell.commitEdit(TableCell.java:349)
at javafx.scene.control.cell.CellUtils.lambda$createTextField$615(CellUtils.java:248)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at com.sun.javafx.scene.control.behavior.TextFieldBehavior.fire(TextFieldBehavior.java:179)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callAction(TextInputControlBehavior.java:178)
at com.sun.javafx.scene.control.behavior.BehaviorBase.callActionForEvent(BehaviorBase.java:218)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.callActionForEvent(TextInputControlBehavior.java:127)
at com.sun.javafx.scene.control.behavior.BehaviorBase.lambda$new$74(BehaviorBase.java:135)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$KeyHandler.process(Scene.java:3964)
at javafx.scene.Scene$KeyHandler.access$1800(Scene.java:3910)
at javafx.scene.Scene.impl_processKeyEvent(Scene.java:2040)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2501)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:197)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:147)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$353(GlassViewEventHandler.java:228)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:227)
at com.sun.glass.ui.View.handleKeyEvent(View.java:546)
at com.sun.glass.ui.View.notifyKey(View.java:966)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
So my cell wouldnt do anything after edit commited.
回答1:
data
is declared as ObservableList<ObservableList> data;
and you fill it with ObservableList
s:
while (rs.next()) {
//Iterate Row
ObservableList<String> row = FXCollections.observableArrayList();
...
data.add(row);
}
In the onEditCommit
handler you do this however:
public void handle(CellEditEvent<Adminsupervisor, String> t) {
((Adminsupervisor) t.getTableView().getItems().get(
t.getTablePosition().getRow())).set(j, t.getNewValue());
}
t.getTableView().getItems().get(index)
returns a ObservableList
, which you try to cast to Adminsupervisor
which for obvious reasons doesn't work...
You need to use the same type for items and in the handler. Whether you want to use ObservableList
or Adminsupervisor
is up to you...
Note: Add type parameters to the TableView
and the TableColumn
, and the compiler should complain about this. By using raw types however, you prevent the compiler from doing those checks (you may get a warning about raw types though).
Furthermore
for (j = 0; j < 4; j++) {
if (j == 0) {
setId(newValue);
}
if (j == 2) {
setPassword(newValue);
}
if (j == 3) {
setUserType(newValue);
}
if (j == 1) {
setUsername(newValue);
}
}
should be rewrittern as
setId(newValue);
setUsername(newValue);
setPassword(newValue);
setUserType(newValue);
j = 4; // not really neccessary since there is no read access to j
At least that achieves the same effect. (But maybe you just added the for
loop around those if
s for no reason and it should be removed.)
And also consider removing j
as parameter from the Adminsupervisor.set
method since the value is never used in method (in the original version it's overwritten with 0
before any read access happens in for (j = 0; j < 4; j++)
and in the improved version it's not read at all).
Furthermore the ObservableValue
returned by your cellValueFactory
will never trigger an update. If you use ObservableList
as item type, you could use the Bindings
class to get a ObservableValue
for a specific index:
col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {
return Bindings.stringValueAt(param.getValue(), j);
}
});
来源:https://stackoverflow.com/questions/37937125/setoneditcommit-with-iteration-javafx