java - 如何在 JavaFX 形状中插入 HTML 文本?

标签 java javafx-8

我想在JavaFx中创建一个基于树的算法可视化,并且符号中有很多子脚本和 super 脚本。我想将这些符号添加到圆形等形状中。

我曾尝试使用 WebView 对象来执行此操作,但它只是覆盖了整个屏幕。

public void start(Stage primaryStage) throws Exception{

        primaryStage.setTitle("Shape Text");
        Group circles = new Group();
        Circle circle = new Circle(50, Color.web("white", 0.7));
        circle.setCenterX(500.0f);
        circle.setCenterY(200.0f);
        circle.setStrokeType(StrokeType.OUTSIDE);
        circle.setStroke(Color.web("white", 0.16));
        circle.setStrokeWidth(4);
        circles.getChildren().add(circle);

        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webEngine.loadContent("<h1>B<sub>0</sub></h1>");

        StackPane stack = new StackPane();
        stack.getChildren().addAll(circles, webView);

        Scene scene = new Scene(stack, 1000, 800, Color.BLACK);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

上面的代码用 HTML 文本替换了整个 View 。我也试过 javafx.scene.text.Text 类,但它不支持 HTML 内容。

提前致谢!

最佳答案

您可能需要做三件事:

  1. Size the WebView to the HTML content (或形状的内部显示区域)。
  2. 制作background of the WebView pages transparent .
  3. Center the HTML content in the WebView , WebView 以 Shape 为中心。

sized webview

下面的代码演示了其中的一些技巧:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.StrokeType;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

import java.lang.reflect.Field;

public class ShapedHTML extends Application {
    @Override
    public void start(Stage stage) throws Exception{
        stage.setTitle("Shape Text");
        Group circles = new Group();
        Circle circle = new Circle(50, Color.web("white", 0.7));
        circle.setCenterX(500.0f);
        circle.setCenterY(200.0f);
        circle.setStrokeType(StrokeType.OUTSIDE);
        circle.setStroke(Color.web("white", 0.16));
        circle.setStrokeWidth(4);
        circles.getChildren().add(circle);

        WebView webView = new WebView();
        WebEngine webEngine = webView.getEngine();
        webView.maxWidthProperty().bind(circle.radiusProperty().multiply(2));
        webView.maxHeightProperty().bind(circle.radiusProperty().multiply(2));
        webEngine.documentProperty().addListener(observable -> {                   
            try {
                // Use reflection to retrieve the WebEngine's private 'page' field.
                Field f = webEngine.getClass().getDeclaredField("page");
                f.setAccessible(true);
                com.sun.webkit.WebPage page = (com.sun.webkit.WebPage) f.get(webEngine);
                page.setBackgroundColor((new java.awt.Color(0, 0, 0, 0)).getRGB());
            } catch (Exception e) {
                System.out.println("Difficulty to make WebView background transparent");
                e.printStackTrace();
            }
        });

        webEngine.loadContent("<h1 id='root' style='background : rgba(0,0,0,0); margin: 0; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);'>B<sub>0</sub></h1>");

        StackPane stack = new StackPane();
        stack.getChildren().addAll(circles, webView);

        Scene scene = new Scene(stack, 1000, 800, Color.BLACK);
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }

}

com.sun 类用法注意事项

上面的代码使用了 com.sun 类(通常不推荐,因为它不是公开支持的 API)。但是,它对我有用(在 Java 8 上),我不知道有什么更好的方法来实现 WebView 背景的透明度。

如果您使用的是更高版本的 Java(例如 Java 11+),那么您将需要提供一些 VM 参数以允许使用相关的 com.sun 类。参见,例如,堆栈溢出问题 Cannot access JavaFX class "WebPage" in IntelliJ-IDEA用于解决 Java 11+ 中 com.sun.webkit.WebPage 的可访问性问题。该问题的答案建议使用以下 VM 参数(我还没有尝试过):

--add-exports javafx.web/com.sun.webkit=projectname

最后一个参数是您在项目的 module-info.java 中声明的模块名称。

关于java - 如何在 JavaFX 形状中插入 HTML 文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57826914/

相关文章:

java - 重写 JFrame.setBackground() 时遇到问题

java - 将查询参数传递到下一页

java - JavaFX 中按钮上的 Svg

java - 有没有办法控制 JavaFX 8 中的菜单弹出位置?

java - 用于导入 Excel 工作表然后将其存储到 servlet 中的数据库中的省时程序

java - 无法理解 Spring security 的行为

java - 设置 JavaFX TextArea 的制表符间距/大小可视化

java - System.getProperty ("line.separator"之间的区别;和 "\n"?

java - 线程锁和条件变量,生产者消费者示例

java - 加载异常: Root value already specified on custom control