ImageGetter (JavaFX) での覚え書き
この前、JavaFX の学習がてらに創った ImageGetter というお遊びプログラムでの覚え書きです。
イメージを取得して画像を表示させる処理と、その画像を保存させる処理を書いておきます。
プログラム全体を載せようと思ったのですが無駄に長いのと JavaFX 初心者ということもあって間違ってるかもしれないので。(^_^;)
見たいって人がいれば暇をみつけてプログラム全体をアップするか考えます。
解説は無いですが何をしているか解るようにコメントをいれてあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
@FXML public void handleGet(ActionEvent event) { // イメージ取得時にこれらを非活性化する prpgressIndicator.setVisible(true); timeLimit.setDisable(true); getButton.setDisable(true); slider.setDisable(true); effectCombo.setDisable(true); saveButton.setDisable(true); file.setDisable(true); edit.setDisable(true); exit.setDisable(true); img.setDisable(true); imgUrl_1.setDisable(true); imgUrl_2.setDisable(true); imgUrl_3.setDisable(true); // Task クラスを使い Image を取得し、GUI を更新 Task<Void> task = new Task<Void>() { // 戻り値なしの非同期処理 ( キャンセル処理は無し ) @Override protected Void call() throws Exception { // ExecutorService 設定 int procs = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(); if (procs > 1) { procs = 2; } executor = Executors.newFixedThreadPool(procs); // CompletableFuture を使い Image を取得 // works は、Image 取得クラスのインスタンス image = CompletableFuture.supplyAsync(() -> works.getImg(baseUrl, subUrl), executor); image.thenRun(() -> { }); try { target = image.get(limit, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException ex) { // Good catch! (In the latest Japan, it is an indispensable comment.) Image temp; if (limit < 5) { temp = new Image(getClass().getResource("TimeOut.png").toString()); } else { temp = new Image(getClass().getResource("out.png").toString()); } image.complete(temp); } try { target = image.get(); } catch (InterruptedException | ExecutionException ex1) { // Good catch! (In the latest Japan, it is an indispensable comment.) Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex1); } // GUI 更新 Platform.runLater(() -> { imgView.setImage(target); timeLimit.setDisable(false); getButton.setDisable(false); slider.setDisable(false); effectCombo.setDisable(false); saveButton.setDisable(false); file.setDisable(false); edit.setDisable(false); exit.setDisable(false); img.setDisable(false); imgUrl_1.setDisable(false); imgUrl_2.setDisable(false); imgUrl_3.setDisable(false); prpgressIndicator.setVisible(false); Toolkit.getDefaultToolkit().beep(); // ExecutorService 止める while (true) { if (image.isDone()) { executor.shutdown(); } try { if (!executor.awaitTermination(2, TimeUnit.SECONDS)) { executor.shutdownNow(); break; } } catch (InterruptedException ex) { // Good catch! (In the latest Japan, it is an indispensable comment.) Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex); } break; } }); return null; } }; new Thread(task).start(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@FXML public void handleSave(ActionEvent event) { // ImageView だけのスナップショット WritableImage writableImage = imgView.snapshot(null, null); // ファイルチューザ File outFile = fileChooser.showSaveDialog(null); // 保存 if (outFile != null) { try { ImageIO.write(SwingFXUtils.fromFXImage(writableImage, null), "png", outFile); } catch (IOException ex) { Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
@Override public void initialize(URL url, ResourceBundle rb) { ................................................ // ファイルチューザ fileChooser = new FileChooser(); // タイトル fileChooser.setTitle("Save Image File"); // フィルター fileChooser.getExtensionFilters() .addAll(new ExtensionFilter("Image Files", "*.png", "*.jpg", "*.gif"), new ExtensionFilter("All Files", "*.*")); } |
あと ImageView のサイズ調整に ImageGetter.java の starat メソッドに
1 2 |
FXMLDocumentController.imgView.fitWidthProperty().bind(stage.widthProperty().multiply(0.75)); FXMLDocumentController.imgView.fitHeightProperty().bind(stage.heightProperty().multiply(0.75)); |
としてます。
縮小率は適当です。(やってることも適当です)
こんなことしなくても良い方法があるかもしれませんが解らなかったので諦めてこうしました。(^_^;)
あと Dialog でも少しはまったのでそのことも書こうかと思ったのですが標準ライブラリでない無いからやめておきます。
なんで Dialog が標準ライブラリでないのか疑問ですがこの先どうなるのかまだ解らないですしね。
最後に、くどいようですが間違ってるかもしれないのでおかしなところがあれば笑って許してくださいね。(^_^)
TAGS: JavaFX | 2013年8月18日6:55 AM | Comment : 0