JavaFX 3 Canvas
Canvasクラス Canvas class
JavaFXのCanvasクラスはProcessingやJavaScriptのcanvasと同じ様に使う事ができます.
Canvas class of JavaFX can be used the same as Processing or canvas of JavaScript.
GraphicContext
まずCanvasクラスが持っているGraphicContextを取得します.
First, get GraphicContext of Canvas class.
GraphicsContext ctx = canvas.getGraphicsContext2D();
fill, stroke
図形の輪郭を描く時はGraphicContextクラスの"stroke"で始まるメソッドを使用します. また図形の塗り潰す時はGraphicContextクラスの"fill"で始まるメソッドを使用します.
To draw outline of shape, use GraphicContext class's methods starts with "stroke". To paint all over a shape, use GraphicContext class's methods starts with "fill".
ctx.strokeOval(p.getX() - 5, p.getY() - 5, 10, 10)
path
パスを描く時はまずGraphicContextクラスのbeginPathメソッドでパスを開始します. そしてmoveTo, lineTo, quadraticCurveTo, bezierCurveTo, arc, arcTo, appendSVGPath, rect, closePathなどのメソッドでパスを作ります. パスの内側を塗り潰す時はGraphicContextクラスのfillメソッド, パスの輪郭を描く時はstrokeメソッドを使用します.
To generate path, firstly use beginPath method of GraphicContext class. After that, construct path with moveTo, lineTo, quadraticCurveTo, bezierCurveTo, arc, arcTo, appendSVGPath, rect or closePath methods. Finally, if you want to paint all over the region inside the path, use fill method of GraphicContext class. If you want to draw a outline of the path, use stroke method.
ctx.beginPath(); ctx.moveTo(points.get(0).getX(), points.get(0).getY()); points.stream().skip(1).forEach(p -> ctx.lineTo(p.getX(), p.getY())); ctx.stroke();
clear
キャンバスをクリアする時はGraphicContextクラスのclearRectメソッドを使用します.
To clear the canvas, use clearRect method of GraphicContext.
ctx.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
サンプル Sample
クリックされた点を直線で繋ぐプログラムです.
The following program draws lines between clicked points.
View.fxml
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.canvas.*?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="canvassample.ViewController"> <children> <Canvas fx:id="canvas" height="200.0" onMouseClicked="#handleClick" width="320.0" /> </children> </AnchorPane>
Main.java
package canvassample; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("View.fxml")); stage.setScene(new Scene(root)); stage.show(); } public static void main(String[] args) { launch(args); } }
ViewController.java
package canvassample; import java.net.URL; import java.util.LinkedList; import java.util.List; import java.util.ResourceBundle; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.geometry.Point2D; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.input.MouseEvent; public class ViewController implements Initializable { private final List<Point2D> points = new LinkedList<>(); @FXML private Canvas canvas; @FXML synchronized private void handleClick(MouseEvent e) { points.add(new Point2D(e.getX(), e.getY())); GraphicsContext ctx = canvas.getGraphicsContext2D(); ctx.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); points.forEach(p -> ctx.strokeOval(p.getX() - 5, p.getY() - 5, 10, 10)); ctx.beginPath(); ctx.moveTo(points.get(0).getX(), points.get(0).getY()); points.stream().skip(1).forEach(p -> ctx.lineTo(p.getX(), p.getY())); ctx.stroke(); } @Override public void initialize(URL url, ResourceBundle rb) { } }