0

I have a very large complicated diagram that needs to be drawn on the fly.

I am already using a double buffered technique to paint the image (from this answer: Using threads to paint panel in java) however, the generated image that is being painted is so large that it cant be painted as a single image (and the multiple images required to paint it cant be stored in memory all at the same time). For this reason, I paint the currently visible area of the view + some margin. As I scroll, I paint the area that is going to come next, and remove from memory the area we just came from. However, if the user then decides to change direction, they need to wait for this area to be painted again. My question is this:

If a single "frame" of the screen being painted is approximately 1000*1000 pixels, in which approximately 5000 lines/circles are drawn (nodes/edges of a graph) is it likely to be more efficient to repaint this image each time, or is there a way to affectively cache the image to hard disk (to avoid java heap limitations).

Ive already optimised the paint method as much as I can think of, but there are still several seconds of delay if a user scrolls to quickly (i.e. moves out of the painted area before the next set of "frames" are painted). So my second question is this: Will moving to OpenGL offer a large improvement, and will it require major changes to the infrastructure of the code? (I tried doing this a couple of days ago, and found it was not as simple as I thought - often led to the computer crashing).

Community
  • 1
  • 1
Zack Newsham
  • 2,810
  • 1
  • 23
  • 43

1 Answers1

2

Several things come to mind:

  • Profile to verify your working hypotheses; self-time the animation budget on your target platform for comparison, as shown in this AnimationTest.

  • Compare your approach to the example cited here; it scales into the 1000's and accommodates dragging selections into the hundreds.

  • If your frames have a suitable geometry, consider adopting the flyweight pattern for rendering; JTable rendering is an example; the underlying mechanism using CellRendererPane is examined here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks very much for the answer - it didnt actually "help" but it set me looking at something else, which ended up being the issue, I wasnt caching the values of the nodes - very embarrassing. Its odd though, because the calculations to determine node position are not particularly intensive, (does involve divide and modulo though). Anyhow, just caching the values meant that instead of taking 20+ seconds to draw each frame, it takes closer to 1 second. The link you gave likely wouldnt scale enough - the graphs I am looking at have upwards of 400,000 nodes and double that in edges. – Zack Newsham Dec 06 '13 at 05:28
  • Glad you got it sorted and good observation; a `GridLayout` of components lags in the low thousands, while `JTable` scales to millions; `JGraph` also uses the pattern; please consider updating or [answering](http://meta.stackexchange.com/q/17463/163188) your question to reflect your finding. – trashgod Dec 06 '13 at 11:27
  • just so I understand, it seems like you are suggesting that I use a table to draw the different images that need to be drawn? This actually sounds like a great idea, but I'm not sure how I would implement it, presumably as your answer suggests Each cell has a visible area which is unique, and I would just pass that visible area to my current drawing system? – Zack Newsham Dec 07 '13 at 00:26
  • @ZackNewsham: A custom `JTable` renderer is not bad idea; see the _rendering_ link above. – trashgod Dec 07 '13 at 00:30
  • 1
    Hey, just wanted to let you know I went with the custom renderer, made my implementation a little slower (working on that) but much more consistent. – Zack Newsham Dec 13 '13 at 07:31