请考虑以下应用程序:

enter image description here

我希望,通过每次点击按钮,第一个数据的LineChart被删除.点击后的输出必须如下所示:

After 1st click

enter image description here

After 2nd click

enter image description here

After 3rd click

enter image description here

然而,在第一次点击之后,我得到了以下ClassCastException条:

Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
    at javafx.controls@18/javafx.scene.chart.LineChart.createDataRemoveTimeline(LineChart.java:503)
    at javafx.controls@18/javafx.scene.chart.LineChart.dataItemRemoved(LineChart.java:359)
    at javafx.controls@18/javafx.scene.chart.XYChart.dataItemsChanged(XYChart.java:505)
    at javafx.controls@18/javafx.scene.chart.XYChart$Series$1.onChanged(XYChart.java:1474)
    at javafx.base@18/com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
    at javafx.base@18/com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    at javafx.base@18/javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:239)
    at javafx.base@18/javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    at javafx.base@18/javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    at javafx.base@18/javafx.collections.ObservableListBase.endChange(ObservableListBase.java:211)
    at javafx.base@18/javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:190)
    at com.example.demo/com.example.demo.MyApplication.lambda$start$0(MyApplication.java:21)
    at javafx.base@18/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base@18/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base@18/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18/javafx.scene.Node.fireEvent(Node.java:8797)
    at javafx.controls@18/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls@18/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208)
    at javafx.controls@18/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base@18/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247)
    at javafx.base@18/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base@18/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234)
    at javafx.base@18/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base@18/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base@18/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base@18/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base@18/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base@18/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics@18/javafx.scene.Scene$MouseHandler.process(Scene.java:3881)
    at javafx.graphics@18/javafx.scene.Scene.processMouseEvent(Scene.java:1874)
    at javafx.graphics@18/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607)
    at javafx.graphics@18/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411)
    at javafx.graphics@18/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at javafx.graphics@18/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450)
    at javafx.graphics@18/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424)
    at javafx.graphics@18/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449)
    at javafx.graphics@18/com.sun.glass.ui.View.handleMouseEvent(View.java:551)
    at javafx.graphics@18/com.sun.glass.ui.View.notifyMouse(View.java:937)
    at javafx.graphics@18/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics@18/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
    at java.base/java.lang.Thread.run(Thread.java:833)

代码如下:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class MyApplication extends Application {
    @Override
    public void start(Stage stage) {

        LineChart<String,String> lineChart=createLineChart();

        Button button = new Button("BUTTON");

        button.setOnAction(event -> lineChart.getData().get(0).getData().remove(0));

        VBox vBox=new VBox(button,lineChart);

        Scene scene = new Scene(vBox);

        stage.setScene(scene);

        stage.show();

    }

    LineChart<String,String> createLineChart(){
        LineChart<String, String> lineChart = new LineChart<>(new CategoryAxis(), new CategoryAxis());
        lineChart.getData().add(new XYChart.Series<>());
        for (int i = 0; i < 3; i++) {
            lineChart.getData().get(0).getData().add(new XYChart.Data<>("X string %d".formatted(i+1), "Y string %d".formatted(i+1)));
        }
        lineChart.getXAxis().setTickLabelFont(new Font(20));
        lineChart.getYAxis().setTickLabelFont(new Font(20));
        return lineChart;
    }

    public static void main(String[] args) {
        launch();
    }

}

Question

为什么ClassCastExceptionStringNumber的转换中上升,而我没有Number类型的数据?

推荐答案

这是LineChart实现中的一个错误.我找不到它在https://bugs.openjdk.org/secure/Dashboard.jspa的活动错误报告.

该问题出现在对方法createDataRemoveTimeline(...)(在当前实现中找到here)的调用中,该方法createDataRemoveTimeline(...)被实现为:

    private Timeline createDataRemoveTimeline(final Data<X,Y> item, final Node symbol, final Series<X,Y> series) {
        Timeline t = new Timeline();
        // save data values in case the same data item gets added immediately.
        XYValueMap.put(item, ((Number)item.getYValue()).doubleValue());

        t.getKeyFrames().addAll(new KeyFrame(Duration.ZERO, new KeyValue(item.currentYProperty(),
                item.getCurrentY()), new KeyValue(item.currentXProperty(),
                item.getCurrentX())),
                new KeyFrame(Duration.millis(500), actionEvent -> {
                    if (symbol != null) getPlotChildren().remove(symbol);
                    removeDataItemFromDisplay(series, item);
                    XYValueMap.clear();
                },
                new KeyValue(item.currentYProperty(),
                item.getYValue(), Interpolator.EASE_BOTH),
                new KeyValue(item.currentXProperty(),
                item.getXValue(), Interpolator.EASE_BOTH))
        );
        return t;
    }

该实现在Map<Data<X,Y>, Double>中缓存被移除的值(据我所知,这是必要的,以防相同的值被添加回来,同时用于移除它们的动画正在进行).这假设y值是Number(请注意该方法第二行的强制转换),当然这不一定是真的.我认为这应该用Map<Data<X,Y>, Y>实现,尽管我还没有完全分析代码.

dataItemRemoved(...)方法中调用createDataRemoveTimeline(...)方法(当从一个数据系列中删除一项时调用),但仅当animated设置为真时调用.因此,一种解决方法是禁用动画:

lineChart.setAnimated(false);

Java相关问答推荐

在现有Json文件中添加新记录

日食IDE 2024-03在Ubuntu下崩溃,导致hr_err_pid.log

如何计算内循环的时间复杂度?

将Nimbus设置为计算机上运行的所有Java应用程序的默认外观

将成为一个比较者.比较…在现代Java中,编译器会对`CompareTo`方法进行优化吗?

什么是Java原子属性的正确getter和setter

当Volatile关键字真的是必要的时候?

我如何知道MediaDiscoverer何时完成发现介质?

迁移到Java 17后,日期显示不准确

来自外部模块的方面(对于Java+Gradle项目)不起作用

为什么StandardOpenOption.CREATE不能通过Ubuntu在中小企业上运行?

EXCEL中的公式单元格显示#NAME?

一对多关系和ID生成

如何从HttpResponse实例获取Entity对象的内容?

Java中HashSet的搜索时间与TreeSet的搜索时间

视图被推出线性布局-Android

如何在特定关键字后提取与模式匹配的多个值?

如何以事务方式向ibmmq发送消息

如何从指定某些字段的父对象创建子对象

UuidGenerator Bean 类型不匹配?