Timmey92
Commodore
- Registriert
- Okt. 2008
- Beiträge
- 4.569
Hallo liebe Freunde,
ich arbeite gerade an einem kleinen Projekt und nutze erstmals JavaFX. Als Teil dieses Projekts muss ein Array aus bis zu 250000 Objekten (500x500) auf einen JavaFX Canvas gezeichnet werden (es ist eine Simulation).
Das Problem ist: das dauert verdammt noch mal ewig (bis zu 10 Sekunden auf schwachen Rechnern).
Ein weiteres Problem ist: der UI Thread blockiert währenddessen, da die Zeichenoperation so lange dauert.
Mögliche Lösungsansätze meinerseits: Zeichnen in einen Puffer auf einen extra Thread auslagern und dann Ergebnis im UI Thread austauschen - wie könnte das gehen? Bisherige Versuche mit schreiben in ein BufferedImage welches anschließend auf dem Canvas als ganzes gezeichnet wird, sind gescheitert (Threading ist grundsätzlich kein Problem für mich).
Habt ihr da Ideen warum das so inperformant ist? Eine Beispielapplikation, um das Problem zu verdeutlichen, siehe in den Codeblöcken.
Danke für eure Hilfe, ist gerade enorm wichtig für mich!
Main.java
Controller.java
sample.fxml
ich arbeite gerade an einem kleinen Projekt und nutze erstmals JavaFX. Als Teil dieses Projekts muss ein Array aus bis zu 250000 Objekten (500x500) auf einen JavaFX Canvas gezeichnet werden (es ist eine Simulation).
Das Problem ist: das dauert verdammt noch mal ewig (bis zu 10 Sekunden auf schwachen Rechnern).
Ein weiteres Problem ist: der UI Thread blockiert währenddessen, da die Zeichenoperation so lange dauert.
Mögliche Lösungsansätze meinerseits: Zeichnen in einen Puffer auf einen extra Thread auslagern und dann Ergebnis im UI Thread austauschen - wie könnte das gehen? Bisherige Versuche mit schreiben in ein BufferedImage welches anschließend auf dem Canvas als ganzes gezeichnet wird, sind gescheitert (Threading ist grundsätzlich kein Problem für mich).
Habt ihr da Ideen warum das so inperformant ist? Eine Beispielapplikation, um das Problem zu verdeutlichen, siehe in den Codeblöcken.
Danke für eure Hilfe, ist gerade enorm wichtig für mich!
Main.java
Code:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
ScrollPane scrollPane = (ScrollPane) root.lookup("#scrollPane");
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Code:
package sample;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ScrollPane;
import javafx.scene.paint.Color;
import java.util.Random;
public class Controller {
@FXML
private ScrollPane scrollPane;
Canvas canvas;
@FXML
protected void draw(ActionEvent event) {
canvas = new Canvas(500,500);
scrollPane.setContent(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
Random r = new Random();
for(int i = 0; i<=500; i++) {
for(int j = 0; j<=500; j++) {
if (r.nextBoolean()) {
gc.setFill(Color.BLACK);
} else {
gc.setFill(Color.BLUE);
}
gc.fillRect(i, j, i+1, j+1);
}
}
}
}
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.GridPane?>
<AnchorPane prefHeight="275.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="sample.Controller">
<children>
<ScrollPane fx:id="scrollPane" content="$null" prefHeight="237.0" prefWidth="300.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="38.0" />
<Button layoutX="14.0" layoutY="14.0" mnemonicParsing="false" onAction="#draw" text="Draw" />
</children>
</AnchorPane>