5

How to open a link in the browser if I click on a button. I am using Compose for Desktop for it.

Button(onClick = {
    // What I have to write here..
}) {
    Text(
        text = "Open a link",
        color = Color.Black
    )
}

Thanks in advance.

Avijit Karmakar
  • 8,890
  • 6
  • 44
  • 59

3 Answers3

5

Use the Desktop#browse(URI) method. It opens a URI in the user's default browser.

public static boolean openWebpage(URI uri) {
    Desktop desktop = Desktop.isDesktopSupported() ? Desktop.getDesktop() : null;
    if (desktop != null && desktop.isSupported(Desktop.Action.BROWSE)) {
        try {
            desktop.browse(uri);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return false;
}

public static boolean openWebpage(URL url) {
    try {
        return openWebpage(url.toURI());
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    return false;
}
JIm
  • 236
  • 1
  • 2
  • This is about kotlin, so why do you paste Java code? – xdevs23 May 22 '22 at 22:03
  • @xdevs23 one of the following reasons maybe: - this can be a good reference for anyone who gets to this question - desktop compose runs on the JVM - it's easy to translate to kotlin, IntelliJ will even do that if you paste this in kotlin code – Aguragorn Jul 16 '22 at 07:24
  • 1
    While that's true, it still does not directly answer the question as the question is only about Kotlin. – xdevs23 Jul 16 '22 at 11:42
5

Inspired by https://stackoverflow.com/a/54869038/1575096 to also work on Linux and Mac:

fun openInBrowser(uri: URI) {
    val osName by lazy(LazyThreadSafetyMode.NONE) { System.getProperty("os.name").lowercase(Locale.getDefault()) }
    val desktop = Desktop.getDesktop()
    when {
        Desktop.isDesktopSupported() && desktop.isSupported(Desktop.Action.BROWSE) -> desktop.browse(uri)
        "mac" in osName -> Runtime.getRuntime().exec("open $uri")
        "nix" in osName || "nux" in osName -> Runtime.getRuntime().exec("xdg-open $uri")
        else -> throw RuntimeException("cannot open $uri")
    }
}

Button(onClick = { openInBrowser(URI("https://domain.tld/page")) }) {
    Text(
        text = "Open a link",
        color = Color.Black
    )
}
Schleichardt
  • 7,502
  • 1
  • 27
  • 37
  • Hey, I am an android developer for the last two years. recently I have explored compose for desktop. but I didn't get any resources for this tech. I am 0 in desktop app development where I should start learning desktop app development with compose. i know nothing about desktop app development. please suggest to me what should I learn about this. I am developing an app in kotlin. – Gulab Sagevadiya Aug 25 '21 at 03:33
  • Call to `lowercase()` in this answer uses the wrong locale. Should be `Locale.ROOT` for consistent behaviour, which is actually the default if you don't provide it. – Hakanai Apr 05 '22 at 04:57
  • I would suggest to put the `openInBrowser` call in a coroutine running under the `IO` dispatcher. That is, get the current GUI scope and call `scope.launch(Dispatchers.IO) { openInBrowser... }` inside the `onClick` lambda. You never know... – rwst Aug 28 '23 at 14:50
1

Minimal example

  1. put the function code in the commonMain module
expect fun browseUrl(url: String)
  1. place the function code in the desktopMain module
actual fun browseUrl(url: String) {
    val desktop = Desktop.getDesktop()
    desktop.browse(URI.create(url)) 
}
  1. use
onClick = {
    browseUrl("http://${link}")
}
QiXi
  • 59
  • 5