I have been running into issues with the repaint event handler taking up too much of the client resources. This code takes the byte array into an image. Recently the images we have displaying became higher resolution. The byte array expanded from ~80,000 to ~500,000. I have taken some tips from slower/stop repainting but it is still quite slow client side, within my designer it perform well. I am not sure what I can do to improve performance.
Old Code
g = event.graphics
bytes = system.file.readFileAsBytes("C:\\imagefile.PNG")
if bytes:
from javax.imageio import ImageIO
from java.io import ByteArrayInputStream
image = ImageIO.read(ByteArrayInputStream(bytes))
scaledImage = image.getScaledInstance(700,600,0)
g.drawImage(scaledImage,0,-15,event.source)
New Code
Repaint
g = event.graphics
filename = "C:\\imagefile.PNG"
image = event.source.getClientProperty("img-cached")
if not event.source.manualTextFieldModified and image:
g.drawImage(image, 0, 0, 820, 615, event.source)
propertyChange
filename = "C:\\imagefile.PNG"
image = event.source.getClientProperty("img-bytes-cached")
if event.source.manualTextFieldModified or not image:
from javax.imageio import ImageIO
from java.io import ByteArrayInputStream
bytes = system.file.readFileAsBytes(filename)
image = ImageIO.read(ByteArrayInputStream(bytes))
event.source.putClientProperty("img-cached",image)
system.tag.write("manualTextFieldModified", 0)
Hmm. New code looks good overall to me. One note though, please use the preformatted text option (it looks like a laptop in the toolbar above the comment, or press ctrl+shift+C. Its much easier to read.)
I’m wondering why you’re using a paintable canvas for this, though. This looks like a job for the normal image component, uhnless you’re doing more with it. The image filename looks static, perfect for the image component. If not, I believe theres a way to dynamically edit the images in the little image browser that pops up when you select an image. Unfortunately I’m not familiar with that, but hopefully someone else can point out how to do that, if its possible.
Try setPath() on the image component (see here). But I was rereading your code, your propertyChange script - does it check for event.propertyName? If not, that’s probably the issue.
Unfortunately, there’s an upper bound to Java Swing’s graphic performance - all operations are CPU-bound, rather than using the GPU for painting related tasks. A large byte array is always going to be “expensive” to draw. You can try enabling hardware acceleration using a command line flag, but your results may vary - this option is disabled by default and not something we test against: -Dsun.java2d.opengl=true (see the manual for instructions on how to use command line flags)
Also, I don’t know if you just omitted this for copy-pasting, but if your propertyChange script is exactly what you posted, then you can also get an easy performance gain by only actually running your code if the event is relevant, ie:
if event.propertyName == 'manualTextFieldModified':
# put the rest of your code here
I did not notice any performance gain from this code change.
The whole reason I embarked on improving the code was that when I used the old code. It would bog down all the text fields and drop downs. The text fields values are used within the image itself. The new code does not bog down the client but it takes way a while to load.
Transition Time between the new different image sizes.
Old Code
Small Image -> Big Image = Load time 8 secs
Large Image loaded modify text on image = 6 secs
Big Image to Small Image = 6 secs
Down side, everything is slower.
New Code
Small Image -> Big Image = Load time 22 secs
Large Image loaded modify text on image = 4 secs
Big Image to Small Image = 4 secs