【问题标题】:How to find the end point of a paragraph (Label) in JavaFX?如何在 JavaFX 中找到段落(标签)的结束点?
【发布时间】:2019-07-06 18:25:43
【问题描述】:

简单的问题,希望有一个简单的解决方案。我的 JavaFX 应用程序中有一个 Label,我希望在其中一个按钮位于段落的末尾。在段落的末尾,我的意思是好像它是另一个角色。我无法将 X 和 Y 设置为特定值,因为段落的长度并不总是相同,所以这个按钮的位置并不总是相同。

下面,红色是我想要的按钮。有什么方法可以以编程方式找到这一点?

谢谢

【问题讨论】:

    标签: user-interface button javafx label fxml


    【解决方案1】:

    您可以使用辅助方法将长文本拆分为代表单行文本的 ListText 节点。然后,将您的Text 添加到FlowPane 后,只需在末尾添加Button

    看看以下演示的 MCVE:

    import javafx.application.Application;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.layout.FlowPane;
    import javafx.scene.layout.VBox;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.StringTokenizer;
    
    public class TextFlowSample extends Application {
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) {
    
            // Simple interface
            VBox root = new VBox(5);
            root.setPadding(new Insets(10));
            root.setAlignment(Pos.CENTER);
    
            String longText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc nibh sapien, commodo in libero ac, feugiat accumsan odio. Aliquam erat volutpat. Integer accumsan sapien at elit aliquet sagittis. Praesent fermentum nec nunc ultrices mollis. Nam in odio ullamcorper, eleifend quam quis, aliquam sem. Nullam feugiat ex nec elit rutrum blandit. Etiam ut mauris magna. Proin est nunc, viverra quis tempus sed, dictum in lacus.";
    
            // Create a FlowPane to hold our Text
            FlowPane flowPane = new FlowPane();
    
            // Now, our button
            Button button = new Button("Click This!");
    
            // Let's use our custom method to get a list of Text objects to add to the FlowPane
            // Here we can set our max length and determine if we'll allow words to be broken up
            flowPane.getChildren().addAll(getTextsFromString(longText, 75, false));
            flowPane.getChildren().add(button);
    
            root.getChildren().add(flowPane);
    
            // Show the Stage
            primaryStage.setWidth(425);
            primaryStage.setHeight(300);
            primaryStage.setScene(new Scene(root));
            primaryStage.show();
        }
    
        /**
         * Helper method to convert a long String into a List of Text objects
         */
        private List<Text> getTextsFromString(String string, int maxLineLength, boolean breakWords) {
    
            List<Text> textList = new ArrayList<>();
    
            // If we are breaking up words, just cut into rows up to the max length
            if (breakWords) {
                int index = 0;
                while (index < string.length()) {
                    textList.add(new Text(string.substring(index, Math.min(index + maxLineLength, string.length()))));
                    index += maxLineLength;
                }
            } else {
    
                // First, let's insert linebreaks into the String when max length is reached. The tokenizer here
                // allows us to split the string and keep the spaces, making it easy to loop through later.
                StringTokenizer tokenizer = new StringTokenizer(string, " ", true);
                StringBuilder sb = new StringBuilder();
    
                int currentLength = 0;
                while (tokenizer.hasMoreTokens()) {
                    String word = tokenizer.nextToken();
    
                    // If the next word would exceed our max length, add the new line character
                    if (currentLength + word.length() > maxLineLength) {
                        sb.append("\n");
                        currentLength = 0;
                    }
    
                    sb.append(word);
                    currentLength += word.length();
                }
    
                // Now we can split the string using the \n as a delimiter
                List<String> rows = Arrays.asList(sb.toString().split("\n"));
                for (String row : rows) {
                    textList.add(new Text(row));
                }
    
            }
    
            return textList;
    
        }
    }
    

    结果:

    【讨论】:

      【解决方案2】:

      我认为最简单的方法是创建自己的包装方法,根据可用宽度将段落字符串转换为文本(或标签)对象数组,然后将它们放在带有按钮的 FlowPane 中在末尾。我不相信您可以轻松地检索到标签的实际结束坐标,因为它是一个覆盖节点边界的矩形。

      在将多个 Text 对象连接在一起的意义上,类似于此问题中的解决方案:JavaFX: setting background color for Text controls

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-26
        • 2022-08-13
        • 1970-01-01
        • 1970-01-01
        • 2014-04-10
        • 1970-01-01
        相关资源
        最近更新 更多