From bf457620dbc11dc4037bd1eba23c57f8b33261c1 Mon Sep 17 00:00:00 2001 From: David Cavaceci Date: Wed, 2 Oct 2024 11:30:06 -0500 Subject: [PATCH] Fix #1510: Handle spacing and links in content box messages. --- .../control/TitledDescriptionPane.java | 72 +++++++++++++++---- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/sparrowwallet/sparrow/control/TitledDescriptionPane.java b/src/main/java/com/sparrowwallet/sparrow/control/TitledDescriptionPane.java index 3f2f1262..118c567b 100644 --- a/src/main/java/com/sparrowwallet/sparrow/control/TitledDescriptionPane.java +++ b/src/main/java/com/sparrowwallet/sparrow/control/TitledDescriptionPane.java @@ -14,8 +14,8 @@ import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; -import java.util.Arrays; -import java.util.OptionalDouble; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class TitledDescriptionPane extends TitledPane { private Label mainLabel; @@ -127,25 +127,44 @@ public class TitledDescriptionPane extends TitledPane { } protected Node getContentBox(String message) { - Label details = new Label(message); - details.setWrapText(true); - - HBox contentBox = new HBox(); + // Create the VBox to hold text and Hyperlink components + VBox contentBox = new VBox(); contentBox.setAlignment(Pos.TOP_LEFT); - contentBox.getChildren().add(details); contentBox.setPadding(new Insets(10, 30, 10, 30)); + contentBox.setPrefWidth(400); // Set preferred width for wrapping - double width = TextUtils.computeTextWidth(details.getFont(), message, 0.0D); - double numLines = Math.max(1, Math.ceil(width / 400d)); + // Define the regex pattern to match URLs + String urlPattern = "(\\[https?://\\S+])"; + Pattern pattern = Pattern.compile(urlPattern); + Matcher matcher = pattern.matcher(message); - //Handle long words like txids - OptionalDouble maxWordLength = Arrays.stream(message.split(" ")).mapToDouble(word -> TextUtils.computeTextWidth(details.getFont(), message, 0.0D)).max(); - if(maxWordLength.isPresent() && maxWordLength.getAsDouble() > 300.0) { - numLines += 1.0; + // StringBuilder to track the non-URL text + int lastMatchEnd = 0; + + // Iterate through the matches and build the components + while (matcher.find()) { + // Add the text before the URL as a normal Label + if (matcher.start() > lastMatchEnd) { + String nonUrlText = message.substring(lastMatchEnd, matcher.start()); + Label textLabel = createWrappedLabel(nonUrlText); + contentBox.getChildren().add(textLabel); + } + + // Extract the URL and create a Hyperlink for it + String url = matcher.group(1).replaceAll("\\[", "").replaceAll("\\]", ""); + Hyperlink hyperlink = createHyperlink(url); + contentBox.getChildren().add(hyperlink); + + // Update last match end + lastMatchEnd = matcher.end(); } - double height = Math.max(60, numLines * 20); - contentBox.setPrefHeight(height); + // Add remaining text after the last URL (if any) + if (lastMatchEnd < message.length()) { + String remainingText = message.substring(lastMatchEnd); + Label remainingLabel = createWrappedLabel(remainingText); + contentBox.getChildren().add(remainingLabel); + } return contentBox; } @@ -178,4 +197,27 @@ public class TitledDescriptionPane extends TitledPane { return account; } + + // Helper method to create a wrapped Label with a specified maxWidth + private Label createWrappedLabel(String text) { + Label label = new Label(text); + label.setWrapText(true); + label.setMaxWidth(400); + return label; + } + + // Helper method to create a Hyperlink + private Hyperlink createHyperlink(String url) { + Hyperlink hyperlink = new Hyperlink(url); + hyperlink.setMaxWidth(400); // Set maximum width for wrapping + hyperlink.setWrapText(true); // Ensure text wrapping in the hyperlink + hyperlink.setOnAction(e -> { + try { + java.awt.Desktop.getDesktop().browse(new java.net.URI(url)); + } catch (Exception ex) { + // TODO: handle failure to launch link + } + }); + return hyperlink; + } }