view src/name/blackcap/clipman/PasteboardQueue.kt @ 1:fb224c3aebdf

Got it auto-scrolling to the bottom.
author David Barts <n5jrn@me.com>
date Sat, 18 Jan 2020 09:12:58 -0800
parents be282c48010a
children 6fb94eae32fa
line wrap: on
line source

/*
 * The queue of pasteboard items we manage. New stuff gets added to the
 * tail, and old stuff truncated off the head.
 */
package name.blackcap.clipman

import java.awt.Container
import java.awt.Rectangle
import java.util.Collections
import java.util.LinkedList
import java.util.logging.Level
import java.util.logging.Logger
import javax.swing.*

/**
 * A queue that tracks the data we display and the widgets used to
 * display them. We never explicitly remove stuff from the queue,
 * though items will get silently discarded to prevent the queue from
 * exceeding the specified maximum size.
 */
class PasteboardQueue(val parent: Container, maxSize: Int) {
    private val queue = LinkedList<QueueItem>()
    private var _maxSize = maxSize

    /**
     * The maximum allowed size of this queue. Attempts to make the queue
     * larger than this size, or specifying a size smaller than the current
     * size, will result in the oldest item(s) being discarded. A size less
     * than or equal to zero means an unlimited size.
     */
    var maxSize: Int
        get() { return _maxSize }
        @Synchronized set(value) {
            _maxSize = value
            truncate(false)
        }

    /**
     * Add a QueueItem to the end of the queue.
     * @param item QueueItem to add
     */
    @Synchronized fun add(item: QueueItem) {
        inSwingThread {
            parent.add(item.component)
            /* XXX - assumes there is a JScrollPane above us in the tree */
            var sp = parent.parent
            while (sp != null && !(sp is JScrollPane)) {
                sp = sp.parent
            }
            (sp as JScrollPane).run {
                revalidate()
                verticalScrollBar.run { value = maximum }
            }
        }
        queue.addLast(item)
        truncate(true)
    }

    private fun truncate(forceValidate: Boolean) {
        if (_maxSize > 0) {
            var size = queue.size
            var dirty = forceValidate
            while (size > _maxSize) {
                var extra = queue.removeFirst().component
                inSwingThread { parent.remove(extra) }
                dirty = true
                size -= 1
            }
            if (dirty) {
                inSwingThread { parent.validate() }
            }
        }
    }
}

/**
 * An item in the above queue.
 */
data class QueueItem(val component: JComponent, val contents: PasteboardItem)