展开 JavaFX 组件中的文本
Expand text in a JavaFX component
我有一个字符串(大约一段长,包含换行符和 unicode),我在 JavaFX 组件中显示(现在是一个大标签,但可以选择更改特定实现),当用户单击一个词,我希望那个词是 "expanded" ("word" -> "w o r d")
(其实,这不完全正确,我想将这个词传递给更复杂的函数并使用结果,但是函数是什么无关紧要)
我可以生成 html 并使用它,但是在 html 中通过单击它来更改文本的所有方法似乎都需要 java 脚本,我不知道java 处理嵌入式 js 的能力如何。
我可以生成一堆标签,每个单词一个,然后编写一个 onClick 侦听器,但间距可能会搞砸。
我可以使用一个标签并使用一个 onClick 侦听器,并尝试使用 mouseX 和 mouseY 找出正在点击的单词,但这非常棘手,我想知道是否有更好的解决方案。
有什么建议吗?
这是一个在 TextFlow
中使用 Text
个对象集合的示例。这样做使您能够直接在每个文本对象上注册一个鼠标处理程序。这还在文本对象上设置了一个 CSS 伪类,因此您可以使用 CSS 样式表轻松更改扩展词的样式。
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class ExpandingTextExample extends Application {
// The following text is taken from the "JavaFX CSS Reference Guide":
// http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html
private static final String text = "Never has styling a Java UI been easier than "
+ "with JavaFX and Cascading Style Sheets (CSS). "
+ "Going from one theme to another, or "
+ "customizing the look of just one control, "
+ "can all be done through CSS. To the novice, "
+ "this may be unfamiliar territory; "
+ "but the learning curve is not that great. "
+ "Give CSS styling a try and the benefits will soon be apparent. "
+ "You can also split the design and development workflow, or "
+ "defer design until later in the project. "
+ "Up to the last minute changes, and even post-deployment "
+ "changes, in the UI's look can be achieved through JavaFX CSS. "
+ "\n"
+ "The structure of this document is as follows. "
+ "First, there is a description of all "
+ "value types for JavaFX CSS properties. "
+ "Where appropriate, this includes a grammar "
+ "for the syntax of values of that type. "
+ "Then, for each scene‑graph node that supports CSS styles, "
+ "a table is given that lists the properties that are supported, "
+ "along with type and semantic information. "
+ "The pseudo‑classes for each class are also given. "
+ "The description of CSS properties continues for the controls. "
+ "For each control, the substructure of that control's skin is given, "
+ "along with the style‑class names for the Region "
+ "objects that implement that substructure." ;
private static final String NBSP = "\u2007" ;
private final PseudoClass expanded = PseudoClass.getPseudoClass("expanded");
@Override
public void start(Stage primaryStage) {
String[] words = text.split(" ");
TextFlow flow = new TextFlow();
flow.setLineSpacing(5);
Stream.of(words)
.map(s -> s.concat(" "))
.map(Text::new)
.peek(text -> text.getStyleClass().add("word"))
.peek(text -> text.setOnMousePressed(event -> expand(text)))
.forEach(flow.getChildren()::add);
ScrollPane scroller = new ScrollPane();
scroller.setFitToWidth(true);
scroller.setContent(flow);
Scene scene = new Scene(scroller, 600, 400);
scene.getStylesheets().add("expanding-text.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private void expand(Text text) {
if (text.getPseudoClassStates().contains(expanded)) { //collapse:
String[] letters = text.getText().split(NBSP);
StringBuilder newText = new StringBuilder();
Stream.of(letters).forEach(newText::append);
text.setText(newText.toString());
text.pseudoClassStateChanged(expanded, false);
} else {
String[] letters = text.getText().split("");
text.setText(String.join(NBSP, letters));
text.pseudoClassStateChanged(expanded, true);
}
}
public static void main(String[] args) {
launch(args);
}
}
样式表正在展开-text.css:
.word:expanded {
-fx-font-size: 12pt ;
-fx-font-weight: bold ;
}
这是启动时的屏幕截图:
这是点击第一段中每个句子的第一个单词后的结果:
我有一个字符串(大约一段长,包含换行符和 unicode),我在 JavaFX 组件中显示(现在是一个大标签,但可以选择更改特定实现),当用户单击一个词,我希望那个词是 "expanded" ("word" -> "w o r d")
(其实,这不完全正确,我想将这个词传递给更复杂的函数并使用结果,但是函数是什么无关紧要)
我可以生成 html 并使用它,但是在 html 中通过单击它来更改文本的所有方法似乎都需要 java 脚本,我不知道java 处理嵌入式 js 的能力如何。
我可以生成一堆标签,每个单词一个,然后编写一个 onClick 侦听器,但间距可能会搞砸。
我可以使用一个标签并使用一个 onClick 侦听器,并尝试使用 mouseX 和 mouseY 找出正在点击的单词,但这非常棘手,我想知道是否有更好的解决方案。
有什么建议吗?
这是一个在 TextFlow
中使用 Text
个对象集合的示例。这样做使您能够直接在每个文本对象上注册一个鼠标处理程序。这还在文本对象上设置了一个 CSS 伪类,因此您可以使用 CSS 样式表轻松更改扩展词的样式。
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;
public class ExpandingTextExample extends Application {
// The following text is taken from the "JavaFX CSS Reference Guide":
// http://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html
private static final String text = "Never has styling a Java UI been easier than "
+ "with JavaFX and Cascading Style Sheets (CSS). "
+ "Going from one theme to another, or "
+ "customizing the look of just one control, "
+ "can all be done through CSS. To the novice, "
+ "this may be unfamiliar territory; "
+ "but the learning curve is not that great. "
+ "Give CSS styling a try and the benefits will soon be apparent. "
+ "You can also split the design and development workflow, or "
+ "defer design until later in the project. "
+ "Up to the last minute changes, and even post-deployment "
+ "changes, in the UI's look can be achieved through JavaFX CSS. "
+ "\n"
+ "The structure of this document is as follows. "
+ "First, there is a description of all "
+ "value types for JavaFX CSS properties. "
+ "Where appropriate, this includes a grammar "
+ "for the syntax of values of that type. "
+ "Then, for each scene‑graph node that supports CSS styles, "
+ "a table is given that lists the properties that are supported, "
+ "along with type and semantic information. "
+ "The pseudo‑classes for each class are also given. "
+ "The description of CSS properties continues for the controls. "
+ "For each control, the substructure of that control's skin is given, "
+ "along with the style‑class names for the Region "
+ "objects that implement that substructure." ;
private static final String NBSP = "\u2007" ;
private final PseudoClass expanded = PseudoClass.getPseudoClass("expanded");
@Override
public void start(Stage primaryStage) {
String[] words = text.split(" ");
TextFlow flow = new TextFlow();
flow.setLineSpacing(5);
Stream.of(words)
.map(s -> s.concat(" "))
.map(Text::new)
.peek(text -> text.getStyleClass().add("word"))
.peek(text -> text.setOnMousePressed(event -> expand(text)))
.forEach(flow.getChildren()::add);
ScrollPane scroller = new ScrollPane();
scroller.setFitToWidth(true);
scroller.setContent(flow);
Scene scene = new Scene(scroller, 600, 400);
scene.getStylesheets().add("expanding-text.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private void expand(Text text) {
if (text.getPseudoClassStates().contains(expanded)) { //collapse:
String[] letters = text.getText().split(NBSP);
StringBuilder newText = new StringBuilder();
Stream.of(letters).forEach(newText::append);
text.setText(newText.toString());
text.pseudoClassStateChanged(expanded, false);
} else {
String[] letters = text.getText().split("");
text.setText(String.join(NBSP, letters));
text.pseudoClassStateChanged(expanded, true);
}
}
public static void main(String[] args) {
launch(args);
}
}
样式表正在展开-text.css:
.word:expanded {
-fx-font-size: 12pt ;
-fx-font-weight: bold ;
}
这是启动时的屏幕截图:
这是点击第一段中每个句子的第一个单词后的结果: