JavaFXのフォームを画像キャプチャする方法
JavaFXでフォームの画像キャプチャする方法です。JavaFXではタイトルバーを含めたフォームのキャプチャはできなくて、VBoxやPaneのようなパネル系クラスの親にNodeというクラスが合って、そこにsnapshot
というメソッドがあります。そのメソッドを使ってパネルごとキャプチャすることができます。
[ad#top-1]
サンプルプログラムの完成形
起動するとこんな感じです。「キャプチャ」というボタンを押すと下段のパネルが配置されたコントロールごとキャプチャされます。
キャプチャボタンを押すと下図の通りカレントディレクトリにtest.pngという画像が現れます。
開くと以下の通り、下段のパネル部分がキャプチャされました。
ソースコード
ソースコードの前にまずはSceneBuilderで作ったUI部分です。
キャプチャというボタンにonClick
というアクションIDを付けて、下段のPaneにmainPane
とID付しました。それ以外は適当に配置しています。CheckBoxもTableViewも適当に配置していて特に制御しません。mainPane
ごとキャプチャするために置いたものです。
FXMLのソースは以下の通りです。
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.CheckBox?> <?import javafx.scene.control.TableColumn?> <?import javafx.scene.control.TableView?> <?import javafx.scene.layout.Pane?> <?import javafx.scene.layout.VBox?> <VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FormCapture"> <children> <Pane prefHeight="64.0" prefWidth="600.0"> <children> <Button layoutX="14.0" layoutY="9.0" mnemonicParsing="false" onAction="#onClick" text="キャプチャ" /> </children> </Pane> <Pane fx:id="mainPane" prefHeight="381.0" prefWidth="600.0"> <children> <CheckBox layoutX="53.0" layoutY="38.0" mnemonicParsing="false" text="CheckBox" /> <TableView layoutX="45.0" layoutY="80.0" prefHeight="200.0" prefWidth="407.0"> <columns> <TableColumn prefWidth="75.0" text="C1" /> <TableColumn prefWidth="75.0" text="C2" /> </columns> </TableView> <Button layoutX="174.0" layoutY="35.0" mnemonicParsing="false" prefHeight="24.0" prefWidth="124.0" text="Button" /> </children> </Pane> </children> </VBox>
次に本体のJavaのソースコードです。解説は後述。
import javafx.application.Application; import javafx.fxml.*; import javafx.scene.*; import javafx.stage.Stage; import javafx.scene.layout.*; import javafx.event.ActionEvent; import javafx.scene.image.*; import javax.imageio.*; import javafx.embed.swing.*; import java.io.*; public class FormCapture extends Application implements Initializable { @FXML private Pane mainPane; public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception{ VBox root = FXMLLoader.load(getClass().getResource("FormCapture.fxml")); stage.setTitle("FormCapture Test"); stage.setScene(new Scene(root)); stage.show(); } @Override public void initialize(java.net.URL url, java.util.ResourceBundle bundle) { //今回ここを使わなかった...。 } @FXML public void onClick(ActionEvent e) { WritableImage img = mainPane.snapshot(new SnapshotParameters(), null); try{ ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", new File("test.png")); }catch(Exception ex){ //悪手とされるExceptionでキャッチ。ゆるして。 System.out.println(ex); } System.out.println("OK"); } }
パネルのキャプチャは以下の1行部分です。mainPane
の親クラス(Node)のsnapshot
メソッドを使ってキャプチャします。
WritableImage img = mainPane.snapshot(new SnapshotParameters(), null);
で、最後にpng形式で保存するのが以下の一文。これも一行だけで至って簡単。
ImageIO.write(SwingFXUtils.fromFXImage(img, null), "png", new File("test.png"));
[ad#ad-1]
スポンサーリンク