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
相关产品推荐
相关产品推荐

