2017-01-10 8 views
0

StudentオブジェクトとClassroomオブジェクトを含むTableViewを作成しようとしています。今、ChoiceBoxClassroomから別のものに交換するためにStudentsを交換したいと思います。カスタム編集可能なセルでJFX TableViewを作成する際の問題

ここに私のテーブルビュークラスのコード

public class ChoiceBoxCell extends TableCell<Student, Classroom> { 


    ChoiceBox<Classroom> classroomChoiceBox = new ChoiceBox<>(); 

    public ChoiceBoxCell(ObservableList<Classroom> classroomObservableList) { 
     ObservableList<Classroom> classroomObservableListList = classroomObservableList; 
     classroomChoiceBox.setItems(classroomObservableListList); 

     classroomChoiceBox.getSelectionModel().selectedIndexProperty().addListener((obs, oldValue, newValue) -> { 
      Classroom value = classroomChoiceBox.getItems().get((int) newValue); 
      classroomChoiceBox.setValue(value); 
      processEdit(value); 
     }); 
    } 
    private void processEdit(Classroom value) { 
     commitEdit(value); 
     classroomChoiceBox.setValue(value); 
     setGraphic(classroomChoiceBox); 
    } 

    @Override 
    public void cancelEdit() { 
     super.cancelEdit(); 
     setGraphic(classroomChoiceBox); 
    } 

    @Override 
    public void commitEdit(Classroom value) { 
     super.commitEdit(value); 
     classroomChoiceBox.setValue(value); 
     setGraphic(classroomChoiceBox); 
    } 

    @Override 
    public void startEdit() { 
     super.startEdit(); 
     Classroom value = getItem(); 
     if (value != null) { 
      classroomChoiceBox.setValue(value); 
      setGraphic(classroomChoiceBox); 
     } 
    } 

    @Override 
    protected void updateItem(Classroom item, boolean empty) { 
     super.updateItem(item, empty); 
     if (item == null || empty) { 
      classroomChoiceBox.setValue(item); 
      setGraphic(classroomChoiceBox); 
     } else { 
      classroomChoiceBox.setValue(item); 
      setGraphic(classroomChoiceBox); 
     } 
    } 
} 

一覧classroomList =新しいClassroomDaoは()だgetAllClasses(); ObservableListクラスルームObservableList = FXCollections.observableArrayList(classroomList);

classroomNameColumn.setPrefWidth(columnSize); 
classroomNameColumn.setCellValueFactory(cdf -> cdf.getValue().classroomProperty()); 
classroomNameColumn.setCellFactory(column -> new ChoiceBoxCell(classroomObservableList)); 
classroomNameColumn.setEditable(true); 

私は

Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: -1 
at java.util.ArrayList.elementData(ArrayList.java:418) 
at java.util.ArrayList.get(ArrayList.java:431) 
at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89) 
at view.adminAccess.studentOverview.ChoiceBoxCell.lambda$new$0(ChoiceBoxCell.java:20) 
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361) 
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81) 
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176) 
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142) 
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113) 
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147) 
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68) 
at javafx.scene.control.SingleSelectionModel.select(SingleSelectionModel.java:114) 
at javafx.scene.control.ChoiceBox$4.invalidated(ChoiceBox.java:331) 
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111) 
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146) 
at javafx.scene.control.ChoiceBox.setValue(ChoiceBox.java:336) 
at view.adminAccess.studentOverview.ChoiceBoxCell.updateItem(ChoiceBoxCell.java:58) 
at view.adminAccess.studentOverview.ChoiceBoxCell.updateItem(ChoiceBoxCell.java:10) 
at javafx.scene.control.TableCell.updateItem(TableCell.java:639) 
at javafx.scene.control.TableCell.indexChanged(TableCell.java:468) 
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116) 
at com.sun.javafx.scene.control.skin.TableRowSkinBase.requestCellUpdate(TableRowSkinBase.java:659) 
at com.sun.javafx.scene.control.skin.TableRowSkinBase.lambda$init$497(TableRowSkinBase.java:159) 
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137) 
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81) 
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105) 
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112) 
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146) 
at javafx.scene.control.Cell.setItem(Cell.java:403) 
at javafx.scene.control.Cell.updateItem(Cell.java:670) 
at javafx.scene.control.TableRow.updateItem(TableRow.java:268) 
at javafx.scene.control.TableRow.indexChanged(TableRow.java:225) 
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116) 
at com.sun.javafx.scene.control.skin.VirtualFlow.releaseCell(VirtualFlow.java:1807) 
at com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength(VirtualFlow.java:1881) 
at com.sun.javafx.scene.control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2528) 
at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1189) 
at javafx.scene.Parent.layout(Parent.java:1079) 
at javafx.scene.Parent.layout(Parent.java:1085) 
at javafx.scene.Parent.layout(Parent.java:1085) 
at javafx.scene.Parent.layout(Parent.java:1085) 
at javafx.scene.Parent.layout(Parent.java:1085) 
at javafx.scene.Scene.doLayoutPass(Scene.java:552) 
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397) 
at com.sun.javafx.tk.Toolkit.lambda$runPulse$31(Toolkit.java:355) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354) 
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381) 
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510) 
at com.sun.javafx.tk.quantum.PaintCollector.liveRepaintRenderJob(PaintCollector.java:320) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:788) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler$ViewEventNotification.run(GlassViewEventHandler.java:749) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleViewEvent$369(GlassViewEventHandler.java:828) 
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleViewEvent(GlassViewEventHandler.java:827) 
at com.sun.glass.ui.View.handleViewEvent(View.java:539) 
at com.sun.glass.ui.View.notifyResize(View.java:875) 
at com.sun.glass.ui.win.WinWindow._setBounds(Native Method) 
at com.sun.glass.ui.Window.setBounds(Window.java:572) 
at com.sun.javafx.tk.quantum.WindowStage.setBounds(WindowStage.java:318) 
at javafx.stage.Window$TKBoundsConfigurator.apply(Window.java:1274) 
at javafx.stage.Window$TKBoundsConfigurator.pulse(Window.java:1290) 
at com.sun.javafx.tk.Toolkit.lambda$runPulse$31(Toolkit.java:355) 
at java.security.AccessController.doPrivileged(Native Method) 
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354) 
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:378) 
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$runToolkit$405(QuantumToolkit.java:319) 
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) 
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191) 
at java.lang.Thread.run(Thread.java:745) 

