下面列出了怎么用javafx.scene.text.TextFlow的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Selects the best {@link MatchResult} given a list of candidates and a query.
*
* <p>The results are useless unless you provide the {@link MatchSelector} that
* suits your use case (limiter).
*
* @param candidates List of stuff to sort
* @param matchExtractor Extracts the searchable text from an item
* @param limiter Selects the best candidates, may process them further to break ties
* @param query Text to search for
*/
public static <T> Stream<MatchResult<T>> filterResults(List<? extends T> candidates,
Function<? super T, String> matchExtractor,
String query,
MatchSelector<T> limiter) {
if (query.length() < MIN_QUERY_LENGTH) {
return Stream.empty();
}
Stream<MatchResult<T>> base = candidates.stream()
.map(it -> {
String cand = matchExtractor.apply(it);
return new MatchResult<>(0, it, cand, query, new TextFlow(makeNormalText(cand)));
});
return limiter.selectBest(base);
}
public void show()
{
final Hyperlink hyperlink = new Hyperlink("Google Cloud SDK");
hyperlink.setOnAction(e -> Paintera.getApplication().getHostServices().showDocument(googleCloudSdkLink));
final TextArea area = new TextArea(googleCloudAuthCmd);
area.setFont(Font.font("monospace"));
area.setEditable(false);
area.setMaxHeight(24);
final TextFlow textFlow = new TextFlow(
new Text("Please install "),
hyperlink,
new Text(" and then run this command to initialize the credentials:"),
new Text(System.lineSeparator() + System.lineSeparator()),
area);
final Alert alert = PainteraAlerts.alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Could not find Google Cloud credentials.");
alert.getDialogPane().contentProperty().set(textFlow);
alert.show();
}
protected Parent overlay(Args args) {
Color fill = getTextFill(args);
TextFlow topLeft = text(fill, getTopLeftText(args), LEFT);
TextFlow topCenter = text(fill, getTopCenterText(args), CENTER);
TextFlow topRight = text(fill, getTopRightText(args), RIGHT);
TextFlow bottomLeft = text(fill, getBottomLeftText(args), LEFT);
TextFlow bottomCenter = text(fill, getBottomCenterText(args), CENTER);
TextFlow bottomRight = text(fill, getBottomRightText(args), RIGHT);
StackPane top = new StackPane(topLeft, topCenter, topRight);
StackPane bottom = new StackPane(bottomLeft, bottomCenter, bottomRight);
BorderPane.setMargin(top, new Insets(20));
BorderPane.setMargin(bottom, new Insets(20));
BorderPane layout = new BorderPane();
layout.setBackground(EMPTY);
layout.setTop(top);
layout.setBottom(bottom);
return layout;
}
public PrefixPane(String ownerModule, UserContext userContext) {
this.ownerModule = defaultString(ownerModule);
this.field = new PrefixField(userContext.getDefaultPrefix(this.ownerModule));
getStyleClass().addAll(Style.CONTAINER.css());
getStyleClass().addAll(Style.HCONTAINER.css());
I18nContext ctx = DefaultI18nContext.getInstance();
getChildren().addAll(new Label(DefaultI18nContext.getInstance().i18n("Generated PDF documents name prefix:")),
field,
helpIcon(new TextFlow(
new Text(ctx.i18n("Prefix for the output files name.") + System.lineSeparator()),
new Text(ctx.i18n("Some special keywords are replaced with runtime values.")
+ System.lineSeparator()),
new Text(ctx.i18n("Right click to add these keywords.")))));
eventStudio().add(TaskExecutionRequestEvent.class, e -> {
if (ownerModule.equals(e.getModuleId())) {
userContext.setDefaultPrefix(this.ownerModule, field.getText());
}
});
}
private void setContent() {
TextFlow flow = new TextFlow(new Text(Util.text("login-intro")), link);
flow.setTextAlignment(TextAlignment.CENTER);
addElement(flow);
addElement(loginText);
addElement(passwordText);
addElement(loginButton);
addElement(loginStatus);
if (!Settings.getSetting("user").isEmpty()) {
loginText.setText(Settings.getSetting("user"));
Platform.runLater(() -> {
passwordText.requestFocus();
});
}
}
protected TextFlow buildThreadListGraphic(final TableCell<ThreadElement, Set<ThreadElement>> cell, final Set<ThreadElement> threads) {
final TextFlow threadsGraphic = new TextFlow();
threadsGraphic.setPrefHeight(20);
final Iterator<ThreadElement> threadIterator = threads.iterator();
while (threadIterator.hasNext()) {
final ThreadElement thread = threadIterator.next();
threadsGraphic.getChildren().add(buildThreadLink(cell, thread));
if (threadIterator.hasNext()) {
threadsGraphic.getChildren().add(buildThreadSeparator());
}
}
return threadsGraphic;
}
@Override
public void updateItem(TemplateInfo item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setGraphic(null);
setText(null);
} else {
Text t = IconBuilder.create(IconFontGlyph.valueOf(item.icon), 18.0).build();
t.setFill(Color.WHITE);
TextFlow tf = new TextFlow(t);
tf.setTextAlignment(TextAlignment.CENTER);
tf.setPadding(new Insets(5, 5, 5, 5));
tf.setStyle("-fx-background-color: #505050; -fx-background-radius: 5px;");
tf.setPrefWidth(30.0);
setGraphic(tf);
setText(item.name);
}
}
@Override
public void updateItem(TopicInfo item, boolean empty) {
super.updateItem(item, empty);
if (item == null) {
setGraphic(null);
setText(null);
} else {
Text t = IconBuilder.create(item.getFactory().getGlyph(), 18.0).build();
t.setFill(Color.WHITE);
TextFlow tf = new TextFlow(t);
tf.setTextAlignment(TextAlignment.CENTER);
tf.setPadding(new Insets(5, 5, 5, 5));
tf.setStyle("-fx-background-color: #505050; -fx-background-radius: 5px;");
tf.setPrefWidth(30.0);
setGraphic(tf);
String label = item.getLabel().getValue();
setText(item.getFactory().getTypeName() + ((label == null || label.isEmpty()) ? "" : " : " + label));
}
}
@Override
protected void drawStepContent() {
final String title = this.getParentWizardTitle();
VBox contentPane = new VBox();
contentPane.setId("presentationBackground");
Label titleWidget = new Label(title + "\n\n");
titleWidget.setId("presentationTextTitle");
Text textWidget = new Text(textToShow);
textWidget.setId("presentationText");
TextFlow flow = new TextFlow();
flow.getChildren().add(textWidget);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setId("presentationScrollPane");
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scrollPane.setFitToWidth(true);
scrollPane.setContent(flow);
VBox.setVgrow(scrollPane, Priority.ALWAYS);
contentPane.getChildren().add(scrollPane);
getParent().getRoot().setCenter(contentPane);
}
/**
* creates an empty paragraph
*
* @param richtext true if richtext
* @param editable true if editable
* @param parent the parent richtextarea
*/
public Paragraph(boolean richtext, boolean editable, RichTextArea parent) {
this.richtext = richtext;
this.editable = editable;
this.bulletpoint = false;
this.title = false;
this.textflow = new TextFlow();
textflow.setLineSpacing(1);
textlist = new ArrayList<FormattedText>();
this.parent = parent;
if (editable)
createFlowWriteListener();
createSelectionListener();
}
TextFlow styledPresentableText(Node node) {
DesignerBindings bindings = languageBindingsProperty().getOrElse(DefaultDesignerBindings.getInstance());
Attribute attr = bindings.getMainAttribute(node);
TextFlow flow = new TextFlow(makeStyledText(node.getXPathNodeName(), NODE_XPATH_NAME_CSS));
if (attr != null && attr.getStringValue() != null) {
flow.getChildren().add(makeStyledText(" [", NODE_XPATH_PUNCT_CSS));
flow.getChildren().add(makeStyledText("@" + attr.getName(), NODE_XPATH_MAIN_ATTR_NAME_CSS));
flow.getChildren().add(makeStyledText(" = ", NODE_XPATH_PUNCT_CSS));
flow.getChildren().add(makeStyledText(attrToXpathString(attr), NODE_XPATH_MAIN_ATTR_VALUE_CSS));
flow.getChildren().add(makeStyledText("]", NODE_XPATH_PUNCT_CSS));
}
return flow;
}
private static TextFlow richTextForNode(TextAwareNodeWrapper node) {
StyledDocument<Collection<String>, String, Collection<String>> richText = node.getNodeRichText();
TextFlow result = new TextFlow();
int lastSpanEnd = 0;
for (StyleSpan<Collection<String>> span : richText.getStyleSpans(0, richText.length())) {
String spanText = richText.getText(lastSpanEnd, lastSpanEnd + span.getLength());
int truncateTo = spanText.indexOf("\n");
Text text = new Text(truncateTo < 0 ? spanText : spanText.substring(0, truncateTo));
text.getStyleClass().addAll(span.getStyle());
result.getChildren().add(text);
lastSpanEnd += text.getText().length();
if (truncateTo > 0) {
break;
}
}
// we truncated
if (lastSpanEnd < richText.length()) {
result.getChildren().add(new Text("..."));
}
return result;
}
public MatchResult(int score, T data, String suggestion, String query, TextFlow textFlow) {
this.score = score;
this.data = data;
this.suggestion = suggestion;
this.textFlow = textFlow;
this.query = query;
}
@Override protected void initGraphics() {
super.initGraphics();
titleText = new Text();
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
text = new Text(tile.getText());
text.setFill(tile.getUnitColor());
Helper.enableNode(text, tile.isTextVisible());
LocalTime duration = tile.getDuration();
leftText = new Text(Integer.toString(duration.getHour() > 0 ? duration.getHour() : duration.getMinute()));
leftText.setFill(tile.getValueColor());
leftUnit = new Text(duration.getHour() > 0 ? "h" : "m");
leftUnit.setFill(tile.getValueColor());
rightText = new Text(Integer.toString(duration.getHour() > 0 ? duration.getMinute() : duration.getSecond()));
rightText.setFill(tile.getValueColor());
rightUnit = new Text(duration.getHour() > 0 ? "m" : "s");
rightUnit.setFill(tile.getValueColor());
timeText = new TextFlow(leftText, leftUnit, rightText, rightUnit);
timeText.setTextAlignment(TextAlignment.RIGHT);
timeText.setPrefWidth(PREFERRED_WIDTH * 0.9);
description = new Label(tile.getDescription());
description.setAlignment(Pos.TOP_RIGHT);
description.setWrapText(true);
description.setTextFill(tile.getTextColor());
Helper.enableNode(description, !tile.getDescription().isEmpty());
getPane().getChildren().addAll(titleText, text, timeText, description);
}
@Override protected void initGraphics() {
super.initGraphics();
titleText = new Text();
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
text = new Text(tile.getText());
text.setFill(tile.getUnitColor());
Helper.enableNode(text, tile.isTextVisible());
valueText = new Text(String.format(locale, formatString, ((tile.getValue() - minValue) / range * 100)));
valueText.setFill(tile.getValueColor());
valueText.setTextOrigin(VPos.BASELINE);
Helper.enableNode(valueText, tile.isValueVisible());
unitText = new Text(" " + tile.getUnit());
unitText.setFill(tile.getUnitColor());
unitText.setTextOrigin(VPos.BASELINE);
Helper.enableNode(unitText, !tile.getUnit().isEmpty());
valueUnitFlow = new TextFlow(valueText, unitText);
valueUnitFlow.setTextAlignment(TextAlignment.RIGHT);
description = new Label(tile.getText());
description.setAlignment(tile.getDescriptionAlignment());
description.setWrapText(true);
description.setTextFill(tile.getTextColor());
Helper.enableNode(description, tile.isTextVisible());
getPane().getChildren().addAll(titleText, text, valueUnitFlow, description);
}
@Override
protected void seriesAdded(Series<X, Y> series, int seriesIndex) {
super.seriesAdded(series, seriesIndex);
if (labelType == null || labelType == LabelType.NotDisplay || labelType == LabelType.Pop) {
return;
}
try {
for (int j = 0; j < series.getData().size(); j++) {
Data<X, Y> item = series.getData().get(j);
String name = item.getYValue() + "";
String value = item.getXValue() + "";
String labelValue = StringTools.format(FxmlControl.realValue(chartCoordinate, Double.valueOf(value)));
String label;
switch (labelType) {
case Name:
label = name;
break;
case Value:
label = labelValue;
break;
case NameAndValue:
default:
label = name + " " + labelValue;
break;
}
Text text = new Text(label);
text.setStyle("-fx-font-size: " + textSize + "px; -fx-text-fill: black;");
TextFlow textFlow = new TextFlow(text);
textFlow.setTextAlignment(TextAlignment.CENTER);
nodeMap.put(item.getNode(), textFlow);
this.getPlotChildren().add(textFlow);
}
} catch (Exception e) {
logger.debug(e.toString());
}
}
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
if (labelType == null || labelType == LabelType.NotDisplay || labelType == LabelType.Pop) {
return;
}
for (Node bar : nodeMap.keySet()) {
TextFlow textFlow = nodeMap.get(bar);
textFlow.relocate(bar.getBoundsInParent().getMaxX() + 10, bar.getBoundsInParent().getMinY());
}
}
@Override
protected void seriesAdded(Series<X, Y> series, int seriesIndex) {
super.seriesAdded(series, seriesIndex);
if (labelType == null || labelType == LabelType.NotDisplay || labelType == LabelType.Pop) {
return;
}
try {
for (int j = 0; j < series.getData().size(); j++) {
Data<X, Y> item = series.getData().get(j);
String name = item.getXValue() + "";
String value = item.getYValue() + "";
String label;
String labelValue = StringTools.format(FxmlControl.realValue(chartCoordinate, Double.valueOf(value)));
switch (labelType) {
case Name:
label = name;
break;
case Value:
label = labelValue;
break;
case NameAndValue:
default:
label = name + " " + labelValue;
break;
}
Text text = new Text(label);
text.setStyle("-fx-font-size: " + textSize + "px; -fx-text-fill: black;");
TextFlow textFlow = new TextFlow(text);
textFlow.setTextAlignment(TextAlignment.CENTER);
nodeMap.put(item.getNode(), textFlow);
this.getPlotChildren().add(textFlow);
}
} catch (Exception e) {
logger.debug(e.toString());
}
}
/**
* @param index The index of the desired paragraph box
* @return A list of text nodes which render the text in the ParagraphBox
* specified by the given index.
*/
protected List<Text> getTextNodes(int index) {
TextFlow tf = getParagraphText(index);
List<Text> result = new ArrayList<>();
tf.getChildrenUnmodifiable().filtered(n -> n instanceof Text).forEach(n -> result.add((Text) n));
return result;
}
/**
* Creates a new instance of a code editor
* @param armSimulator the simulator
*/
public CodeEditor(ArmSimulator armSimulator) {
mainPane = new AnchorPane();
this.armSimulator = armSimulator;
this.textArea = new TextArea();
this.textFlow = new TextFlow();
this.scrollPane = new ScrollPane(this.textFlow);
visibleNodes = FXCollections.observableArrayList();
dockNode = new DockNode(mainPane, "Editor");
dockNode.setPrefSize(300, 100);
dockNode.setClosable(false);
AnchorPane.setBottomAnchor(this.textArea, 0D);
AnchorPane.setLeftAnchor(this.textArea, 0D);
AnchorPane.setRightAnchor(this.textArea, 0D);
AnchorPane.setTopAnchor(this.textArea, 0D);
this.mainPane.setMinSize(300, 300);
AnchorPane.setBottomAnchor(this.scrollPane, 0D);
AnchorPane.setLeftAnchor(this.scrollPane, 0D);
AnchorPane.setRightAnchor(this.scrollPane, 0D);
AnchorPane.setTopAnchor(this.scrollPane, 0D);
this.mainPane.getChildren().addAll(this.scrollPane, this.textFlow, this.textArea);
this.dockNode.getStylesheets().add("/resources/style.css");
mainPane.setMaxHeight(Double.MAX_VALUE);
mainPane.setMaxWidth(Double.MAX_VALUE);
scrollPane.vvalueProperty().addListener((obs) -> {
checkVisible(scrollPane);
});
scrollPane.hvalueProperty().addListener((obs) -> {
checkVisible(scrollPane);
});
}
/** @param field Field where user entered text
* @param text Text entered by user
* @param proposal Matching proposal
* @return AutocompleteItem that will apply the proposal
*/
private AutocompleteItem createItem(final TextInputControl field,
final String text, final Proposal proposal)
{
final TextFlow markup = new TextFlow();
for (MatchSegment seg: proposal.getMatch(text))
{
final Label match = new Label(seg.getDescription());
switch (seg.getType())
{
case MATCH:
match.setTextFill(Color.BLUE);
match.setFont(highlight_font);
break;
case COMMENT:
match.setTextFill(Color.GRAY);
match.setFont(highlight_font);
break;
case NORMAL:
default:
}
markup.getChildren().add(match);
}
return new AutocompleteItem(markup, () ->
{
final String value = proposal.apply(text);
field.setText(value);
field.positionCaret(value.length());
invokeAction(field);
});
}
SplitOptionsPane() {
super(Style.DEFAULT_SPACING);
getStyleClass().addAll(Style.CONTAINER.css());
I18nContext ctx = DefaultI18nContext.getInstance();
levelCombo.setId("bookmarksLevel");
regexpField.setId("bookmarksRegexp");
regexpField.setPromptText(ctx.i18n("Regular expression the bookmark has to match"));
regexpField.setPrefWidth(350);
getChildren().addAll(createLine(new Label(ctx.i18n("Split at this bookmark level:")), levelCombo),
createLine(new Label(ctx.i18n("Matching regular expression:")), regexpField, helpIcon(new TextFlow(
new Text(ctx.i18n("A regular expression the bookmark text has to match")
+ System.lineSeparator()),
new Text(ctx.i18n(
"Example: use .*Chapter.* to match bookmarks containing the word \"Chapter\""))))));
}
@Override protected void initGraphics() {
super.initGraphics();
titleText = new Text();
titleText.setFill(tile.getTitleColor());
Helper.enableNode(titleText, !tile.getTitle().isEmpty());
text = new Text(tile.getText());
text.setFill(tile.getUnitColor());
Helper.enableNode(text, tile.isTextVisible());
LocalTime duration = tile.getDuration();
leftText = new Text(Integer.toString(duration.getHour() > 0 ? duration.getHour() : duration.getMinute()));
leftText.setFill(tile.getValueColor());
leftUnit = new Text(duration.getHour() > 0 ? "h" : "m");
leftUnit.setFill(tile.getValueColor());
rightText = new Text(Integer.toString(duration.getHour() > 0 ? duration.getMinute() : duration.getSecond()));
rightText.setFill(tile.getValueColor());
rightUnit = new Text(duration.getHour() > 0 ? "m" : "s");
rightUnit.setFill(tile.getValueColor());
timeText = new TextFlow(leftText, leftUnit, rightText, rightUnit);
timeText.setTextAlignment(TextAlignment.RIGHT);
timeText.setPrefWidth(PREFERRED_WIDTH * 0.9);
description = new Label(tile.getDescription());
description.setAlignment(Pos.TOP_RIGHT);
description.setWrapText(true);
description.setTextFill(tile.getDescriptionColor());
Helper.enableNode(description, !tile.getDescription().isEmpty());
getPane().getChildren().addAll(titleText, text, timeText, description);
}
/**
* @param index The index of the desired paragraph box
* @return The ParagraphText (protected subclass of TextFlow) for the paragraph at the specified index
*/
protected TextFlow getParagraphText(int index) {
// get the ParagraphBox (protected subclass of Region)
Region paragraphBox = getParagraphBox(index);
// get the ParagraphText (protected subclass of TextFlow)
return (TextFlow) paragraphBox.getChildrenUnmodifiable().stream()
.filter(n -> n instanceof TextFlow)
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("No TextFlow node found in area at index: " + index));
}
private GridPane setContent() {
this.getStylesheets().add(css);
this.setAlignment(Pos.CENTER);
this.setHgap(20);
this.setVgap(5);
this.getStyleClass().add("background");
this.getColumnConstraints().add(Util.newColumn(400, "px"));
this.addRow(0, new WikiLabel("pattypan").setClass("title"));
this.addRow(1, new WikiLabel("v. " + Settings.VERSION));
if (!Session.WIKI.getDomain().equals("commons.wikimedia.org")) {
this.addRow(3, new WikiLabel(Session.WIKI.getDomain()));
}
this.addRow(20, new HBox(20,
new WikiButton("start-generate-button", "primary")
.setWidth(300)
.linkTo("ChooseDirectoryPane", stage),
new WikiButton("start-validate-button")
.setWidth(300)
.linkTo("LoadPane", stage)));
this.addRow(22, new HBox(20,
new WikiLabel("start-generate-description").setWidth(300),
new WikiLabel("start-validate-description").setWidth(300)));
String year = new SimpleDateFormat("yyyy").format(new Date());
this.addRow(40, new WikiLabel(year + " // Pawel Marynowski").setClass("muted"));
TextFlow flow = new TextFlow(
new Text(Util.text("start-bug-found")), bugLink,
new Text(" • "), logFile);
flow.setTextAlignment(TextAlignment.CENTER);
this.addRow(41, flow);
return this;
}
@Override
public TableCell<ThreadElement, Set<ThreadElement>> call(TableColumn<ThreadElement, Set<ThreadElement>> param) {
final TableCell<ThreadElement, Set<ThreadElement>> cell = new TableCell<ThreadElement, Set<ThreadElement>>() {
@Override
protected void updateItem(Set<ThreadElement> item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !item.isEmpty() && !empty) {
final TextFlow threadList = buildThreadListGraphic(this, item);
if (this.prefHeightProperty().isBound()) {
this.prefHeightProperty().unbind();
}
this.prefHeightProperty().bind(threadList.heightProperty());
threadList.prefWidthProperty().bind(this.widthProperty().subtract(-5));
this.setGraphic(threadList);
this.layout();
} else {
this.setGraphic(null);
}
}
};
return cell;
}
public StyledTextArea(@NamedArg("initialParagraphStyle") PS initialParagraphStyle,
@NamedArg("applyParagraphStyle") BiConsumer<TextFlow, PS> applyParagraphStyle,
@NamedArg("initialTextStyle") S initialTextStyle,
@NamedArg("applyStyle") BiConsumer<? super TextExt, S> applyStyle,
@NamedArg("document") EditableStyledDocument<PS, String, S> document) {
this(initialParagraphStyle, applyParagraphStyle,
initialTextStyle, applyStyle, document, true);
}
public StyledTextArea(@NamedArg("initialParagraphStyle") PS initialParagraphStyle,
@NamedArg("applyParagraphStyle") BiConsumer<TextFlow, PS> applyParagraphStyle,
@NamedArg("initialTextStyle") S initialTextStyle,
@NamedArg("applyStyle") BiConsumer<? super TextExt, S> applyStyle,
@NamedArg("preserveStyle") boolean preserveStyle) {
this(
initialParagraphStyle,
applyParagraphStyle,
initialTextStyle,
applyStyle,
new SimpleEditableStyledDocument<>(initialParagraphStyle, initialTextStyle),
preserveStyle);
}
public CHitInfo getHit(TextFlow t, double x, double y)
{
HitInfo h = getHitInfo(t, x, y);
int ix = h.getCharIndex();
boolean leading = h.isLeading();
return new CHitInfo(ix, leading);
}
public DemoHPane()
{
super(DemoGenerator.HPANE);
setTitle("DemoHPane.java");
String info = "HPane is a horizontal Pane with a single row layout similar to CPane.";
infoField = new TextFlow(new Text(info));
p = new CPane();
p.setGaps(10, 7);
p.setPadding(10);
p.addColumns
(
CPane.FILL
);
p.addRows
(
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF,
CPane.PREF
);
int r = 0;
p.add(0, r++, infoField);
p.add(0, r++, p(HPane.FILL));
// p.add(0, r++, p(1.0));
// p.add(0, r++, p(0.1, HPane.FILL, HPane.FILL, 0.1));
p.add(0, r++, p(0.1, HPane.FILL));
// p.add(0, r++, p(HPane.FILL, HPane.FILL));
// p.add(0, r++, p(HPane.PREF, HPane.PREF, HPane.PREF));
setContent(p);
}