“MỌI SỰ CỐ GẮNG CHƯA CHẮC ĐÃ GẶT HÁI ĐƯỢC KẾT QUẢ NHƯNG MỖI KẾT QUẢ ĐẠT ĐƯỢC CHẮC CHẮN LÀ CẢ MỘT QUÁ TRÌNH CỐ GẮNG”

JavaFX HTMLEditor chèn hình ảnh base64 và URL tại vị trí xác định

Thứ ba - 12/03/2024 02:24

JavaFX HTMLEditor chèn hình ảnh base64 và URL tại vị trí xác định

JavaFX HTMLEditor chèn hình ảnh base64 và URL tại vị trí xác định

1) CustomHTMLEditor

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.geometry.Orientation;
import javafx.scene.control.Button;
import javafx.scene.control.Separator;
import javafx.scene.control.ToolBar;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebView;
import javafx.stage.FileChooser;

public class CustomHTMLEditor extends HTMLEditor {

    public static final String TOP_TOOLBAR = ".top-toolbar";
    public static final String BOTTOM_TOOLBAR = ".bottom-toolbar";
    public static final String WEB_VIEW = ".web-view";
    private static final String IMPORT_BUTTON_GENERAL = "embed.png";

    private final WebView mWebView;
    private final ToolBar mTopToolBar;
    private final ToolBar mBottomToolBar;
    private Button mImportFileButton;

    private Button mImportFileButtonurl;

    public CustomHTMLEditor() {
        mWebView = (WebView) this.lookup(WEB_VIEW);
        mTopToolBar = (ToolBar) this.lookup(TOP_TOOLBAR);
        mBottomToolBar = (ToolBar) this.lookup(BOTTOM_TOOLBAR);
        GridPane.setVgrow(mWebView, Priority.ALWAYS);

        createCustomButtons();
        this.setHtmlText("<html />");

    }

    /**
     * Inserts HTML data after the current cursor. If anything is selected, they
     * get replaced with new HTML data.
     *
     * @param html HTML data to insert.
     */
    public void insertHtmlAfterCursor(String html) {
        //replace invalid chars
        html = html.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\r", "\\r")
                .replace("\n", "\\n");
        //get script
        String script = String.format(
                "(function(html) {"
                + "  var sel, range;"
                + "  if (window.getSelection) {"
                + "    sel = window.getSelection();"
                + "    if (sel.getRangeAt && sel.rangeCount) {"
                + "      range = sel.getRangeAt(0);"
                + "      range.deleteContents();"
                + "      var el = document.createElement(\"div\");"
                + "      el.innerHTML = html;"
                + "      var frag = document.createDocumentFragment(),"
                + "        node, lastNode;"
                + "      while ((node = el.firstChild)) {"
                + "        lastNode = frag.appendChild(node);"
                + "      }"
                + "      range.insertNode(frag);"
                + "      if (lastNode) {"
                + "        range = range.cloneRange();"
                + "        range.setStartAfter(lastNode);"
                + "        range.collapse(true);"
                + "        sel.removeAllRanges();"
                + "        sel.addRange(range);"
                + "      }"
                + "    }"
                + "  }"
                + "  else if (document.selection && "
                + "           document.selection.type != \"Control\") {"
                + "    document.selection.createRange().pasteHTML(html);"
                + "  }"
                + "})(\"%s\");", html);
        //execute script
        mWebView.getEngine().executeScript(script);
    }

    /**
     * Creates Custom ToolBar buttons and other controls
     */
    private void createCustomButtons() {
        //add embed file button  
        /*
        ImageView graphic = new ImageView(new Image(getClass().getResourceAsStream(IMPORT_BUTTON_GENERAL)));
        mImportFileButton = new Button("Import File", graphic);
         */
        mImportFileButton = new Button("Chèn ảnh base64");
        mImportFileButton.setTooltip(new Tooltip("Tệp ảnh chuyển sang base64"));
        mImportFileButton.setOnAction((event) -> onImportFileButtonAction());

        mImportFileButtonurl = new Button("Chèn ảnh URL");
        mImportFileButtonurl.setTooltip(new Tooltip("Lưu địa chỉ URL tệp ảnh"));
        mImportFileButtonurl.setOnAction((event) -> onImportFileButtonActionURL());

        //add to top toolbar 
        mTopToolBar.getItems().add(mImportFileButton);
        mTopToolBar.getItems().add(mImportFileButtonurl);
        mTopToolBar.getItems().add(new Separator(Orientation.VERTICAL));

    }

