The app displays an icon using ```Icon(imageFromRe...
# compose-desktop
v
The app displays an icon using
Copy code
Icon(imageFromResource("images/logo.png"))
But sometimes, when the system is under heavy load I have NullPointerException in DesktopImageAssetKt.loadResource() Apparently the icon doesn't have time to load... How to make waiting for the icon to load and then display it?
i
imageFromResource
shouldn't be used directly in
@Composable
function. Use
imageResource
instead (it loads resource only in the first call of
Composable
function) But
NullPointerException
looks strange. Loading and composition here is synchronous in a single thread, so theoretically everything should work. Also strange that
Icon
sometimes works.
Icon
shouldn't work with "png" images, it will show black rectangle instead of an image. For "png" images we should use
Image
👍 1
v
I check format of logo.png - this is PNG with size 32x31 pixels. And he is normally showed as Icon :)
I get it from old application ico-file and save in some Icon editor as PNG
I changed
imageFromResource
to
imageResource
and tried to repeat situation with
NullPointerException
, all works well...
After some compilations and test executions I receive again same error:
Exception in thread "AWT-EventQueue-0 @coroutine#1" java.lang.NullPointerException
at androidx.compose.ui.graphics.DesktopImageAssetKt.loadResource(DesktopImageAsset.kt:80)
i
Exception happened in this line?
Copy code
val resource = Thread.currentThread().contextClassLoader.getResource(path)
Maybe something overrides contextClassLoader in your application 🤔. Is it pure "Compose" application? Also it will be very helpful if you can provide a snippet with bug
v
I find coroutine launch in my composable. When coroutine is running Icon changes its tint. So maybe it breaks something. I move coroutine launch to outside of Composable and will be wait this bug again...
@Igor Demin So, after many runs, I got this error again. I have little experience in describing errors, and I do not know if I can repeat this error in a separate code... I'll try to give you as much information as possible here: bug.txt - message about bug HintContainer - container for all main window content and hints. Render of main window:
Copy code
@Composable
override fun render() {
    HintContainer {
        Scaffold(
            topBar = { infoBar.render() }
        ) {
            //...
infoBar render contains StatusIcon:
Copy code
@Composable
override fun render() {
    val connectionState = remember { databaseController.connectionStatus }.collectAsState()
    TopAppBar {
        val connectMessage = derivedStateOf {
            when (connectionState.value) {
                ConnectionStatus.INITIALIZED -> "Connecting to database"
                ConnectionStatus.SUCCESS -> "Connected to ${databaseController.connection}"
                else -> "Failed connection"
            }
        }
        val statusColor = derivedStateOf {
            if (connectionState.value == ConnectionStatus.SUCCESS) Color.Unspecified
            else AppTheme.colors.material.error
        }

        Row(modifier = Modifier.weight(1f)) {
            StatusIcon(
                message = connectMessage.value,
                color = statusColor.value,
                modifier = Modifier.align(Alignment.CenterVertically).padding(8.dp)
            )
            // .....
connectionStatus described in databaseController:
Copy code
private val _state = MutableStateFlow<ConnectionStatus>(ConnectionStatus.NOT_REQUESTED)
val connectionStatus: StateFlow<ConnectionStatus> get() = _state
_state.value changes in another coroutine I hope this information will be enough
Exception happened in this line?
val resource = Thread.currentThread().contextClassLoader.getResource(path)
Yes
i
Thanks! I will look at it
Unfortunately I can't reproduce the bug (everything seems fine). Can you try this function instead of `imageResource`:
Copy code
@Composable
fun imageResource2(path: String): ImageBitmap {
    return remember(path) { Image.makeFromEncoded(loadResource2(path)).asImageBitmap() }
}

private fun loadResource2(path: String): ByteArray {
    val resource = ClassLoader.getSystemClassLoader().getResource(path)
    requireNotNull(resource) { "Resource $path not found" }
    return resource.readBytes()
}
Also maybe on the latest version (0.2.0-build128) it will be working? We changed default coroutine dispatcher recently (https://github.com/JetBrains/compose-jb/issues/17)
v
I've been working on the latest version for the last two days and I didn't get this error...
i
I hope we fixed it 🙂