javaFX学习笔记之 WebView中打印html(转载)

参考的原文链接:DOC-04-09 打印HTML内容 | JavaFX中文资料

WebView组件中加载的Web页面。

使用JavaFX8中提供的打印API,你可以打印JavaFX程序的图形化内容。在javafx.print包中有对应的类和枚举。

使用打印API

要想在JavaFX程序中启用打印功能,你需要使用PrinterJob类。该类表示与系统默认打印机相关联的一个打印任务。使用Printer类来控制一个打印机来执行特定的打印任务。对于每一个打印任务,你都可以通过使用JobSetting类的属性来指定任务设置,如校对(collation)、份数(copies)、页面布局(pageLayout)、页面范围(pageRanges)、纸张来源(paperSource)、打印颜色(printColor)、打印分辨率(printResolution)、打印质量(printQuality)和单双面(printSides)

你可以打印场景图的任何节点,包括根节点。你也可以打印那些没添加到场景中的节点。使用printPage方法job.printPage(node)来为某node初始化一个打印任务 

在使用JavaFX的web组件时,你通常需要打印一个加载到浏览器中的HTML页面而不是程序UI本身。这就是为什么WebEngine类中添加了print方法,此方法就是为了打印与webEngine对象关联的HTML页面而生的 

添加上下文菜单启用打印功能

通常来讲,需要把打印指令添加到程序的菜单或者工具栏中

 

//adding context menu
final ContextMenu cm = new ContextMenu();
MenuItem cmItem1 = new MenuItem("Print");
cm.getItems().add(cmItem1);
toolBar.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {
    if (e.getButton() == MouseButton.SECONDARY) {
        cm.show(toolBar, e.getScreenX(), e.getScreenY());
    }
}); 

处理打印任务

将打印的菜单添加到程序UI中以后,就可以定义打印的动作了。首先,你需要创建一个PrinterJob对象;然后,调用WebEngine.print方法,将该printJob对象作为参数传进去

 

对printerJob的非空判断很重要,因为如果系统中没有可用的打印机则createPrinterJob方法会返回null 

若想扩充WebViewSample程序的打印功能,请使用javafx.print包中的类。

 创建工具栏的弹出式菜单

1

2

3

4

5

6

7

8

9

//adding context menu

final ContextMenu cm = new ContextMenu();

MenuItem cmItem1 = new MenuItem("Print");

cm.getItems().add(cmItem1);

toolBar.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {

    if (e.getButton() == MouseButton.SECONDARY) {

        cm.show(toolBar, e.getScreenX(), e.getScreenY());

    }

});

把上例中的代码片段加到之前的WebViewSample程序中,运行以后右键点击工具栏打印菜单即出现了

将打印的菜单添加到程序UI中以后,就可以定义打印的动作了。首先,你需要创建一个PrinterJob对象;然后,调用WebEngine.print方法,将该printJob对象作为参数传进去。请参考例9-2。

调用WebEngine.print方法

1

2

3

4

5

6

7

8

//processing print job

cmItem1.setOnAction((ActionEvent e) -> {

    PrinterJob job = PrinterJob.createPrinterJob();

    if (job != null) {

        webEngine.print(job);

        job.endJob();

    }

});

对printerJob的非空判断很重要,因为如果系统中没有可用的打印机则createPrinterJob方法会返回null。

________________________________________

help.html 的代码

<html lang="en">
    <head>
        <!-- Visibility toggle script -->
        <script type="text/javascript">
            <!--
            function toggle_visibility(id) {
                var e = document.getElementById(id);
                if (e.style.display == 'block')
                    e.style.display = 'none';
                else
                    e.style.display = 'block';
            }
//-->
        </script>
    </head>
    <body>
        <h1>Online Help</h1>
        <p class="boxtitle"><a href="#" οnclick="toggle_visibility('help_topics');" 
  class="boxtitle">[+] Show/Hide Help Topics</a></p>    
        <ul id="help_topics" style='display:none;'>
            <li>Products - Extensive overview of Oracle hardware and software products, 
                and summary Oracle consulting, support, and educational services. </li>
            <li>Blogs - Oracle blogging community (use the Hide All and Show All buttons 
                to collapse and expand the list of topics).</li>
            <li>Documentation - Landing page to start learning Java. The page contains 
                links to the Java tutorials, developer guides, and API documentation.</li>
            <li>Partners - Oracle partner solutions and programs. Popular resources and 
                membership opportunities.</li>
        </ul>
    </body>
