Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call system Explorer/Finder to select files in Compose #176

Closed
ggoraa opened this issue Dec 7, 2020 · 15 comments
Closed

Call system Explorer/Finder to select files in Compose #176

ggoraa opened this issue Dec 7, 2020 · 15 comments
Labels
question Not a bug, but question or comment

Comments

@ggoraa
Copy link

ggoraa commented Dec 7, 2020

How does that achievable?

@igordmn
Copy link
Collaborator

igordmn commented Dec 7, 2020

We can use java.awt.FileDialog:

import androidx.compose.desktop.LocalAppWindow
import androidx.compose.desktop.Window
import androidx.compose.material.Button
import androidx.compose.material.Text
fun main() = Window {
    val window = LocalAppWindow.current!!
    Button(onClick = {
        java.awt.FileDialog(window.window).isVisible = true
    }) {
        Text("Button")
    }
}

@olonho olonho added the question Not a bug, but question or comment label Dec 8, 2020
@olonho olonho closed this as completed Dec 8, 2020
@ggoraa
Copy link
Author

ggoraa commented Dec 8, 2020

Thanks!

@pnogas
Copy link

pnogas commented Feb 26, 2021

Figured I would post what I did to have file open files using the menu bar / keyboard shortcuts in case anyone else arrived here looking to do the same thing

AppManager.setMenu(
    MenuBar(
        Menu(
            name = "File",
                MenuItem(
                    name = "Open",
                    shortcut = KeyStroke(Key.O),
                    onClick = { windowActionManager.handleAction(MenuBarActions.OpenFile) }, // ...more stuff

and that eventually leads to

fun openLogFile() {
    var result: File?
        JFileChooser(System.getProperty("user.home")).apply {
            showOpenDialog(null)
            result = selectedFile
        } // ...more stuff

@v79
Copy link

v79 commented Apr 2, 2021

import androidx.compose.desktop.AppWindowAmbient

No longer seems to be available; this is what worked for me:

Button(onClick = {
	java.awt.FileDialog(AppManager.focusedWindow!!.window).isVisible = true
}) {
	Text("File Picker")
}

@igordmn
Copy link
Collaborator

igordmn commented Apr 2, 2021

import androidx.compose.desktop.AppWindowAmbient

No longer seems to be available; this is what worked for me:

Button(onClick = {
	java.awt.FileDialog(AppManager.focusedWindow!!.window).isVisible = true
}) {
	Text("File Picker")
}

It was renamed to LocalAppWindow (I changed my comment).

Better to use it instead of focusedWindow. focusedWindow works, but probably not in all cases (we can "click" without taking the window into focus, for example in tests)

@jposes22
Copy link

Updated:

Button(onClick = {
    java.awt.FileDialog(ComposeWindow()).isVisible = true
}) {
    Text("File Picker")
}

@sebkur
Copy link
Contributor

sebkur commented Jan 10, 2022

Updated:

Button(onClick = {
    java.awt.FileDialog(ComposeWindow()).isVisible = true
}) {
    Text("File Picker")
}

If I'm not mistaken, ComposeWindow() doesn't give you the current window, instead it just creates a new one.

@igordmn it seems LocalAppWindow isn't available any longer? Do you have a different solution?

@igordmn
Copy link
Collaborator

igordmn commented Jan 10, 2022

We should pass the parent window instead of the new Window (so the parent window will be blocked while dialog is opened). In 1.0 we can do that this way:

fun FrameWindowScope.openFileDialog() {
    java.awt.FileDialog(window).isVisible = true
}

FrameWindowScope is the scope provided by Window or singleWindowApplicaion, so you can use openFileDialog only inside them, or passing down FrameWindowScope or ComposeWindow via parameter/receiver/CompositionLocal manually.

There is also Composable way to open a file dialog.

@sebkur
Copy link
Contributor

sebkur commented Jan 10, 2022

awesome, thanks for the quick reply!

A small detail I noticed is, you need to actually use FrameWindowScope instead of WindowScope, as the former provides the more specific javax.swing.JFrame while the latter provides java.awt.Window as the window. It matters because FileDialog requires a java.awt.Frame (or Dialog) in its constructor of which JFrame is a subclass but Window isn't.

Anyway, also thanks for the pointer to the Composable way, that's sounds like it is the way one really wants to integrate this.

@igordmn
Copy link
Collaborator

igordmn commented Jan 10, 2022

use FrameWindowScope instead of WindowScope

Good point, thanks. I changed the comment.

@code-byte-labs
Copy link

Updated:

Button(onClick = {
    java.awt.FileDialog(ComposeWindow()).isVisible = true
}) {
    Text("File Picker")
}

I can't select a dir in this way

@sebkur
Copy link
Contributor

sebkur commented Jan 24, 2022

wow, indeed, looks like FileDialog doesn't support picking directories (at least not on all operating systems). Probably a disappointing workaround, but you could use JFileChooser:

    val f = JFileChooser()
    f.fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
    f.showSaveDialog(null)

@sebkur
Copy link
Contributor

sebkur commented Jan 24, 2022

probably worth a separate issue

@mahozad
Copy link
Contributor

mahozad commented Aug 27, 2022

To get a native look and feel (tested on Windows) I called this at the start of the program:

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())

To open directories only, created and showed a dialog like this:

val fileChooser = JFileChooser("/").apply {
    fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
    dialogTitle = "Select a folder"
    approveButtonText = "Select"
    approveButtonToolTipText = "Select current directory as save destination"
}
fileChooser.showOpenDialog(window.window /* OR null */)
val result = fileChooser.selectedFile

@okushnikov
Copy link
Collaborator

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Not a bug, but question or comment
Projects
None yet
Development

No branches or pull requests

10 participants