setOnEditCommit with Iteration JavaFX

痴心易碎 提交于 2020-01-17 04:45:05

问题


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 ObservableLists:

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 ifs 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!