在JavaFX组件中展开文本

在JavaFX组件中展开文本,java,javafx,Java,Javafx,我有一个字符串(大约一段长,包含换行符和unicode),我正在JavaFX组件中显示(现在是一个大标签,但更改特定的实现是一个选项),当用户单击一个单词时,我希望该单词被“扩展”(“单词”->“w o r d”) (事实上,这并不完全正确,我想将单词传递给更复杂的函数并使用结果,但函数是什么并不重要) 我可以生成html并使用它,但所有通过在html中单击文本来更改文本的方法似乎都需要javascript,我不知道java如何处理嵌入式js 我可以生成一组标签,每个单词一个,然后编写一个onC

我有一个字符串(大约一段长,包含换行符和unicode),我正在JavaFX组件中显示(现在是一个大标签,但更改特定的实现是一个选项),当用户单击一个单词时,我希望该单词被“扩展”(“单词”->“w o r d”)

(事实上,这并不完全正确,我想将单词传递给更复杂的函数并使用结果,但函数是什么并不重要)

我可以生成html并使用它,但所有通过在html中单击文本来更改文本的方法似乎都需要javascript,我不知道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 ;
}
以下是startup的屏幕截图:

这是在点击第一段中每个句子的第一个单词之后:


您是否尝试过将
文本
元素放入一个文档中?这样你就可以很容易地检测到单个文本对象上的输入事件。多亏了这一点,它工作得非常好,非常感谢!