
org.fernice.reflare.cache.ImageCache.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fernice-reflare Show documentation
Show all versions of fernice-reflare Show documentation
CSS integration through fernice-flare in Java Swing as a LookAndFeel
The newest version!
package org.fernice.reflare.cache
import org.fernice.flare.url.Url
import org.fernice.reflare.internal.ImageHelper
import org.fernice.reflare.util.concurrentMap
import java.awt.Image
import java.lang.RuntimeException
import java.net.URL
import java.security.AccessController
import java.security.PrivilegedAction
import java.util.concurrent.CompletableFuture
import java.util.concurrent.Executor
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import java.util.function.Supplier
import javax.imageio.ImageIO
object ImageCache {
private val cachedImages = concurrentMap>()
private val threadCount = AtomicInteger()
private val unboundExecutor = Executor { runnable ->
val thread = Thread(runnable, "fernice-image-loader-${threadCount.getAndIncrement()}")
thread.isDaemon = true
thread.start()
}
private val boundExecutor = ThreadPoolExecutor(0, 8, 50, TimeUnit.MILLISECONDS, LinkedBlockingQueue()) { runnable ->
val thread = Thread(runnable, "fernice-shared-image-loader-${threadCount.getAndIncrement()}")
thread.isDaemon = true
thread
}
fun fetch(url: Url, callback: (() -> Unit)? = null): CompletableFuture {
val future = cachedImages.computeIfAbsent(url) {
execute(shareExecutor = callback != null) {
if (url.value.startsWith("/")) {
ImageHelper.getMultiResolutionImageResource(url.value)
} else {
ImageIO.read(URL(url.value)) ?: throw RuntimeException("image could not be processed: ImageIO.read() returned null")
}
}
}
if (callback != null && !future.isDone) {
future.thenRun(callback)
}
return future
}
private fun execute(shareExecutor: Boolean, block: () -> T): CompletableFuture {
val threadExecutor = if (shareExecutor) boundExecutor else unboundExecutor
return CompletableFuture.supplyAsync(Supplier {
AccessController.doPrivileged(PrivilegedAction { block() })
}, threadExecutor)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy