First of all, many thanks to the authors of jpen-2, I have been using it
for many years as the basis for the Tablet library in Processing ( http://interfaze.info/libraries/tablet/).
It appears that AWT is starting to fall out of favor as the default
windowing toolkit. Oracle's efforts go mostly behind JavaFX, while JOGL (an
OpenGL-Java binding) introduced its own toolkit (NEWT, http://jogamp.org/jogl/doc/NEWT-Overview.html).
NEWT defines its own base class (GLWindow) but has some API reminiscent of
AWT (listeners, etc.) This makes me wonder how difficult would be to
implement a NewtPenOwner, etc.
jogl and newt are fun. Here is an implementation of a newt WindowPenOwner:
importcom.jogamp.newt.event.MouseAdapter;importcom.jogamp.newt.event.MouseEvent;importcom.jogamp.newt.Window;importjava.util.Arrays;importjava.util.Collection;importjpen.owner.PenClip;importjpen.owner.PenOwner;importjpen.PenEvent;importjpen.PenProvider;importjpen.provider.osx.CocoaProvider;importjpen.provider.wintab.WintabProvider;importjpen.provider.xinput.XinputProvider;publicclassWindowPenOwnerimplementsPenOwner{privatePenManagerHandlepenManagerHandle;privatefinalWindowPenClipWindowPenClip=newWindowPenClip(this);privatefinalWindowwindow;privatevolatilebooleanmayBeDraggingOut;publicWindowPenOwner(Windowwindow){this.window=window;}publicWindowgetWindow(){returnwindow;}@OverridepublicvoidsetPenManagerHandle(PenManagerHandlepenManagerHandle){this.penManagerHandle=penManagerHandle;window.addMouseListener(newMouseAdapter(){@OverridepublicvoidmouseEntered(MouseEventev){mayBeDraggingOut=true;// escape from the EDT to avoid thead-safety issues...newThread(()->penManagerHandle.setPenManagerPaused(false)).start();}@OverridepublicvoidmouseExited(MouseEventev){mayBeDraggingOut=false;// escape from the EDT to avoid thead-safety issues...// Note: this has a side effect: some level events continue to be fired for a "very short time" after the mouse has exited, we would have to modify jpen internals to filter them out if necessary... let me know if this needs to be done for your use case.newThread(()->penManagerHandle.setPenManagerPaused(true)).start();}});}@OverridepublicCollection<PenProvider.Constructor>getPenProviderConstructors(){returnArrays.asList(newPenProvider.Constructor[]{//Note: do you need a newt mouse/keyboard provider (so that regular newt mouse events/keyboard are fired as jpen events too)?newXinputProvider.Constructor(),newWintabProvider.Constructor(),newCocoaProvider.Constructor(),});}@OverridepublicPenClipgetPenClip(){returnWindowPenClip;}@OverridepublicbooleanisDraggingOut(){returnmayBeDraggingOut;}@OverridepublicObjectevalPenEventTag(PenEventev){returnnull;}@OverridepublicbooleanenforceSinglePenManager(){returntrue;}}
and its WindowPenClip:
importcom.jogamp.newt.Window;importjava.awt.geom.Point2D;importjava.awt.Point;importjava.awt.Rectangle;importjpen.owner.PenClip;finalclassWindowPenClipimplementsPenClip{finalWindowPenOwnerwindowPenOwner;publicWindowPenClip(WindowPenOwnerwindowPenOwner){this.windowPenOwner=windowPenOwner;}@OverridepublicvoidevalLocationOnScreen(PointpointOnScreen){//-> called holding the pen scheduler lockpointOnScreen.x=pointOnScreen.y=0;com.jogamp.nativewindow.util.PointjoglPoint=windowPenOwner.getWindow().getLocationOnScreen(null);pointOnScreen.x=joglPoint.getX();pointOnScreen.y=joglPoint.getY();}@Overridepublicbooleancontains(Point2D.Floatpoint){//-> called holding the pen scheduler lockif(point.x<0||point.y<0)returnfalse;Windowwindow=windowPenOwner.getWindow();returnpoint.x<=window.getWidth()&&point.y<=window.getHeight();}}
A dummy application printing jpen events on std output is:
importcom.jogamp.newt.event.WindowAdapter;importcom.jogamp.newt.event.WindowEvent;importcom.jogamp.newt.opengl.GLWindow;importcom.jogamp.newt.Window;importcom.jogamp.opengl.GLCapabilities;importcom.jogamp.opengl.GLProfile;importjpen.event.PenAdapter;importjpen.PenManager;importjpen.PKindEvent;importjpen.PLevelEvent;publicclassJPenOnWindow{publicsynchronizedstaticvoidmain(String...args)throwsThrowable{Windowwindow=GLWindow.create(newGLCapabilities(GLProfile.getDefault()));window.setTitle("Newt and JPen");window.addWindowListener(newWindowAdapter(){@OverridepublicvoidwindowDestroyNotify(WindowEventev){synchronized(JPenOnWindow.class){JPenOnWindow.class.notify();}}});installJPen(window);window.setVisible(true);JPenOnWindow.class.wait();}staticvoidinstallJPen(Windowwindow){PenManagerpenManager=newPenManager(newWindowPenOwner(window));penManager.pen.addListener(newPenAdapter(){@OverridepublicvoidpenLevelEvent(PLevelEventev){System.out.println("ev="+(ev));}@OverridepublicvoidpenKindEvent(PKindEventev){System.out.println("ev="+(ev));}});}}
This code run as expected on my linux (wacom) box, I haven't tested on Windows or OS X. Let me know if you do, and what you think... would this be enough for your use case?
que la pases bien!
Nicolas
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Excellent, thanks so much! I will use your code to update the Processing Tablet library, and will test on Windows and OS X. I will post an update shortly!
Saludos,
Andres
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I incorporated the NEWT's WindowPenOwner into the Tablet library, and the good news is that it works (tested it on OS X)!
However, one user reported that the library is queuing up all the intermediate pen values generated between each frame. However, when the user queries the pressure, position, etc., the oldest value in the queue is returned. This is in contrast with AWT, where the current pen state is returned.
So two questions:
1) How can we get the most recent pen state with NEWT's WindowPenOwner?
2) Is it possible to access the entire queue?
Thanks!
Andres
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
you can try disabling jpen event buffering by inserting "pm.pen.setFrequencyLater(1001);" on line ~147 of Tablet.java, (javadoc, 60 by default, values greater than 1000 will disable buffering). Let me know what you think or if this change resolves the issue. **
Cheers!
Nicolas
** Note that changing the Pen frequency to 200 or higher will cause potentially 200/60=~3 times more event processing by the Processing applet penTock (a Wacom Intuos reaches 200pps maximum) which can lead to unnecessarily high CPU usage. An alternative is adding a new setFrequency(){pm.setFrequencyLater()} method on Tablet.java and let demanding clients call it if needed.
Last edit: Nicolas Carranza 2015-10-17
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi there,
First of all, many thanks to the authors of jpen-2, I have been using it
for many years as the basis for the Tablet library in Processing (
http://interfaze.info/libraries/tablet/).
It appears that AWT is starting to fall out of favor as the default
windowing toolkit. Oracle's efforts go mostly behind JavaFX, while JOGL (an
OpenGL-Java binding) introduced its own toolkit (NEWT,
http://jogamp.org/jogl/doc/NEWT-Overview.html).
NEWT defines its own base class (GLWindow) but has some API reminiscent of
AWT (listeners, etc.) This makes me wonder how difficult would be to
implement a NewtPenOwner, etc.
Best,
Andres
hi Andres, I will take a look at newt next weekend and let you know.
thank you,
Nicolas
Last edit: Nicolas Carranza 2015-09-02
hi Andres,
jogl and newt are fun. Here is an implementation of a newt WindowPenOwner:
and its WindowPenClip:
A dummy application printing jpen events on std output is:
This code run as expected on my linux (wacom) box, I haven't tested on Windows or OS X. Let me know if you do, and what you think... would this be enough for your use case?
que la pases bien!
Nicolas
Hola Nicolas,
Excellent, thanks so much! I will use your code to update the Processing Tablet library, and will test on Windows and OS X. I will post an update shortly!
Saludos,
Andres
Hi Nicolas,
I incorporated the NEWT's WindowPenOwner into the Tablet library, and the good news is that it works (tested it on OS X)!
However, one user reported that the library is queuing up all the intermediate pen values generated between each frame. However, when the user queries the pressure, position, etc., the oldest value in the queue is returned. This is in contrast with AWT, where the current pen state is returned.
So two questions:
1) How can we get the most recent pen state with NEWT's WindowPenOwner?
2) Is it possible to access the entire queue?
Thanks!
Andres
Hi Andres,
you can try disabling jpen event buffering by inserting "pm.pen.setFrequencyLater(1001);" on line ~147 of Tablet.java, (javadoc, 60 by default, values greater than 1000 will disable buffering). Let me know what you think or if this change resolves the issue. **
Cheers!
Nicolas
** Note that changing the Pen frequency to 200 or higher will cause potentially 200/60=~3 times more event processing by the Processing applet penTock (a Wacom Intuos reaches 200pps maximum) which can lead to unnecessarily high CPU usage. An alternative is adding a new setFrequency(){pm.setFrequencyLater()} method on Tablet.java and let demanding clients call it if needed.
Last edit: Nicolas Carranza 2015-10-17
** UPDATE to previous post: I just saw that Tablet.java does not do anything with the penTock method. You can ignore the previous note :-)
Hi Nicolas,
Thanks for the help, I will try the setFrequencyLater(1001) call!
Andres