Dial Widget Drawing


#1

Hi,

I need to place 32 ‘dial’ type displays on the screen, sort of like a pie-chart look.
I designed my dial using the addArcSegment method of Path which automatically draws a path of straight lines around the edge of the circle spaced 0.05 radians apart.
Unfortunately, hooking it up to my new shiny vertical slider gives REALLY slow performance on even my 2.8GHz Athlon when dragging the slider up and down. IS THERE ANY WAY OF SPEEDING THIS UP?

I guess options may be to use larger radian interval, or even draw one or two cubic lines instead of lots of straight ones. Another might be to use two half circles and mask portions out with a rotating rectangle…
WOULD AN OPENGL IMPLEMENTATION BE FASTER??

Another weird thing is that if I scale the dials down in size, they respond a lot faster, even though it seems to simple-old-me that it must be doing the same number of operations. So would rendering it small and then artificially scaling up somehow be another solution???

Huge thanks in anticipation of any response at all! I really need these responsive dials being, erm, responsive. Cheers!

Matt


#2

Maybe using an image cache of 100 or so frames of the animated dial may be faster??

btw: I just read a discouraging page on the GDI+ FAQ (http://www.bobpowell.net/why_so_slow.htm)… :frowning:


#3

I’ve used the addArcSegment stuff to do exactly the same thing in another project, and it was extremely fast - sounds like you’re accidentally doing too much work somehow? Just drawing a fairly small shape shouldn’t present any speed problems, as you can see from stuff like the juce demo.


#4

Hi Jules,

yes, I suppose add ArcSegment is quite fast. In the case of a single dial, everything looks very nice and it responds very fast. However, addingandmakingvisible 32 of those dials so that they take up the entire screen means they suddenly STOP being so fast and responsive!!

I have had a few suggestions from people such as ‘draw all dials in the same component so they get drawn all together rather than individually’ or use ‘hardware accelerated translation/rotation of components’ as is possible in my black-rectangle-mask idea.

I did get the ‘video’ version working last night, where I preloaded about 20 frames of a dial spinning round into an imagecache, setting the hashcode accordingly, and using drawImageAt(). This DOES actually seem to be a bit faster! I suppose since the drawing has to create the image bitmap to blat to the screen anyway at the end of the day, the image buffer just bypasses these processes to perform prebuffered ‘blatting’. The PLUS side of this of course is that my dials can look like photos!

However, this still hogs my cpu significantly and doesn’t seem like the ‘best’ solution.
I can still imagine drawing 32 3d cubes in opengl and have them spinning around and it still being faster than drawing simple shapes, but I may be very wrong.

Just drawing a fairly small shape shouldn’t present any speed problems

But what about the big shapes?:!: :wink:

Thanks for your help!


#5

Big shapes will always be a problem until I’ve added some hardware acceleration! (and they’ll still be slower - drawing shapes is just a tricky thing)

Why do you need to redraw all 32 dials? If you’ve designed your UI nicely, you should only ever repaint the things that actually change, so does changing one value affect all the others?

P.S. putting them all in one component won’t make it faster, it’ll just be a mess! Keep them separate and use ChangeListener/ChangeBroadcaster to update them lazily and individually.


#6

putting them all in one component won’t make it faster, it’ll just be a mess!

Ha! well thats good to hear. I was fearing that inevitable ‘mess’.

As you may have imagined, I was redrawing the entire dial each time (at the time I wasn’t sure how to just draw extra segments on top).
Instead I’ve now settled on an extremely complicated - but hopefully unbeatably fast - dial in the shape of a rectangle with the centre removed. Lines are drawn at regularly spaced angles to indicate position, and the component is divided into four smaller rectangle sections (since I imagined that even drawing a single line inside the component required the component to create a bitmap the size of the component itself, so I minimised this area by disregarding the centre section entirely). This one will only draw NEW lines, making use of the fact that the dials will never go anticlockwise!

Basically, the reason I need 32 dials is that these display ‘play position’ and need them all to update as frequently as possible.
Thanks for your VERY fast replies, man! If you have any spare time I’d appreciate it if you could verify whether I’m correct in thinking that drawing a SINGLE line in a component requires the entire visible area of the component to be redrawn - therefore indicating that cpu doesn’t particularly correspond to how MUCH you draw - or whether the amount you draw DIRECTLY affects cpu, as in 2 lines would update roughly half as fast as drawing one.

Thanks again!


#7