2016-06-21 66 views
0

我是一個純粹的新手。我做了我的表用迭代從數據庫中添加列:setOnEditCommit with Iteration JavaFX

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"); 
    } 
    } 

正如你所看到的,我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()); 
      } 
     } 
     ); 

這是模型類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"); 
    } 
}} 

我得到了這個堆棧跟蹤:

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) 

所以我的單元格在編輯提交後不會做任何事情。

+0

看一看你的堆棧跟蹤,並在第一行說,你嘗試「ObservableListWrapper」轉換爲你的模型類「AdminSide.Adminsupervisor」。你確定,你的DATA對象是一個ObservableList的ObservableList,還是你想擁有一個AdminSide.Adminsupervisor的ObservableList? 'ObservableList '? – SSchuette

+1

@SSchuette是的我想讓Adminsupervisor與ObservableList的類型相同,因此我可以將它包裝成沒有問題。你願意告訴我該怎麼辦? –

+0

「我想讓'Adminsupervisor'與'ObservableList'類型相同?這些(非常)不同的類型 - 你不能假裝它們是同一件事。您需要確定表格的每一行代表什麼類型,並堅持下去。如果你想讓它成爲'Adminsupervisor',那麼把'data'變成'ObservableList '並且添加適當的對象。如果你希望它是'ObservableList'(應該是'ObservableList '),那麼完全刪除'Adminsupervisor'類並且只使用'ObservableList'。第一個更好,恕我直言,但你需要選擇一個。 –

回答

1

data被聲明爲ObservableList<ObservableList> data;和你ObservableList個飽吧:

while (rs.next()) { 
    //Iterate Row 
    ObservableList<String> row = FXCollections.observableArrayList(); 
    ... 
    data.add(row); 
} 

onEditCommit處理你這樣做不過:

public void handle(CellEditEvent<Adminsupervisor, String> t) { 
    ((Adminsupervisor) t.getTableView().getItems().get(
      t.getTablePosition().getRow())).set(j, t.getNewValue()); 
} 

t.getTableView().getItems().get(index)返回ObservableList,你試着投到Adminsupervisor由於顯而易見的原因不起作用...

您需要爲項目和處理程序使用相同的類型。無論您是想用ObservableListAdminsupervisor是你......

注:添加類型參數的TableViewTableColumn,編譯器應該抱怨。但是,通過使用原始類型,您可以阻止編譯器執行這些檢查(儘管您可能會收到關於原始類型的警告)。

此外

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); 
    } 
} 

應當rewrittern作爲

setId(newValue); 
setUsername(newValue); 
setPassword(newValue); 
setUserType(newValue); 

j = 4; // not really neccessary since there is no read access to j 

至少能實現相同的效果。 (但也許你剛剛添加圍繞這些if S中for循環無緣無故,它應該被刪除。)

而且還考慮取消jAdminsupervisor.set方法的參數,因爲值永遠不會在方法中(原版本在for (j = 0; j < 4; j++)發生任何讀取訪問之前被0覆蓋,在改進的版本中它根本不被讀取)。

此外,您的cellValueFactory返回的ObservableValue永遠不會觸發更新。如果您使用ObservableList作爲項目類型,你可以使用Bindings類來獲得一個ObservableValue特定指數:

col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>() { 
    public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) { 
     return Bindings.stringValueAt(param.getValue(), j); 
    } 
}); 
+0

謝謝先生,但我需要解決方案而不是判斷。 –

+1

@SuryaHardiansyah:然後只需將'Adminsupervisor's添加爲項目,或者將其替換爲'ObservableList'。我認爲這一點很明顯,一旦問題得到解釋... – fabian

+0

如何做到這一點先生? :「( 請告訴我我應該在 –