SWT: Integrate clickable link into StyledText
Asked Answered
D

1

1

With the help of this question I was able to figure out how I can display a link inside a StyledText widget in SwT. The color is correct and even the cursor changes shape when hovering over the link.

So far so good, but the link is not actually clickable. Although the cursor changes its shape, nothing happens if clicking on the link. Therefore I am asking how I can make clicking the link to actually open it in the browser.

I thought of using a MouseListener, tracking the click-location back to the respective text the click has been performed on and then deciding whether to open the link or not. However that seems way too complicated given that there already is some routine going on for changing the cursor accordingly. I believe that there is some easy way to do this (and assuring that the clicking-behavior is actually consistent to when the cursor changes its shape).

Does anyone have any suggestions?

Here's an MWE demonstrating what I have done so far:

public static void main(String[] args) throws MalformedURLException {
final URL testURL = new URL("https://mcmap.net/q/1486094/-can-html-style-links-be-added-to-swt-styledtext");

Display display = new Display();

Shell shell = new Shell(display);
shell.setLayout(new GridLayout(1, true));

StyledText sTextWidget = new StyledText(shell, SWT.READ_ONLY);

final String firstPart = "Some text before ";
String msg = firstPart + testURL.toString() + " some text after";

sTextWidget.setText(msg);
sTextWidget.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

StyleRange linkStyleRange = new StyleRange(firstPart.length(), testURL.toString().length(), null, null);
linkStyleRange.underline = true;
linkStyleRange.underlineStyle = SWT.UNDERLINE_LINK;
linkStyleRange.data = testURL.toString();

sTextWidget.setStyleRange(linkStyleRange);

shell.open();

while(!shell.isDisposed()) {
    display.readAndDispatch();
}
}
Deberadeberry answered 7/8, 2018 at 20:25 Comment(0)
D
1

Okay I was being a little too fast on posting this question... There's a snippet that deals with exactly this problem and it shows, that one indeed has to use an extra MouseListener in order to get things working.

The snippet can be found here and this is the relevant part setting up the listener:

styledText.addListener(SWT.MouseDown, event -> {
    // It is up to the application to determine when and how a link should be activated.
    // In this snippet links are activated on mouse down when the control key is held down
    if ((event.stateMask & SWT.MOD1) != 0) {
        int offset = styledText.getOffsetAtLocation(new Point (event.x, event.y));
        if (offset != -1) {
            StyleRange style1 = null;
            try {
                style1 = styledText.getStyleRangeAtOffset(offset);
            } catch (IllegalArgumentException e) {
                // no character under event.x, event.y
            }
            if (style1 != null && style1.underline && style1.underlineStyle == SWT.UNDERLINE_LINK) {
                System.out.println("Click on a Link");
            }
        }
    }
});
Deberadeberry answered 7/8, 2018 at 20:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.