Как найти конечную точку абзаца (метки) в JavaFX? - PullRequest
0 голосов
/ 13 февраля 2019

Простой вопрос, надеюсь, есть простое решение.У меня есть Label в моем приложении JavaFX, в котором я хотел бы, чтобы кнопка была в конце абзаца.Под концом абзаца я подразумеваю, как будто это был другой персонаж.Я не могу установить X и Y на конкретные значения, потому что длина абзаца не всегда одинакова, поэтому место, где должна быть эта кнопка, не всегда одинаково.

Ниже, красный, где я быкак кнопка, чтобы быть.Любой способ программно найти эту точку?

enter image description here

Спасибо

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Вы можете использовать вспомогательный метод, чтобы разделить ваш длинный текст на узлы List из Text, которые представляют одну строку текста.Затем, после добавления вашего 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;

    }
}

Результат:

screenshot

0 голосов
/ 13 февраля 2019

Я думаю, что самый простой способ сделать это - создать собственный метод обтекания для преобразования строки абзаца в массив объектов Text (или Label) на основе доступной ширины и поместить их в FlowPane с помощью кнопки.в конце.Я не верю, что вы можете легко получить фактические конечные координаты метки, так как это прямоугольник, охватывающий границы узла.

Подобно решению в этом вопросе в смысле объединения нескольких текстовых объектов.: JavaFX: установка цвета фона для элементов управления Text

...