21 HTML编辑器
在本章中,您将学习如何通过使用嵌入的HTML编辑器在JavaFX应用程序中编辑文本。
HTMLEditor
控件是一个完全功能的富文本编辑器。它的实现基于HTML5的文档编辑功能,包括以下编辑功能:
-
文本格式设置,包括粗体、斜体、下划线和删除线样式
-
段落设置,如格式、字体和字号
-
前景色和背景色
-
文本缩进
-
项目符号和编号列表
-
文本对齐
-
添加水平线
-
复制和粘贴文本片段
图21-1显示了一个富文本编辑器添加到JavaFX应用程序中。
HTMLEditor
类以HTML字符串的形式呈现编辑内容。例如,在图21-1中编辑器中输入的内容由以下字符串表示:"<html><head></head><body contenteditable="true"><h1>标题</h1><div><u>文本</u>,一些文本</div></body></html>"。
由于HTMLEditor
类是Node
类的扩展,您可以对其实例应用视觉效果或变换。
添加HTML编辑器
和其他UI控件一样,HTMLEditor
组件必须添加到场景中才能在应用程序中显示。您可以直接将其添加到场景中,如示例21-1所示,也可以通过布局容器添加,就像其他示例中所做的那样。
示例21-1 将HTML编辑器添加到JavaFX应用程序中
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.web.HTMLEditor; import javafx.stage.Stage; public class HTMLEditorSample extends Application { @Override public void start(Stage stage) { stage.setTitle("HTMLEditor示例"); stage.setWidth(650); stage.setHeight(300); final HTMLEditor htmlEditor = new HTMLEditor(); htmlEditor.setPrefHeight(245); Scene scene = new Scene(htmlEditor); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
编译和运行这段代码片段会产生如图21-2所示的窗口。
HTMLEditor
类提供了一种方法来定义应用程序启动时在编辑区域中显示的内容。使用setHtmlText
方法,如示例21-2所示,设置编辑器的初始文本。
示例21-2 设置文本内容
private final String INITIAL_TEXT = "<html><body>Lorem ipsum dolor sit " + "amet, consectetur adipiscing elit. Nam tortor felis, pulvinar " + "in scelerisque cursus, pulvinar at ante. Nulla consequat" + "congue lectus in sodales. Nullam eu est a felis ornare " + "bibendum et nec tellus. Vivamus non metus tempus augue auctor " + "ornare. Duis pulvinar justo ac purus adipiscing pulvinar. " + "Integer congue faucibus dapibus. Integer id nisl ut elit " + "aliquam sagittis gravida eu dolor. Etiam sit amet ipsum " + "sem.</body></html>"; htmlEditor.setHtmlText(INITIAL_TEXT);
图21-3演示了使用setHTMLText
方法设置的文本编辑器。
您可以在此字符串中使用HTML标签来应用初始渲染内容的特定格式。
使用HTML编辑器构建用户界面
您可以使用HTMLEditor
控件在JavaFX应用程序中实现典型的用户界面(UI)。例如,您可以实现即时通讯服务、电子邮件客户端,甚至内容管理系统。
下面是一个在许多电子邮件客户端应用程序中找到的消息撰写窗口的用户界面。
示例 21-3 将HTMLEditor添加到电子邮件客户端UI
import javafx.application.Application; import javafx.collections.FXCollections; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; import javafx.scene.web.HTMLEditor; import javafx.stage.Stage; public class HTMLEditorSample extends Application { @Override public void start(Stage stage) { stage.setTitle("消息撰写"); stage.setWidth(650); stage.setHeight(500); Scene scene = new Scene(new Group()); final VBox root = new VBox(); root.setPadding(new Insets(8, 8, 8, 8)); root.setSpacing(5); root.setAlignment(Pos.BOTTOM_LEFT); final GridPane grid = new GridPane(); grid.setVgap(5); grid.setHgap(10); final ChoiceBox sendTo = new ChoiceBox(FXCollections.observableArrayList( "收件人:", "抄送:", "密送:") ); sendTo.setPrefWidth(100); GridPane.setConstraints(sendTo, 0, 0); grid.getChildren().add(sendTo); final TextField tbTo = new TextField(); tbTo.setPrefWidth(400); GridPane.setConstraints(tbTo, 1, 0); grid.getChildren().add(tbTo); final Label subjectLabel = new Label("主题:"); GridPane.setConstraints(subjectLabel, 0, 1); grid.getChildren().add(subjectLabel); final TextField tbSubject = new TextField(); tbTo.setPrefWidth(400); GridPane.setConstraints(tbSubject, 1, 1); grid.getChildren().add(tbSubject); root.getChildren().add(grid); final HTMLEditor htmlEditor = new HTMLEditor(); htmlEditor.setPrefHeight(370); root.getChildren().addAll(htmlEditor, new Button("发送")); final Label htmlLabel = new Label(); htmlLabel.setWrapText(true); scene.setRoot(root); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
用户界面包括一个选择框用于选择收件人类型,两个文本字段用于输入电子邮件地址和消息的主题,一个标签用于指示主题字段,编辑器和发送按钮。
UI控件通过使用Grid
和VBox
布局容器在应用场景上排列。当您编译和运行此应用程序时,窗口显示的是用户在撰写周报时的输出,如图21-4所示。
您可以通过调用setPrefWidth
或setPrefHeight
方法为HTMLEditor
对象设置特定的宽度和高度值,或者可以将其宽度和高度未指定。 示例21-3指定了组件的高度。其宽度由VBox
布局容器定义。当文本内容超过编辑区域的高度时,垂直滚动条会出现。
获取HTML内容
使用JavaFX的HTMLEditor
控件,您可以编辑文本并设置初始内容。此外,您还可以获取以HTML格式输入和编辑的文本。在示例21-4中实现了这个任务的应用程序。
示例21-4 检索HTML代码
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;
public class HTMLEditorSample extends Application {
private final String INITIAL_TEXT = "Lorem ipsum dolor sit "
+ "amet, consectetur adipiscing elit. Nam tortor felis, pulvinar "
+ "in scelerisque cursus, pulvinar at ante. Nulla consequat"
+ "congue lectus in sodales. Nullam eu est a felis ornare "
+ "bibendum et nec tellus. Vivamus non metus tempus augue auctor "
+ "ornare. Duis pulvinar justo ac purus adipiscing pulvinar. "
+ "Integer congue faucibus dapibus. Integer id nisl ut elit "
+ "aliquam sagittis gravida eu dolor. Etiam sit amet ipsum "
+ "sem.";
@Override
public void start(Stage stage) {
stage.setTitle("HTMLEditor示例");
stage.setWidth(650);
stage.setHeight(500);
Scene scene = new Scene(new Group());
VBox root = new VBox();
root.setPadding(new Insets(8, 8, 8, 8));
root.setSpacing(5);
root.setAlignment(Pos.BOTTOM_LEFT);
final HTMLEditor htmlEditor = new HTMLEditor();
htmlEditor.setPrefHeight(245);
htmlEditor.setHtmlText(INITIAL_TEXT);
final TextArea htmlCode = new TextArea();
htmlCode.setWrapText(true);
ScrollPane scrollPane = new ScrollPane();
scrollPane.getStyleClass().add("noborder-scroll-pane");
scrollPane.setContent(htmlCode);
scrollPane.setFitToWidth(true);
scrollPane.setPrefHeight(180);
Button showHTMLButton = new Button("生成HTML代码");
root.setAlignment(Pos.CENTER);
showHTMLButton.setOnAction((ActionEvent arg0) -> {
htmlCode.setText(htmlEditor.getHtmlText());
});
root.getChildren().addAll(htmlEditor, showHTMLButton, scrollPane);
scene.setRoot(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
在HTMLEditor
对象上调用getHTMLText
方法可以获取编辑的内容并将其呈现为HTML字符串。这些信息传递给文本区域,以便您可以观察、复制和粘贴生成的HTML代码。在图21-5中显示了在HTMLEditor示例中正在编辑的文本的HTML代码。
同样地,您可以获取HTML代码并将其保存在文件中,或将其发送到WebView
对象以同步编辑器和嵌入式浏览器中的内容。请参阅在示例21-5中实现此任务的方法。
示例21-5 在浏览器中渲染编辑的HTML内容
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.VBox; import javafx.scene.web.HTMLEditor; import javafx.scene.web.WebEngine; import javafx.scene.web.WebView; import javafx.stage.Stage; public class HTMLEditorSample extends Application { private final String INITIAL_TEXT = "Lorem ipsum dolor sit " + "amet, consectetur adipiscing elit. Nam tortor felis, pulvinar " + "in scelerisque cursus, pulvinar at ante. Nulla consequat" + "congue lectus in sodales. Nullam eu est a felis ornare " + "bibendum et nec tellus. Vivamus non metus tempus augue auctor " + "ornare. Duis pulvinar justo ac purus adipiscing pulvinar. " + "Integer congue faucibus dapibus. Integer id nisl ut elit " + "aliquam sagittis gravida eu dolor. Etiam sit amet ipsum " + "sem."; @Override public void start(Stage stage) { stage.setTitle("HTMLEditor示例"); stage.setWidth(650); stage.setHeight(500); Scene scene = new Scene(new Group()); VBox root = new VBox(); root.setPadding(new Insets(8, 8, 8, 8)); root.setSpacing(5); root.setAlignment(Pos.BOTTOM_LEFT); final HTMLEditor htmlEditor = new HTMLEditor(); htmlEditor.setPrefHeight(245); htmlEditor.setHtmlText(INITIAL_TEXT); final WebView browser = new WebView(); final WebEngine webEngine = browser.getEngine(); ScrollPane scrollPane = new ScrollPane(); scrollPane.getStyleClass().add("noborder-scroll-pane"); scrollPane.setStyle("-fx-background-color: white"); scrollPane.setContent(browser); scrollPane.setFitToWidth(true); scrollPane.setPrefHeight(180); Button showHTMLButton = new Button("在浏览器中加载内容"); root.setAlignment(Pos.CENTER); showHTMLButton.setOnAction((ActionEvent arg0) -> { webEngine.loadContent(htmlEditor.getHtmlText()); }); root.getChildren().addAll(htmlEditor, showHTMLButton, scrollPane); scene.setRoot(root); stage.setScene(scene); stage.show(); } public static void main(String[] args) { launch(args); } }
从htmlEditor
组件接收到的HTML代码加载到指定内容的WebEngine
对象中,该对象用于嵌入浏览器的内容。每次用户点击“在浏览器中加载内容”按钮时,编辑的内容都会在浏览器中更新。 图21-6演示了示例21-5的操作。
您可以使用Text
组件向UI添加非编辑文本内容。有关Text
组件的更多信息,请参阅在JavaFX中使用文本。
相关API文档