</html>

 ________________

import javafx.application.Platform;

/**
 * @author zhaoyong
 * @Date 2022/10/20
 * @Description
 */
public class JavaApp {

    public void exit() {
        Platform.exit();
    }
}

________________ 

import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.web.PopupFeatures;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebHistory;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;
class Browser extends Region {
    private HBox toolBar;

    final private static String[] imageFiles = new String[]{//图片路径数组
            "folder_16.jpg",
            "folder_16.jpg",
            "root.jpg",
            "root.jpg",
            "root.jpg"
    };
    final private static String[] captions = new String[]{//标题名称数组
            "百度",
            "Blogs",
            "Documentation",
            "Partners",
            "Help"
    };

    final private static String[] urls = new String[]{//添加的测试url集合
            "http://www.baidu.com",
            "http://blogs.oracle.com/",
            "http://docs.oracle.com/javase/index.html",
            "http://www.oracle.com/partners/index.html",
            Browser.class.getResource("help.html").toExternalForm()
    };

    final ImageView selectedImage = new ImageView();//实例化图标视图对象
    final Hyperlink[] hpls = new Hyperlink[captions.length];//定义一个新的超级链接对象
    final Image[] images = new Image[imageFiles.length];//创建一个图片数组
    final WebView browser = new WebView();//定义一个浏览器内核对象
    final WebEngine webEngine = browser.getEngine();//获取浏览器引擎
    final Button toggleHelpTopics = new Button("Toggle Help Topics");
    final ComboBox comboBox = new ComboBox();
    private boolean needDocumentationButton = false;

    final WebView smallView = new WebView();

