在 JavaFx v17、JDK v17、Maven、IntelliJ 中:
Listview<TokenWord> (=TOKListView) 位于 Listview<Signification> (=SIGListView) 的每一行中。當我編輯 TOKListView 的一個單元格時,我在 startEdit() 部分進行了 commitEdit() 呼叫,然后我得到了一個 Error class TokenWord cannot be cast to class Signification。SIGListView 不應該,但會做一個updateItem(),但為什么呢?
Main.class // ReprEx
public class Main extends Application {
public static void main(String[] args) {
Application.launch(Main.class);
}
public class Signification {
ArrayList<TokenWord> tokenWords;
public Signification(ArrayList<TokenWord> tokenWords) {
this.tokenWords = tokenWords;
}
public ArrayList<TokenWord> getTokenWords() {
return tokenWords;
}
}
public class TokenWord {
String Text;
public TokenWord(String text) {
Text = text;
}
public String getText() {
return Text;
}
}
final ListView<Signification> significationListView = new ListView<>();
final ArrayList<Signification> significations = new ArrayList<>();
@Override
public void start(Stage stage) {
significations.add(
new Signification(new ArrayList<TokenWord>(Arrays.asList(
new TokenWord("One")
))));
significationListView.setCellFactory(significationListView -> {
ListCell<Signification> siCell = new ListCell<Signification>() {
//PROBLEM AREA ---- START --------------------------------------
//########## PROBLEM CONSUMED (of PROBLEM FIRED see below) #########
@Override
public void updateItem(Signification sigItem, boolean empty) {
super.updateItem(sigItem, empty);
if ((!empty) && (sigItem != null)) {
ListView<TokenWord> tokenWordListView = new ListView<TokenWord>();
tokenWordListView.setEditable(true);
tokenWordListView.setOrientation(Orientation.HORIZONTAL);
tokenWordListView.setCellFactory(twListView -> {
// each Cell a new Listview
ListCell<TokenWord> twCell = new ListCell<TokenWord>() {
@Override
public void updateItem(TokenWord twItem, boolean empty) {
super.updateItem(twItem, empty);
if ((!empty) && (twItem != null)) setText(twItem.getText());
}
@Override
public void startEdit() {
if (!isEditable() || !getListView().isEditable()) return;
super.startEdit();
if (isEditing()) {
setText("");
TextField textField = new TextField(getItem().getText());
textField.setOnAction(actionEvent -> {
//########## PROBLEM FIRED ###########
commitEdit(new TokenWord(textField.getText()));
});
setGraphic(textField);
} else setGraphic(null);
}
};
return twCell;
});
tokenWordListView.getItems().addAll(sigItem.getTokenWords());
setGraphic(tokenWordListView);
} else {
setGraphic(null);
}
}
//PROBLEM AREA ---- END --------------------------------------
};
siCell.setPrefHeight(40);
return siCell;
});
significationListView.getItems().addAll(significations);
stage.setScene(new Scene(new StackPane(significationListView), 400, 150));
stage.show();
}
}
錯誤資訊:
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class org.example.TheApp$TokenWord cannot be cast to class org.example.TheApp$Signification (org.example.TheApp$TokenWord and org.example.TheApp$Signification are in unnamed module of loader 'app')
at org.example.TheApp$1.updateItem(TheApp.java:61)
at javafx.scene.control.ListCell.updateItem(ListCell.java:481)
at javafx.scene.control.ListCell.lambda$new$2(ListCell.java:168)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:239)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:211)
at javafx.collections.ModifiableObservableListBase.set(ModifiableObservableListBase.java:170)
at javafx.scene.control.ListView.lambda$new$1(ListView.java:375)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
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.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:8792)
at javafx.scene.control.ListCell.commitEdit(ListCell.java:390)
at org.example.TheApp$1$1.lambda$startEdit$0(TheApp.java:94)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
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.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:8792)
at com.sun.javafx.scene.control.behavior.TextFieldBehavior.fire(TextFieldBehavior.java:154)
at com.sun.javafx.scene.control.behavior.TextInputControlBehavior.lambda$keyMapping$62(TextInputControlBehavior.java:332)
at com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
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.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:4105)
at javafx.scene.Scene.processKeyEvent(Scene.java:2156)
at javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2630)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:218)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:150)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:250)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:249)
at com.sun.glass.ui.View.handleKeyEvent(View.java:548)
at com.sun.glass.ui.View.notifyKey(View.java:972)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class org.example.TheApp$TokenWord cannot be cast to class org.example.TheApp$Signification (org.example.TheApp$TokenWord and org.example.TheApp$Signification are in unnamed module of loader 'app')
at org.example.TheApp$1.updateItem(TheApp.java:61)
at javafx.scene.control.ListCell.updateItem(ListCell.java:481)
at javafx.scene.control.ListCell.indexChanged(ListCell.java:337)
at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:120)
at javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1807)
at javafx.scene.control.skin.VirtualFlow.addTrailingCells(VirtualFlow.java:2191)
at javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1327)
at javafx.scene.Parent.layout(Parent.java:1207)
at javafx.scene.Parent.layout(Parent.java:1214)
at javafx.scene.Parent.layout(Parent.java:1214)
at javafx.scene.Scene.doLayoutPass(Scene.java:579)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2515)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:421)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:420)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:450)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:575)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:555)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:548)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:353)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run$$$capture(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:833)
uj5u.com熱心網友回復:
發生錯誤是因為編輯是通過事件控制的,而且我們有一個 ListView 和一個包含 ListView 的單元格:
- 提交沿著通常的事件調度鏈交付
- 提交從編輯單元格(包含 textField 的單元格)觸發到內部 listView
- 內部 listView 的默認提交處理程式通過保存編輯的值來處理事件
- 然后它冒泡到外部 listView 的提交處理程式,在那里它導致類轉換例外
最后一個發生是因為默認提交處理程式不使用該事件。解決方法是消耗它。
一些代碼(為了清楚起見,提取到一個單獨的類中,也可以行內完成)
public class OuterCell extends ListCell<Signification> {
ListView<TokenWord> tokenWordListView;
{
tokenWordListView = new ListView<TokenWord>();
tokenWordListView.setEditable(true);
tokenWordListView.setOrientation(Orientation.HORIZONTAL);
// grab default commit handler
EventHandler<EditEvent<TokenWord>> handler = tokenWordListView.getOnEditCommit();
tokenWordListView.setOnEditCommit(t -> {
// let default handler save the edited value
handler.handle(t);
// consume to prevent dispatching the event to the outer list
t.consume();
});
// use TextFieldListCell for inner cell
StringConverter<TokenWord> converter = new StringConverter<>() {
@Override
public String toString(TokenWord token) {
return token != null ? token.getText() : "";
}
@Override
public TokenWord fromString(String string) {
return new TokenWord(string);
}
};
tokenWordListView.setCellFactory(TextFieldListCell.forListView(converter));
setPrefHeight(40);
}
@Override
public void updateItem(Signification sigItem, boolean empty) {
super.updateItem(sigItem, empty);
if ((!empty) && (sigItem != null)) {
tokenWordListView.getItems().setAll(sigItem.getTokenWords());
setGraphic(tokenWordListView);
} else {
setGraphic(null);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/393288.html
