JavaFx 監聽剪下板實現(Kotlin)

one 發表於 2021-10-10
Java Kotlin

原文地址: JavaFx 監聽剪下板實現(Kotlin) | Stars-One的雜貨小窩

軟體有個需求,想要實現監聽剪下板的內容,若內容符合預期,則進行相關的操作,就可以免去使用者手動貼上的操作,提供軟體的使用者體驗感

比如說之前我的一款下載小說的軟體,複製小說的地址後,實現自動解析功能

本篇程式碼以Kotlin為主,Java實現也是類似,各位可以參考下

實現

本質上是利用一個剪下板的setContents方法,可以傳遞個監聽介面ClipboardOwner

定義個類實現此介面ClipboardOwner,實現此介面定義個的方法lostOwnership

class SystemClipboardMonitor : ClipboardOwner {
    private val clipboard = Toolkit.getDefaultToolkit().systemClipboard
    //定義個變數,用來控制監聽的開關
    private var isOpenListener = true

    //定義個介面回撥,方便在使用的時候回撥
    var listener: GlobalClipBoardListener? = null

    init {
        clipboard.setContents(clipboard.getContents(null), this)
    }

    override fun lostOwnership(clipboard: Clipboard?, contents: Transferable?) {
        
        try {
            Thread.sleep(1)
            var text = ""
            if (clipboard?.isDataFlavorAvailable(DataFlavor.stringFlavor) == true) {
                text = clipboard.getData(DataFlavor.stringFlavor).toString()
            }
            clipboard?.setContents(clipboard.getContents(null), this)
            if (isOpenListener) {
                listener?.onCopy(text, clipboard, contents)
            }
        } catch (e: IllegalStateException) {
            //有時候會出現剪下板被佔用就會出現此異常
        }
    }

    /**
     * 移除監聽
     *
     */
    fun stopListen() {
        isOpenListener = false
    }

    /**
     * 開啟監聽
     *
     */
    fun startListen() {
        isOpenListener = true
    }

    fun addClipboardListener(listener: GlobalClipBoardListener) {
        this.listener = listener
    }
}

interface GlobalClipBoardListener {
    fun onCopy(text: String?, clipboard: Clipboard?, contents: Transferable?)
}

使用

使用的話,新建一個SystemClipboardMonitor物件即可,之後設定你的監聽操作,如下面所示

val monitor = SystemClipboardMonitor()
monitor.addClipboardListener(object :GlobalClipBoardListener{
    override fun onCopy(text: String?, clipboard: Clipboard?, contents: Transferable?) {
        //這裡可以加上相關的判斷來測試內容是否是符合自己的定義的條件才觸發對應的操作
        println("已監聽到方法...")
        println(text)
    }
})

考慮到會有設定的選項,就定義了兩個開關方法,可以在需要的時候進行開關的設定(預設是剪下板的監聽就是開啟的)

//開啟監聽
monitor.stopListen()

//停止監聽
monitor.startListen()

參考