    public Browser() {
        //apply the styles
        getStyleClass().add("browser");//外观添加样式类



        for (int i = 0; i < captions.length; i++) {
            final Hyperlink hpl = hpls[i] = new Hyperlink(captions[i]);//创建带标题的超级链接对象
            Image image = images[i] =
                    new Image(getClass().getResourceAsStream(imageFiles[i]));//根据文件路径创建相关图片对象
            hpl.setGraphic(new ImageView(image));//超级链接上添加图片
            final String url = urls[i];//具体url的读取
            final boolean addButton = (hpl.getText().equals("Help"));
            hpl.setOnAction((ActionEvent e) -> {//超级链接对象添加点击处理事件处理回调函数机制的编写
                needDocumentationButton = addButton;
                    webEngine.load(url);//让浏览器内核加载url指向的资源

            });
        }



        // create the toolbar
        toolBar = new HBox();
        toolBar.setAlignment(Pos.CENTER);
        toolBar.getStyleClass().add("browser-toolbar");//水平布局盒子对象的外部样式引入
        toolBar.getChildren().addAll(hpls);//水平布局盒子上面添加超级链接对象
        toolBar.getChildren().add(comboBox);//创建comboBox
        toolBar.getChildren().add(createSpacer());//创建一个空白区域

        //set action for the button
        toggleHelpTopics.setOnAction((ActionEvent t) -> {//让浏览器内核执行js代码,本例中是调用javascript函数
            webEngine.executeScript("toggle_visibility('help_topics')");
        });
        //add components

        smallView.setPrefSize(300, 200);

        //handle popup windows
        webEngine.setCreatePopupHandler(
                (PopupFeatures config) -> {
                    smallView.setFontScale(0.8);
                    if (!toolBar.getChildren().contains(smallView)) {
                        toolBar.getChildren().add(smallView);
                    }
                    return smallView.getEngine();
                });


        // process page loading
        webEngine.getLoadWorker().stateProperty().addListener(
                (ObservableValue<? extends State> ov, State oldState,
                 State newState) -> {
                    toolBar.getChildren().remove(toggleHelpTopics);
                    if (newState == State.SUCCEEDED) {
                        JSObject win
                                = (JSObject) webEngine.executeScript("window");//获取浏览器引擎中的javascript语言中的window全局对象
                        win.setMember("app", new JavaApp());//创建一个全局对象app(类型是前文中自定义的JavaApp类型),将此app对象置入浏览器引擎中的window对象体内(window对象上下文环境中)
                        if (needDocumentationButton) {
                            toolBar.getChildren().add(toggleHelpTopics);
                        }
                    }
                });

        // load the home page
        webEngine.load("http://www.oracle.com/products/index.html");//浏览器引擎初始化url加载
        final WebHistory history = webEngine.getHistory();
        history.getEntries().addListener(new ListChangeListener<WebHistory.Entry>() {
            @Override
            public void onChanged(Change<? extends WebHistory.Entry> c) {
                c.next();
                for (WebHistory.Entry e : c.getRemoved()) {
                    comboBox.getItems().remove(e.getUrl());
                }
                for (WebHistory.Entry e : c.getAddedSubList()) {
                    comboBox.getItems().add(e.getUrl());
                }
            }
        });

        comboBox.setPrefWidth(60);
        comboBox.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent ev) {
                int offset = comboBox.getSelectionModel().getSelectedIndex() - history.getCurrentIndex();
                history.go(offset);
            }
        });

        //adding context menu
        final ContextMenu cm = new ContextMenu();
        MenuItem cmItem1 = new MenuItem("打印");
        cm.getItems().add(cmItem1);
        toolBar.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> {
            if (e.getButton() == MouseButton.SECONDARY) {
                cm.show(toolBar, e.getScreenX(), e.getScreenY());
            }
        });

        cmItem1.setOnAction((ActionEvent e) -> {
            PrinterJob job = PrinterJob.createPrinterJob();//创建打印任务
            if (job != null) {
                webEngine.print(job);//将web浏览器引擎的显示内容挂载到打印任务组件上去
                job.endJob();
            }
        });
        getChildren().add(toolBar);//添加盒子布局对象到本实例对象的根节点孩子集合上
        getChildren().add(browser);//添加浏览器区域对象到本实例对象的根节点孩子集合上
    }

    private Node createSpacer() {
        Region spacer = new Region();
        HBox.setHgrow(spacer, Priority.ALWAYS);
        return spacer;
    }

    @Override
    protected void layoutChildren() {//浏览器页面初始化页面样式加载重写父类Region对象同名方法
        double w = getWidth();
        double h = getHeight();
        double tbHeight = toolBar.prefHeight(w);
        layoutInArea(browser, 0, 0, w, h - tbHeight, 0, HPos.CENTER, VPos.CENTER);
        layoutInArea(toolBar, 0, h - tbHeight, w, tbHeight, 0, HPos.CENTER, VPos.CENTER);
    }

    @Override
    protected double computePrefWidth(double height) {//浏览器创后宽度设置重写了父类Region对象同名方法
        return 900;
    }

    @Override
    protected double computePrefHeight(double width) {
        return 600;
    }
}

____________________

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Hyperlink;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 * @author zhaoyong
 * @Date 2022/10/18
 * @Description
 */
public class WebViewTest extends Application {

    private Scene scene;

    @Override
    public void start(Stage stage) {
        // create scene
        stage.setTitle("Web View");
        scene = new Scene(new Browser(), 900, 600, Color.web("#666970"));//场景上挂载浏览器对象new Browser()
        stage.setScene(scene);
        scene.getStylesheets().add("BrowserToolbar.css");//场景对象引用外部css文件
        // show stage
        stage.show();//舞台展现
    }

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

____________________________________________

若想扩充WebViewSample程序的打印功能,请使用javafx.print包中的类。

在你的JavaFX程序中,你可以使用TabPane类实现浏览器标签页功能,当用户添加新的标签页时创建新的WebView对象即可。

若要进一步增强该程序,你可以应用特效、变形和动画转换。你也可以添加更多的WebView实例到程序的scene中。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值