JavaFX:为WebEngine / Webview设置默认打印机

时间:2016-01-15 12:23:18

标签: javascript java printing javafx webview

我正在开发一个JavaFX项目,其中我有一堆静态HTML和JS页面,我正在加载index.html用户可以查看并点击链接等。

现在,通常当我们使用FirefoxChromium之类的浏览器时,调用print命令会执行打印任务。

BUt与webview中发生的事情不一样。如何在JavaFX的网页呈现机制中启用打印。

还可以通过某种方式调用打印功能并将其从JavaScript传递给网页或网页。

到目前为止,这是我的代码:

public class Main extends Application {

    private Scene scene;
    MyBrowser myBrowser;

    @Override
    public void start(Stage primaryStage) throws Exception{
        primaryStage.setTitle("Test web");
        Screen screen = Screen.getPrimary();
        myBrowser = new MyBrowser();
        scene = new Scene(myBrowser, 1080, 1920);
        myBrowser.setPrefSize(1080, 1920);
        Rectangle2D bounds = screen.getVisualBounds();
        primaryStage.setX(bounds.getMinX());
        primaryStage.setY(bounds.getMinY());
        scene.setRoot(myBrowser);
        primaryStage.setScene(scene);
        primaryStage.setMaximized(false);
        primaryStage.setFullScreen(true);
        primaryStage.show();
    }


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


class MyBrowser extends Region {

    final String hellohtml = "hello.html";

    WebView webView = new WebView();
    WebEngine webEngine = webView.getEngine();

    public MyBrowser(){

        URL urlHello = getClass().getResource("hello.html");
        webEngine.load(urlHello.toExternalForm());
        webView.setPrefSize(1080, 1920);
        webView.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {
            @Override public void onChanged(Change<? extends Node> change) {
                Set<Node> deadSeaScrolls = webView.lookupAll(".scroll-bar");
                for (Node scroll : deadSeaScrolls) {
                    scroll.setVisible(true);
                }
            }
        });
        getChildren().add(webView);
    }
}

任何建议或指示都会很好。谢谢..: - )

1 个答案:

答案 0 :(得分:1)

假设你在JS的页面中有这样的东西:

<script type="text/javascript">
  function printInJava() {
    ...
  }
</script>

以下是在Java代码和JavaScript之间注册桥梁的方法:

WebEngine webEngine = webView.getEngine();
    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
        @Override
        public void changed(ObservableValue<? extends State> ov, State t, State t1) {
            if (t1 == Worker.State.SUCCEEDED) {
                JSObject window = (JSObject) webEngine.executeScript("window");
                window.setMember("app", this);
            }
        }
    });

在同一个类中,您有从JavaScript触发的方法:

public void print() {
  print(webView);
}

方法print(Node)this example相同。但我必须承认,我实际上没有尝试过这些代码,从外观上看,你可能会遇到一些在多个页面上进行缩放和打印的问题。

现在您可以简单地完成JavaScript:

function printInJava() {
  app.print(); // call out the Java print method defined on the register variable app
}

将所有这些放在一起时,您最终会得到以下代码:

import javafx.application.Application;
import javafx.collections.ListChangeListener;
import javafx.concurrent.Worker;
import javafx.print.PageLayout;
import javafx.print.PageOrientation;
import javafx.print.Paper;
import javafx.print.Printer;
import javafx.print.PrinterJob;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.transform.Scale;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

import java.net.URL;
import java.util.Set;

public class Main extends Application {

  private Scene scene;
  MyBrowser myBrowser;

  @Override
  public void start(Stage primaryStage) throws Exception{
    primaryStage.setTitle("Test web");

    myBrowser = new MyBrowser();
    scene = new Scene(myBrowser, 1080, 1920);

    primaryStage.setScene(scene);
    primaryStage.setFullScreen(true);
    primaryStage.show();

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


class MyBrowser extends Region {

  final String hellohtml = "index.html";

  WebView webView = new WebView();
  WebEngine webEngine = webView.getEngine();


  public MyBrowser(){

    URL urlHello = getClass().getResource(hellohtml);
    webEngine.load(urlHello.toExternalForm());
    webView.setPrefSize(1080, 1920);
    webView.getChildrenUnmodifiable().addListener(new ListChangeListener<Node>() {
      @Override public void onChanged(Change<? extends Node>
                                          change) {
        Set<Node> deadSeaScrolls = webView.lookupAll(".scroll-bar");
        for (Node scroll : deadSeaScrolls) {
          scroll.setVisible(true);
        }
      }
    });

  webEngine. getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue == Worker.State.SUCCEEDED) {
      JSObject window = (JSObject) webEngine.executeScript("window");
      window.setMember("app", this);
    }   });

    getChildren().add(webView);
  }

  /**
   * Callback function from the JavaScript code.
   */
  public void print() {
    print(webView);
  }

  /** Scales the node based on the standard letter, portrait paper to be printed.
   * @param node The scene node to be printed.
   */
  public void print(final Node node) {
    Printer printer = Printer.getDefaultPrinter();
    PageLayout pageLayout = printer.createPageLayout(Paper.NA_LETTER, PageOrientation.PORTRAIT, Printer.MarginType.DEFAULT);
    double scaleX = pageLayout.getPrintableWidth() / node.getBoundsInParent().getWidth();
    double scaleY = pageLayout.getPrintableHeight() / node.getBoundsInParent().getHeight();
    node.getTransforms().add(new Scale(scaleX, scaleY));

    PrinterJob job = PrinterJob.createPrinterJob();
    if (job != null) {
      boolean success = job.printPage(node);
      if (success) {
        job.endJob();
      }
    }
  }
}

进一步参考: