Is it possible to import or create additional mouse pointer options? I just jumped through some hoops and did the same sort of thing with a floating image, but man, it would be easier if I could just change the pointer. Is there some java library available for us to do that?
Yeah, you can. Check out java.awt.Toolkit.createCustomCursor
The trick is to get the Image. You could do something like this:
Ok, I’m almost there, but can’t see where the “expecting 4 args but got 3” error is coming from. In Java examples where there is something like “new Point(0,0)”, what do I use for new?
Here is my code:
p = Point2D.Double(2,2) #Point(2,2) newCursor = javax.swing.ImageIcon(java.net.URL('http://localhost:8080/gateway/images/Builtin/icons/24/refresh.png')) b = Toolkit.createCustomCursor(newCursor,p,'TEST')
I’ve tried a couple of different ways of defining Point, but I still get this error (Line 11 is Line 4 above):
ERROR [ActionAdapter-AWT-EventQueue-0] <HTML>Error executing script for event: <code><b>mousePressed</b></code><BR>on component: <code><b>ModulePB</b></code>. Traceback (innermost last): File "<event:mousePressed>", line 11, in ? TypeError: createCustomCursor(): expected 4 args; got 3 at org.python.core.Py.TypeError(Py.java) at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java) at org.python.core.PyReflectedFunction.throwArgCountError(PyReflectedFunction.java) at org.python.core.PyReflectedFunction.throwError(PyReflectedFunction.java) at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java) at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java) at org.python.core.PyObject.__call__(PyObject.java) at org.python.core.PyObject.invoke(PyObject.java) at org.python.pycode._pyx257.f$0(<event:mousePressed>:11) at org.python.pycode._pyx257.call_function(<event:mousePressed>) at org.python.core.PyTableCode.call(PyTableCode.java) at org.python.core.PyCode.call(PyCode.java) at org.python.core.Py.runCode(Py.java)
I don’t think the point is your problem, you need to do:
b = Toolkit.getDefaultToolkit().createCustomCursor(newCursor,p,'TEST')
createCustomCursor is not a static function, so in python-speak, it takes 4 arguments, the first being the instance of the Toolkit object.
I can’t answer you question re: the error but I can address the “new” issue.
There is no equivalent to the java “new” keyword in Jython. That’s because java is “static typed” and Jython is “dynamic typed”. New instances of an object must be created with the “new” keyword in java. Instances in Jython are created on the fly and don’t have to be created with a “new” keyword.
I’ll try playing with your error this evening, when I get a chance.
Thanks Mickey. Carl nailed it above. I’m going to give it a try tonight.
Here’s a more extensive code snippet:
url = java.net.URL('http://localhost:8080/gateway/images/Builtin/icons/24/refresh.png')
icon = javax.swing.ImageIcon(url)
point = java.awt.Point(2,2)
component = event.source.parent.getComponent("componentName")
customCursor = java.awt.Toolkit.getDefaultToolkit().createCustomCursor(icon.getImage(),point,'refresh')
To reset the cursor:
defaultCursor = java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR)
Here’s a list of the predefined cursors:
You can get the component’s current cursor with the following line:
currentCursor = component.getCursor()
and set it back with this:
Very cool. Thanks Mickey.
I ended up with a different implementation, but with the same results. Is there a preference when it comes to using fully qualified names for methods? For instance, I normally use something like “from java.awt import Image” rather than “import java.awt” and then using java.awt.Image in the code. I have no good reason for doing this other than that’s how I learned to do it through trial and error and it saves a lot of typing when you use the paint component. But otherwise, is one style better than another or is it a wash?
edit: Forgot to post my code.
from java.awt import Cursor from java.awt import Toolkit from java.awt import Image from javax.swing import ImageIcon from java.net import URL from java.awt import Point p = Point(12,12) icon = ImageIcon(URL("http://localhost:8080/gateway/images/Builtin/icons/24/refresh.png")).getImage() newCursor = Toolkit.getDefaultToolkit().createCustomCursor(icon,p,'TEST')
I prefer the “from module import object” approach too. I was playing with it in the Interactive Script Tester and was just too lazy/tired to refactor it as I would have for production code.
The snippet also has a lot more variables than I would normally use but they helped me break up the code into smaller entities so that I could better determine where exceptions were being generated.
I didn’t mean your code specifically. I could see that it was more verbose for the sake of clarity. I meant just in general, and I was reminded of it since your snippet used the fully qualified name in the code. My guess is that the compiler resolves the pointers at compile time in all cases anyway, and using “from … import …” just reduces the amount of typing while writing the code.
Another quick question- do your pointers look ragged? When I use the same images on buttons, the results are very smooth, but when I assign them to mouse pointers, they are coarse. Does fpmi do some kind of image filtering under the covers when it assigns them to buttons?
edit: I think I see what’s happening. The button scales the image down, and looks smoother that way. It is only noticeable on icons that have curves anyway, and it looks great on the other ones. I’ll look at scaling the image before I assign it to the cursor object if I get an icon that really doesn’t look right.
You might want to take a look at the “getBestCursorSize” entry on Carl’s link above.
It recommends calling “getBestCursorSize” to get the cursor dimensions and selecting a image that is of comparable size. It also notes that rescaling an image can degrade quality.
[color=#FF4000]WARNING.[/color] This is a dangerous, experimental (read: unsupported) feature. If you use this, make sure the code is only executed in the client, not the designer, because these custom cursor’s break window serialization.
Thanks for the help on this Carl. Yeah, you have to tread lightly, but the end effect looks great.
Btw, disregarding customCursors for the moment, I found a nice site that has a lot of open-source icons that will fit nicely with normal buttons, which serialize just fine: Tango
The standard Tango library is pretty nice, and if you drill down into the other links, you’ll also find Frugal .
All of these can be wrapped into commercial projects for free (with proper credit, of course).
Another quick question about “customCursor”. What is the significance of the “name” parameter? The docs say this: “a localized description of the cursor, for Java Accessibility use”. Does that name do anything for me? It doesn’t seem to matter what I enter, plus I reference the cursor like this anyway:
newCursor = Toolkit.getDefaultToolkit().createCustomCursor(icon,p,'View')
Java Accessibility is going to come into play when people with special gui needs (in this case, blindness) use the software. This can help the software dictate to the user that the cursor has changed in a non-visual way.