0

I am currently working on a complex project and struggle with increasing the performance, because I ran out of ideas.

So this is what my program looks like at the moment:

enter image description here

It is a Graph, that shows the path of an object, starting at the green node and ending at the red node. The container is a JPanel, which holds another JPanel at the top right corner, containing the buttons, a JLabel at the top left corner for the status and the different Nodes itself of course. The Nodes and lines are JPanels as well.

So what exactly is the problem?

The Graph contains lots of functionalities. Zooming, DnD and adding end deleting new nodes. All of these functionalities need the container to repaint, especially DnD needs this very often. So this is just an example with 4 nodes. everything works fine. But at 1000+ nodes and 999 lines between them, it really gets slow. The graph should be able to work with ~20K nodes without having big troubles.

Everytime you move a Node 1px with the mouse in any direction, the whole container gets repainted.

Creating a minimal reproducable example is not quiet possible, because the code for this application is long and there are a lot of dependencies, that would make it not "minimal".

The ideas I have to increase performance are:

  • Reducing the amount of Nodes (and so the amount of lines), so that less components need to be repainted. This is quiet hard, most nodes are not in a straight line, means there are not many ways to do this. One option would be to reduce the Nodes and increase the level of detail with the zoom function.

  • Clipping the area, that has to be repainted. The problem with this approach is, that I don't know how exactly this clipping function works or whether it is even possible.

  • The last idea of mine would be, to somehow create a JLayer object containing (total amount of nodes / 100) layers, that are all visible and only repainting the layer, that contains the specific Node. This seems very unstructured, I don't really think that this is an option, just an idea.

What am I asking for right now?:

How do you manage so much components that have to be repainted? There are definitly ways and I am open to try them all. I just want you to give me some advice, hints on useful built in libraries, that I maybe haven't found in my research. And if one of my ideas could be the one I should go for.

I am not asking for concrete code examples, just for your experience.

Thank you in advance and I'm sorry if my question does not fit the SO conventions.

John
  • 136
  • 12
  • 4
    I did complex things by my own data structures and rendering them in one JPanel's paintComponent. Selection state, mouse, shadow, zooming all no problems. No new Color, careful with changes. So do profiling with a profiler, and by logging counts and times. Maybe use google maps' technique of other detail levels by zoom factor. **Prepare things before they are rendered.** (Double buffering, swing timer) – Joop Eggen Aug 05 '22 at 14:33
  • Not sure how you are painting the nodes/lines but maybe you can treat them as a single object as the "barbell" shape in this example: https://stackoverflow.com/questions/67443343/drag-a-painted-shape – camickr Aug 05 '22 at 22:40
  • Release the idea of having the graph rendered using multiple JComponents. Just use one to do it all. If speed is still not enough, consider going towards LWJGL or libGDX, – Queeg Aug 07 '22 at 06:34
  • As I recall, the `GraphPanel` cited [here](https://stackoverflow.com/a/11944233/230513) scaled well into the thousands, but _tens_ of thousands calls for the [_flyweight pattern_](https://stackoverflow.com/a/45362769/230513). – trashgod Aug 08 '22 at 23:04
  • @trashgod I appreciate your advice with the flyweight pattern. But how could I make use of it? Every Node has different coordinates. I don't see, how I could possibly improve my performance – John Aug 09 '22 at 08:33
  • @John: Coordinate and color properties are lightweight; rendering is expensive. By not rendering invisible objects, flyweight rendering is one way to avoid the overhead: examples [here](https://stackoverflow.com/a/25526869/230513) and [here](https://stackoverflow.com/a/15702152/230513). – trashgod Aug 09 '22 at 17:23

0 Answers0