    /**
     * Action to do on Import Image button click
     */
    private void onImportFileButtonAction() {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Select a file to import");
        fileChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("All Files", "*.*"));
        File selectedFile = fileChooser.showOpenDialog(this.getScene().getWindow());
        if (selectedFile != null) {
            importDataFile(selectedFile);
        }
    }

    /**
     * Imports an image file.
     *
     * @param file Image file.
     */
    private void importDataFile(File file) {
        try {
            //check if file is too big
            if (file.length() > 1024 * 1024) {
                throw new VerifyError("File is too big.");
            }
            //get mime type of the file
            String type = java.nio.file.Files.probeContentType(file.toPath());
            //get html content
            byte[] data = org.apache.commons.io.FileUtils.readFileToByteArray(file);
            String base64data = java.util.Base64.getEncoder().encodeToString(data);
            String htmlData = String.format(
                    "<embed src='data:%s;base64,%s' type='%s' />",
                    type, base64data, type);
            //insert html
            insertHtmlAfterCursor(htmlData);
        } catch (IOException ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Action to do on Import Image button click
     */
    private void onImportFileButtonActionURL() {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Select a file to import");
        fileChooser.setSelectedExtensionFilter(new FileChooser.ExtensionFilter("All Files", "*.*"));
        File selectedFile = fileChooser.showOpenDialog(this.getScene().getWindow());
        if (selectedFile != null) {
            importDataFileURL(selectedFile);
        }
    }

    private void importDataFileURL(File file) {
        try {
            //check if file is too big
            if (file.length() > 1024 * 1024) {
                throw new VerifyError("File is too big.");
            }
            //get mime type of the file
            String imagePath = file.toURI().toString();
            String imgTag = "<img src=\"" + imagePath + "\">";

            //insert html
            insertHtmlAfterCursor(imgTag);
        } catch (Exception ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
        }
    }
}

2) CustomHTMLEditorTest

import javafx.scene.text.Font;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class CustomHTMLEditorTest extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        CustomHTMLEditor htmlEditor = new CustomHTMLEditor();
        htmlEditor.setMaxHeight(Double.MAX_VALUE);
        htmlEditor.setMaxWidth(Double.MAX_VALUE);
        htmlEditor.setMinWidth(0);
        htmlEditor.setMinHeight(0);
        HBox.setHgrow(htmlEditor, Priority.ALWAYS);
        VBox.setVgrow(htmlEditor, Priority.ALWAYS);

        TextArea textArea = new TextArea();
        textArea.setEditable(false);
        textArea.setFont(new Font("Consolas", 14f));
        TabPane root = new TabPane();
        root.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
        root.getTabs().add(new Tab("   Visual   ", htmlEditor));
        root.getTabs().add(new Tab("   HTML   ", textArea));

        root.getSelectionModel().selectedIndexProperty().addListener((event) -> {
            textArea.setText(
                    htmlEditor.getHtmlText()
                            .replace("<", "\n<")
                            .replace(">", ">\n")
                            .replace("\n\n", "\n")
            );
        });

        Scene scene = new Scene(root, 800, 600);
        primaryStage.setTitle("HTML Editor Test!");
        primaryStage.setScene(scene);

        primaryStage.show();
    }
}

3) Kết quả:

Mã HTML

 

Tác giả: Vàng Văn Quyn

Tổng số điểm của bài viết là: 0 trong 0 đánh giá

Click để đánh giá bài viết
Thống kê
  • Đang truy cập11
  • Hôm nay2,544
  • Tháng hiện tại84,129
  • Tổng lượt truy cập9,175,672
Bạn đã không sử dụng Site, Bấm vào đây để duy trì trạng thái đăng nhập. Thời gian chờ: 60 giây