На мой взгляд, у меня есть три разных компонента для отображения данных.В каждом из компонентов я использую холст для рисования данных.Так как до каждого холста последовательно требуется относительно много времени, я работаю над параллельным решением.Я использую сервис для рисования холста, и когда сервис работает успешно, я передаю холст на панель.Я использую такой сервис в двух разных компонентах, и теперь я редко получаю исключение 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
}
}