package com.home.fx; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Pos; import javafx.scene.control.*; import javafx.scene.control.ScrollPane.ScrollBarPolicy; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.*; import javafx.scene.layout.StackPane; import javafx.stage.FileChooser; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import static javafx.embed.swing.SwingFXUtils.fromFXImage; public class FxImageView { ImageView imageView; ScrollPane scrollPane; Label glassText; StackPane glassView; StackPane layout; Double zoom = 1.0; Image image; public FxImageView(int fontSize, FxRunnable keyHandle) { layout = new StackPane(); imageView = new ImageView(); //new Image(new File("D:/a.png").toURI().toString()) imageView.setPreserveRatio(true); imageView.setPickOnBounds(true); layout.setOnMouseMoved(e -> { if ( e.getX() < layout.getWidth() / 4 || e.getX() > layout.getWidth() * 3 / 4 ) { if ( e.getX() < layout.getWidth() / 4 ) { Platform.runLater(() ->glassText.setText("<")); StackPane.setAlignment(glassView, Pos.BOTTOM_LEFT); } else { Platform.runLater(() ->glassText.setText(">")); StackPane.setAlignment(glassView, Pos.BOTTOM_RIGHT); } glassView.setMaxWidth(layout.getWidth() / 4); glassView.setMaxHeight(layout.getHeight()); glassView.setVisible(true); } else { glassView.setVisible(false); } e.consume(); }); scrollPane = new ScrollPane(); scrollPane.setPannable(true); if( fontSize > 0 ) { scrollPane.setStyle("-fx-font-size: " + fontSize + " pt;"); } //imageView.fitWidthProperty().bind(scrollPane.widthProperty().subtract(10d)); scrollPane.setContent(imageView); scrollPane.vvalueProperty().addListener(new ChangeListener<Number>() { public void changed(ObservableValue<? extends Number> ov, Number old_val, Number new_val) { if ( new_val.equals(1.0) ) { //runnable.run(KeyCode.RIGHT); } if ( new_val.equals(0.0) ) { //runnable.run(KeyCode.LEFT); } } }); scrollPane.setOnKeyPressed(e -> { keyHandle.run(e.getCode()); }); glassText = new Label(""); glassText.setStyle("-fx-text-fill: goldenrod; -fx-font: italic 20 \"serif\"; -fx-padding: 0 0 20 0; -fx-text-alignment: center"); glassView = new StackPane(); StackPane.setAlignment(glassText, Pos.CENTER); glassView.getChildren().addAll(glassText); glassView.setStyle("-fx-background-color: rgba(0, 50, 100, 0.1); -fx-background-radius: 10;"); glassView.setLayoutX(0); glassView.setLayoutY(0); glassView.setPrefWidth(imageView.getFitWidth() / 4); glassView.setPrefHeight(imageView.getFitHeight() / 4); glassView.setVisible(false); glassView.setOnMouseClicked( e-> { if ( glassText.getText().equals(">") ) { keyHandle.run(KeyCode.RIGHT); } else { keyHandle.run(KeyCode.LEFT); } }); glassView.focusedProperty().addListener(new ChangeListener<Boolean>() { @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if( ! newValue.booleanValue() ) { glassView.setVisible(false); } } }); ContextMenu menu = new ContextMenu(); addMenuItem(menu, "Copy", () -> { if( image != null ) { Clipboard clipboard = Clipboard.getSystemClipboard(); ClipboardContent content = new ClipboardContent(); content.putImage(image); clipboard.setContent(content); } } ); addMenuItem(menu, "Save", () -> { if( image != null ) { try { FileChooser fileChooser = new FileChooser(); FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("PNG files (*.png)", "*.png"); fileChooser.getExtensionFilters().add(extFilter); File file = fileChooser.showSaveDialog(null); //stage ImageIO.write(fromFXImage(image, null), "png", file); } catch (IOException e) { e.printStackTrace(); } } } ); scrollPane.setContextMenu(menu); StackPane.setAlignment(glassView, Pos.BOTTOM_LEFT); layout.getChildren().addAll(scrollPane, glassView); layout.setStyle("-fx-background-color: silver; -fx-padding: 1;"); } public StackPane getLayout() { return layout; } public void clearGlassView() { glassView.setVisible(false); } public void setImage(Image image) { this.image = image; imageView.setImage(image); imageView.setFitWidth( image.getWidth() * zoom ); imageView.setFitHeight( image.getHeight() * zoom ); scrollPane.setVvalue(0.0); } public void setImage(byte[] image) { setImage(new Image(new ByteArrayInputStream(image))); } public void setImage(BufferedImage image) { setImage(SwingFXUtils.toFXImage(image,null)); } public void setContextMenu(ContextMenu menu) { scrollPane.setContextMenu(menu); } public void hideScrollBar() { scrollPane.setHbarPolicy(ScrollBarPolicy.NEVER); scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER); } public void showScrollBar() { scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED); scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED); setImage(this.image); } public void fitWidth() { imageView.fitWidthProperty().bind(scrollPane.widthProperty()); //.subtract(10d)); imageView.fitHeightProperty().unbind(); setImage(this.image); } public void fitHeight() { imageView.fitWidthProperty().unbind(); imageView.fitHeightProperty().bind(scrollPane.heightProperty()); //.subtract(10d)); setImage(this.image); } public void fitNone() { imageView.fitWidthProperty().unbind(); imageView.fitHeightProperty().unbind(); setImage(this.image); } public void zoomIn() { zoom += 0.1; setImage(this.image); } public void zoomOut() { if( zoom > 0.2 ) { zoom -= 0.1; } setImage(this.image); } public void addMenuItem(ContextMenu menu, String title, Runnable runnable) { MenuItem item = new MenuItem(); item.setText(title); item.setOnAction(e -> runnable.run()); menu.getItems().add(item); } public void addSeparator(ContextMenu menu) { menu.getItems().add(new SeparatorMenuItem()); } }
2021년 11월 21일 일요일
Java FX ImageView API
1. Java FX ImageView API
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기