You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX HTMLEditor如何通过程序触发字体大小变更功能

JavaFX HTMLEditor 触发字体大小ComboBox变更不生效问题

我使用的HTMLEditor组件隐藏了完整工具栏,希望通过右键菜单替代工具栏让用户调整字体大小。我认为修改编辑器HTML内容最稳妥的方式是触发工具栏上控制字体大小的ComboBox的变更事件,为简化演示,本例中我尝试通过按钮点击触发该变更。
下方示例中我创建了一个标准HTML Editor,然后添加按钮尝试从编辑器中提取对应的ComboBox,将其值设置为对应选项并触发动作事件。按逻辑,若在编辑器中选中文本后点击按钮,选中文本的字体大小应该发生变更,但实际并未生效。
我已经用该方法成功实现了工具栏切换按钮、颜色选择器的触发,但是对ComboBox无法生效。
以下是可复现问题的示例代码:

package main;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

public class Main extends Application {
    
    boolean ifLoadComplete = false;
    
    @Override
    public void start(Stage _primaryStage) {
        VBox vBox = new VBox();
        vBox.setPrefWidth(800);
        vBox.setPrefHeight(800);

        HTMLEditor editor = new HTMLEditor();
        vBox.getChildren().add(editor);
        
        WebView webView = (WebView)editor.lookup("WebView");
        WebEngine webEngine = webView.getEngine();
        webEngine.getLoadWorker().stateProperty().addListener(
            new ChangeListener<Object>() {
                @SuppressWarnings({"restriction"})
                @Override
                public void changed(ObservableValue<?> observableValue, Object oldValue, Object newValue) {
                    // 确认内容加载完成,该回调会触发多次
                    if (newValue != Worker.State.SUCCEEDED) { 
                        return; 
                    }       
                    ifLoadComplete = true;
                }
            }
        );

        Button testButton = new Button("Test");
        testButton.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent arg0) {
                if (!ifLoadComplete) return;
                System.out.println("Setting font size combo!");
                ComboBox combo = (ComboBox)editor.lookup(".font-menu-button");
                combo.getSelectionModel().select(3);
                combo.fireEvent(new ActionEvent());
            }
        });
        vBox.getChildren().add(testButton);
        
        String content = "<p>This is a test!</p>";
        webEngine.loadContent(content);
        
        Scene scene = new Scene(vBox);
        _primaryStage.setTitle("Test Program");
        _primaryStage.setScene(scene);
        _primaryStage.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

解决方案

问题原因

你之前的方法对切换按钮、颜色选择器生效,但对ComboBox无效,是因为HTMLEditor内置的字体大小ComboBox没有监听普通的ActionEvent,仅通过fireEvent(new ActionEvent())无法触发其内部绑定的文本修改逻辑。

修复方案1:调整原有控件触发逻辑

仅需要修改按钮点击事件中的ComboBox操作代码,在选中选项后主动触发选择变更的通知逻辑即可:

testButton.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent arg0) {
        if (!ifLoadComplete) return;
        System.out.println("Setting font size combo!");
        ComboBox combo = (ComboBox)editor.lookup(".font-menu-button");
        combo.getSelectionModel().select(3);
        // 新增下面两行代码触发控件的文本修改逻辑
        combo.show();
        combo.hide();
    }
});

修复方案2:更稳妥的直接操作富文本方案(推荐)

不需要依赖工具栏控件的查找,哪怕工具栏完全隐藏也可以正常运行,直接通过WebView的JS执行能力调用浏览器原生的富文本编辑命令修改字体大小:

testButton.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent arg0) {
        if (!ifLoadComplete) return;
        // 第三个参数对应字体大小编号,和工具栏ComboBox的选项序号完全对应
        webEngine.executeScript("document.execCommand('fontSize', false, '3')");
    }
});

这种方案兼容性更强,不会因为JavaFX版本迭代修改了内置控件的样式类名或事件逻辑导致功能失效。


内容的提问来源于stack exchange,提问作者Geoff L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:36:04