【问题标题】:JavaFX : Set default printer for WebEngine/WebviewJavaFX:为 WebEngine/Webview 设置默认打印机
【发布时间】:2016-04-21 01:02:54
【问题描述】:

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

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

但是,webview 中发生的事情并不相同。如何在 JavaFX 的网页渲染机制中启用打印。

也可以通过某种方式调用打印函数并通过 JavaScript 将网页或 webview 传递给它。

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

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

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

【问题讨论】:

  • @hotzst :该应用程序处于全屏状态,我无法添加额外的按钮。也可以通过某种方式调用打印函数并将其传递给 JavaScript 的网页或 webview。
  • @hotzst:有什么想法吗?
  • 在示例中,按钮用于触发打印,该功能基本上可以附加到任何事件。可能会添加上下文菜单或在页面完成加载时自动触发。
  • @hotzst 我想通过 Javascript 附加它,老实说我既不是 Javfx 也不是 JS 开发人员。你能帮我解决这个问题吗?谢谢你..

标签: javascript java printing javafx webview


【解决方案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();
      }
    }
  }
}

更多参考资料:

【讨论】:

  • 感谢您的及时回复。您是否正在使用其他版本的 Java,因为找不到您正在使用的方法。你可以在这里看到图片:postimg.org/image/t1fg5nj99。我为此在 SO 上创建了一个房间,请你来,一旦我运行了打印机代码,就可以了:chat.stackoverflow.com/rooms/100769/discussion-with-hotzst
  • 您可能有错误的导入。我使用 Java 8 和 JSObjectnetscape.javascript.JSObject
  • JSOObject 不是问题,webEngine.getLoadWorker 及其后续属性。因此,changed 方法也没有实现。这张图更好:postimg.org/image/8m2kfv175
  • WebView 和 webEngine 分别是 javafx.scene.web.WebViewjavafx.scene.web.WebEngine?
  • 是:导入 javafx.scene.web.WebEngine;导入 javafx.scene.web.WebView;这些在我的 Main.java 中。
猜你喜欢
  • 2015-10-06
  • 2011-07-07
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
相关资源
最近更新 更多