1. Java FX Plantuml Viewer
//Run > Run Configuration > Arguments > VM Arguments //--module-path d:\Lib\Jar\javafx-sdk-16\lib --add-modules javafx.controls package com.home.app; import com.home.fx.*; import com.home.java.IconApi; import com.home.java.PUmlApi; import javafx.application.Application; import javafx.embed.swing.SwingFXUtils; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.*; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public class FxPUmlViewer extends Application { static String plantuml_colors ="@startuml\ncolors\n@enduml"; FxRichText textArea; //TextArea textArea; FxImageView imageView; List<BufferedImage> images; int imageIndex; SplitPane split; Label status; int fontSize = 12; Stage primaryStage; boolean ctrl_pressed = false; public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { primaryStage = stage; BorderPane pane = new BorderPane(); Scene scene = new Scene(pane, 480, 320); stage.setTitle("PlantUml Viewer"); stage.getIcons().add(SwingFXUtils.toFXImage(IconApi.getUmlImage(), null)); textArea = new FxRichText(scene); //FxApi.getTextArea(); imageView = new FxImageView(fontSize, keyHandle); //FxApi.getImageView(); split = FX.getHSplitPane(); status = new Label("Ready"); FX.addSplitPane( split, textArea.getLayout()); FX.addSplitPane( split, imageView.getLayout()); //FxApi.getScrollPane(imageView) ); HBox hbox = FX.getHBox(); FX.addHbox(hbox, FX.getButton("Color", (e) -> showColor() ), false); FX.addHbox(hbox, FX.getButton("Show", (e) -> showTextArea() ), false); FX.addHbox(hbox, FX.getButton("<", (e) -> showPrevImage() ), false); FX.addHbox(hbox, FX.getButton(">", (e) -> showNextImage() ), false); FX.addHbox(hbox, FX.getButton("W", (e) -> fitWidth() ), false); FX.addHbox(hbox, FX.getButton("H", (e) -> fitHeight() ), false); FX.addHbox(hbox, FX.getButton("N", (e) -> fitNone() ), false); FX.addHbox(hbox, FX.getButton("+", (e) -> zoomIn() ), false); FX.addHbox(hbox, FX.getButton("-", (e) -> zoomOut() ), false); VBox vbox = FX.getVBox(); FX.addVbox(vbox, getMenuBar(), true); FX.addVbox(vbox, hbox, false); FX.setDropHandler(textArea, dropHandler); pane.setPadding(new Insets(0, 0, 0, 0)); pane.setBottom(status); pane.setTop(vbox); pane.setCenter(split); scene.setOnKeyPressed(ke -> { if( ke.getCode() == KeyCode.CONTROL ) { ctrl_pressed = true; } if( ke.getCode() == KeyCode.MINUS && ctrl_pressed ) { zoomOut(); } if( ke.getCode() == KeyCode.EQUALS && ctrl_pressed ) { zoomIn(); } }); scene.setOnKeyReleased(ke -> { if( ke.getCode() == KeyCode.CONTROL ) { ctrl_pressed = false; } }); scene.setOnScroll((ScrollEvent event) -> { double deltaY = event.getDeltaY(); if( ctrl_pressed ) { if( deltaY > 0 ) { zoomIn(); } else { zoomOut(); } } }); stage.setOnCloseRequest( (e) -> System.exit(0) ); //Platform->exit() stage.setScene(scene); stage.show(); } public void showImagePopup(String puml_text) { textArea.setText(puml_text); try { List<BufferedImage> images = PUmlApi.makeImage(puml_text); for( int i = 0; i < images.size(); i++ ) { SwingApi.showImage( "Diagram " + i, images.get(i)); } } catch (IOException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } } public void showImage(int index) { if( images != null ) { imageView.setImage(SwingFXUtils.toFXImage(images.get(imageIndex), null)); status.setText("" + (imageIndex+1) + "/" + images.size()); } } public void renderImage(String puml_text) { try { //FxToast.show( primaryStage, "rendering ...", 1000, 250, 250); images = PUmlApi.makeImage(puml_text); imageIndex = 0; showImage( imageIndex ); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public void showPrevImage() { if( imageIndex > 0 ) { imageIndex -= 1; showImage( imageIndex ); } } public void showNextImage() { if( imageIndex < images.size() -1 ) { imageIndex += 1; showImage( imageIndex ); } } public void setText(String text) { textArea.setText(text); } void showTextArea() { renderImage(textArea.getText() ); } void showColor() { showImagePopup(plantuml_colors); } void getPasteHtmlAction() { if( Clipboard.getSystemClipboard().hasHtml() ) { textArea.clear(); textArea.setText( Clipboard.getSystemClipboard().getHtml() ); } } FxRunnable keyHandle = new FxRunnable() { @Override public void run(Object... object) { if( images != null ) { KeyCode e = (KeyCode)object[0]; if ( e.equals(KeyCode.UP) ) {} if ( e.equals(KeyCode.DOWN) ) {} if ( e.equals(KeyCode.RIGHT) ) { showNextImage(); } if ( e.equals(KeyCode.LEFT) ) { showPrevImage(); } if ( e.equals(KeyCode.PAGE_UP) ) { } if ( e.equals(KeyCode.PAGE_DOWN) ) { } if ( e.equals(KeyCode.HOME) ) { } if ( e.equals(KeyCode.END) ) { } if ( e.equals(KeyCode.ENTER) ) { } } } }; FxRunnable dropHandler = new FxRunnable() { @SuppressWarnings("unchecked") @Override public void run(Object... object) { if( object[0] instanceof List<?> ) { List<File> f = (List<File>)object[0]; try { String text = new String (Files.readAllBytes( Paths.get((f.get(0).getAbsolutePath())))); textArea.setText(text); renderImage(text); } catch (Exception e) { } } } }; public void fitWidth() { imageView.fitWidth(); } public void fitHeight() { imageView.fitHeight(); } public void fitNone() { imageView.fitNone(); } public void zoomIn() { imageView.zoomIn(); } public void zoomOut() { imageView.zoomOut(); } MenuBar getMenuBar() { int fontSize = 12; MenuBar menubar = new MenuBar(); menubar.getMenus().add(getFileMenu()); menubar.setStyle("-fx-font: " + fontSize + " arial;"); return menubar; } public Menu getFileMenu() { Menu menu = new Menu("File"); MenuItem item = new MenuItem("Exit"); item.setOnAction( (e) -> { System.exit(0); }); menu.getItems().add(item); menu.setStyle("-fx-font: " + fontSize + " arial;"); item.setStyle("-fx-font: " + fontSize + " arial;"); return menu; } }
댓글 없음:
댓글 쓰기