在画布中绘制时在不同组件中出现BufferOverflowException

时间:2019-07-11 08:01:04

标签: java javafx canvas concurrency

在我看来,我有三个不同的组件来显示数据。在每个组件中,我都使用画布来绘制数据。由于顺序到达每个画布都需要相对较长的时间,因此我正在研究一个并发解决方案。我正在使用服务来绘制画布,服务成功后,我会将画布传递给窗格。我在两个不同的组件中使用了这样的服务,但是现在我很少得到BufferOverflowException。

java.nio.BufferOverflowException
at com.sun.javafx.sg.prism.GrowableDataBuffer.ensureReadCapacity(GrowableDataBuffer.java:317)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getInt(GrowableDataBuffer.java:527)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getFloat(GrowableDataBuffer.java:563)

这是我如何实现服务的简单示例。如何避免出现异常?是否有其他(更好的)并发绘制画布的方法?

private class DrawService extends Service<Void> {

    private Canvas[] canvases;
    private short[][] data;
    private double widthFactor;
    private double xFactorCalc;

    private DrawService(Canvas[] canvases, short[][] data, double widthFactor, double xFactorCalc) {
        this.canvases = canvases;
        this.data = data;
        this.widthFactor = widthFactor;
        this.xFactorCalc = xFactorCalc;
    }

    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                for (int canvasIndex = 0; canvasIndes < canvases.length; canvasIndex++) {
                    GraphicsContext gc = canvases[canvasIndex].getGraphicsContext2D();

                    gc.clearRect(0, 0, canvases[canvasIndex].getWidth(),
                            canvases[canvasIndex].getHeight());
                    gc.setStroke(Color.DARKGREY);
                    gc.strokeLine(0, 0, 0, canvases[canvasIndex].getHeight());
                    gc.beginPath();
                    gc.setStroke(Color.BLACK);
                    drawValues(startTime, data, gc, widthFactor, xFactorCalc, canvasIndex);
                    gc.stroke();
                    gc.closePath();
                }
                return null;
            }
        };
    }

    private void drawValues(short[][] data, GraphicsContext gc, double widthFactor, double xFactorCalc, int canvasIndex) {
        for (int j = 0; j < data[canvasIndex].length; j++) {
            short value = data[canvasIndex][j];
            if (j == 0) {
                gc.moveTo(j, value);
            } else
                gc.lineTo(j * xFactorCalc * widthFactor, value);
        }
    }
}


public class ServiceExample extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        int interval = 250;
        Pane aPane = new Pane();
        Pane bPane = new Pane();
        aPane.setPrefSize(600, 400);
        bPane.setPrefSize(600, 400);
        int canvasSize = 7;
        int interval = 250;
        Canvas[] aCanvases = new Canvas[canvasSize];
        Canvas[] bCanvases = new Canvas[canvasSize];
        short[][] data = getData(canvasSize, interval);
        for(int i = 0; i < aCanvases.length; i++) {
            aCanvases[i].setPrefWidth(aPane.getPrefWidth());
            aCanvases[i].setPrefHeight(aPane.getPrefHeight());
            bCanvases[i].setPrefwidth(bPane.getPrefWidth());
            bCanvases[i].setPrefHeight(bPane.getPrefHeight();
        }
        double widthFactor = 1;
        double xFactorCalc = interval / canvases[0].getWidth();
        DrawService drawServiceA = new DrawService(aCanvases, data, widthFactor, xFactorCalc);
        drawServiceA.restart();
        DrawService drawServiceB = new DrawService(bCanvases, data, widthFactor, xFactorCalc);
        drawServiceB.restart();

        drawServiceA.setOnSucceeded((e) -> {
                    aPane.getChildren.addAll(aCanvases);
                }
                drawServiceB.setOnSucceeded((e) -> {
                            bPane.getChildren.addAll(bCanvases);
                        }

                        VBox vBox = new VBox(aPane, bPane);
        Scene scene = new Scene(vBox);
        stage.setScene(scene);
        stage.centerOnScreen();
        stage.show();
    }

    private short[][] getData(int canvasSize, int interval) {
        // pass random values
    }
}

0 个答案:

没有答案