This次の例外を取得していますが、それがどのように見えるかです。最後のセルがテーブル内のすべての行に合わせようとしているようです。ChoiceBox.

これはデータが入っている行だけに限定しておくことができますか?

編集:追加号

私は今使用しているコードの一部です。

classroomChoiceBox.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> { 
     if (newValue != null) { 
      processEdit(newValue); 
     } 
    }); 

@Override 
public void commitEdit(Classroom value) { // always gets executed 
    super.commitEdit(value); 
    Student student = (Student) getTableRow().getItem(); 
    student.setClassroom(value); 
    new StudentDao().updateStudent(student); // students get updated on creation of the table 
    classroomChoiceBox.setValue(value); 
    setGraphic(classroomChoiceBox); 
} 

問題は、表が作成されたときに、各Studentが更新さという点です。

+0

あなたの質問に完全なスタックトレースを投稿してください。 –

+0

@James_D Edited、これはそれだけです。 –

+0

おそらく20行目は 'Classroom value = classroomChoiceBox.getSelectionModel()...'ですか? –

答えて

0

何も選択されていない場合、選択モデルの選択インデックスは-1に設定されます(docs参照)。 -1は、リスト内の有効なインデックスではありませんので、あなたは、この場合に確認する必要があります。

classroomChoiceBox.getSelectionModel().selectedIndexProperty().addListener((obs, oldValue, newValue) -> { 
    int index = newValue.intValue(); 
    if (index >= 0) { 
     Classroom value = classroomChoiceBox.getItems().get(index); 

     // what is the point of the next line? 
     // surely this is the value in the choice box already??? 
     classroomChoiceBox.setValue(value); 

     processEdit(value); 
    } 
}); 

はもちろん、それは簡単かもしれだけではなく、そのインデックスを得るための、選択モデルから直接値を取得します:

classroomChoiceBox.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> { 
    if (newValue != null) { /* don't know if you care if this is null... */ 
     processEdit(newValue); 
    } 
}); 

あなたは空のセルに選択ボックスを見ている理由は、あなたが明示的にセルのupdateItem方法では、空のセルに選択ボックスにグラフィックを設定することです。私は(ifブロックがelseブロックと同一であるため)、これは単なるコピー&ペーストエラーであると私は推測します。

+0

大変ありがとうございます。最初のソリューションは完全に機能します(2番目のメソッドはnewValueが 'Number'で、' Classroom'オブジェクトが必要なので、問題はありません)。 –

+0

@HonzaŠtefánik明らかにあなたは答えを正しく読まなかった。 'newValue'は、' selectedIndexProperty'から 'selectedItemProperty'に変更すると、' Number'ではなく、 'Classroom'です。 –

+0

ああ、私は 'if(index> = 0)'を必要としないことが判明しました。おそらく間違った 'setGraphic'だったでしょう。そして、はい、 'classroomChoiceBox.setValue(value);'は必要ありません。もう一度ありがとう。 –

関連する問題