我正在尝试使用JavaFX 8进行神经网络训练可视化。网络单元显示为根据输出值改变颜色的点。计算和绘图在一个可以通过单击按钮启动或停止的线程中完成。有一段时间一切正常,但经过多次迭代后,显示不再更新。
可靠地更新显示器需要做些什么?
我使用的是JRE版本1.8.0_45。
以下是我的代码的简化版本:
import javafx.application.*;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.*;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
public class TestView extends Application {
public static final int SCENE_WIDTH = 1000;
public static final int SCENE_HEIGHT = 800;
public static final int BUTTON_PANEL_HEIGHT = 80;
private Canvas canvas;
private GraphicsContext gc;
private Task<Void> task = null;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("MLP");
BorderPane borderPane = new BorderPane();
canvas = new Canvas( SCENE_WIDTH, 3*SCENE_HEIGHT-BUTTON_PANEL_HEIGHT );
gc = canvas.getGraphicsContext2D();
borderPane.setCenter(new ScrollPane(canvas));
GridPane buttonPanel = new GridPane();
Button buttonTrain = new Button("Train");
buttonTrain.setMinWidth(SCENE_WIDTH/2);
buttonPanel.setPadding(new Insets(0, 0, 0, 0));
buttonPanel.add(buttonTrain, 1, 0);
borderPane.setBottom(buttonPanel);
buttonTrain.setOnMouseClicked( e -> {
if (task != null) {
task.cancel();
task = null;
}
else {
task = new Task<Void>() {
@Override
protected Void call() throws Exception {
for (int i = 1; i <= 10000000; i++) {
if (isCancelled()) {
break;
}
// dummy calculation
doSomeStuff();
// dummy graphics update
gc.setFill(Color.GREEN);
gc.fillOval(50, 50, 20, 20);
gc.clearRect(200, 10, 200, 100);
gc.setFill(Color.BLACK);
gc.fillText("" + i, 200, 50);
}
return null;
}
};
new Thread(task).start();
}
});
Scene scene = new Scene( borderPane, SCENE_WIDTH, SCENE_HEIGHT );
primaryStage.setScene(scene);
primaryStage.show();
}
private double doSomeStuff() {
double r = 0.5;
for ( int i = 0; i < 10000; i++ ) {
r = Math.sin(r);
}
return r;
}
}