2021년 11월 21일 일요일

Java FX Plantuml Viewer

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;
	}
}

댓글 없음:

댓글 쓰기