Skip to content

Instantly share code, notes, and snippets.

@itsu-dev
Created August 20, 2021 10:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save itsu-dev/fe586cc4df9abd601abff6b7b49415b1 to your computer and use it in GitHub Desktop.
Save itsu-dev/fe586cc4df9abd601abff6b7b49415b1 to your computer and use it in GitHub Desktop.
JPen with JavaFX Canvas
import jpen.owner.PenClip
import java.awt.Point
import java.awt.geom.Point2D
import kotlin.math.round
class JavaFXPenClip(private val javaFXPenOwner: JavaFXPenOwner) : PenClip {
override fun evalLocationOnScreen(pointOnScreen: Point) {
val converted = javaFXPenOwner.getActiveCanvas().localToScreen(0.0, 0.0)
pointOnScreen.x = round(converted.x).toInt()
pointOnScreen.y = round(converted.y).toInt()
}
override fun contains(point: Point2D.Float): Boolean {
val activeCanvas = javaFXPenOwner.getActiveCanvas()
return !(point.x < 0.0F)
&& !(point.y < 0.0F)
&& !(point.x > activeCanvas.width.toFloat())
&& !(point.y > activeCanvas.height.toFloat())
}
}
import javafx.event.EventType
import javafx.scene.Node
import javafx.scene.canvas.Canvas
import javafx.scene.layout.Region
import jpen.PenProvider
import jpen.owner.AbstractPenOwner
import jpen.owner.PenClip
import jpen.provider.osx.CocoaProvider
import jpen.provider.system.SystemProvider
import jpen.provider.wintab.WintabProvider
import jpen.provider.xinput.XinputProvider
import java.awt.event.MouseEvent
import java.lang.ref.WeakReference
class JavaFXPenOwner(private val canvas: Canvas) : AbstractPenOwner() {
private val javaFXPenClip = JavaFXPenClip(this)
private val unpauser = Unpauser()
override fun getPenProviderConstructors(): Collection<PenProvider.Constructor> {
return listOf(
SystemProvider.Constructor(),
XinputProvider.Constructor(),
WintabProvider.Constructor(),
CocoaProvider.Constructor()
)
}
override fun getPenClip(): PenClip {
return this.javaFXPenClip
}
protected fun pause() {
this.unpauser.disable()
this.penManagerHandle.setPenManagerPaused(true)
}
override fun draggingOutDisengaged() {
this.pause()
}
override fun init() {
this.canvas.setOnMouseExited { e ->
synchronized(this.getPenSchedulerLock(e.source as Node)) {
if (!this.startDraggingOut()) {
this.pause()
}
}
}
this.canvas.setOnMouseEntered { e ->
synchronized(this.getPenSchedulerLock(e.source as Node)) {
if (!this.stopDraggingOut()) {
this.unpauser.enable()
}
}
}
}
fun getActiveCanvas() = this.canvas
protected fun getPenSchedulerLock(node: Node?): Any {
if (node != null) {
Thread.currentThread()
// if (Thread.holdsLock(region.))
}
return this.penManagerHandle.penSchedulerLock
}
private inner class Unpauser {
@Volatile private var enabled = false
private var myActiveCanvasRef: WeakReference<Canvas>? = null
@Synchronized
fun enable() {
if (this.enabled) return
val myActiveCanvas = this@JavaFXPenOwner.getActiveCanvas()
this.myActiveCanvasRef = WeakReference(myActiveCanvas)
myActiveCanvas.setOnMouseMoved { this.unpause() }
this.enabled = true
}
@Synchronized
fun disable() {
if (!this.enabled) return
myActiveCanvasRef?.get()?.setOnMouseMoved { }
this.enabled = false
}
fun unpause() {
synchronized(this@JavaFXPenOwner.penManagerHandle.penSchedulerLock) {
if (this.enabled) {
this@JavaFXPenOwner.penManagerHandle.setPenManagerPaused(false)
this.disable()
}
}
}
}
}
import javafx.scene.canvas.Canvas
fun main() {
val manager = PenManager(JavaFXPenOwner(Canvas()))
// do something...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment