Dobieslaw said:
I know that, however the bounding rectangle of the graph algorithm related
drawings will be very big in most steps. I found an easier (and better, I
believe) solution. The GraphPane (derived from JPanel) has a BorderLayout,
and I add to its center as a child the AlgorithmPane (derived from
JComponent). The GraphPane takes all the mouse input, and it draws the graph
in its paintComponent() method. The AlgorithmPane gets no user inputs and
just paints the graph algorithm related figures in its paintComponent() - on
top of the surface of the GraphPane.
This seems to work nice, the AlgorithmPane lets the user input go through it
and it is automatically repainted whenever the GraphPane.repaint() is
called.
It's equally true that, because AlgorithmPane is transparent, GraphPane
is automatically repainted every time AlgorithmPane is repainted. If
your goal is to make your code run faster, then you've failed.
It's interesting that you failed, but didn't notice. Perhaps the
optimizations you are performing are not so important after all. Did
you observe a real performance problem, or are you just assuming that
one will exist? If you're just assuming, then you should stop now and
come back when you have a real problem.
I have not used the 'getClipBounds' optimisation yet, but on the other hand
I am wondering if this makes any sense. I suspect that 'r =
g.getClipBounds()' and then checking the intersection of r with the bounds
of all nodes and edges is very fast compared to repainting all of them, but
on the other hand calculating the bounds of every node is quite complicated
as a node has a variable-length label (so, the call to
Font.getStringBounds(...) is needed in order to estimate the bounds).
If you're concerned about the time it takes to re-layout the component
every time, then the first thing to do is store all of that information
on the location and size of the graph components. For example, you
might keep a HashMap storing the bounds of each graph node and edge.
When you change anything that may affect the layout, such as adding or
removing nodes and edges, changing the font, etc, you'll need to
recalculate the layout. For example:
public class GraphPane extends JPanel
{
private Font font;
private HashMap<Node, Rectangle2D> nodeBounds = null;
private HashMap<Edge, Rectangle2D> edgeBounds = null;
...
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if ((nodeBounds == null) || (edgeBounds == null))
{
calculateLayout();
}
...
}
private void calculateLayout()
{
...
}
public void setFont(Font f)
{
this.font = f;
nodeBounds = edgeBounds = null;
repaint();
}
...
}
Of course, there are further optimizations you could make here based on
additional information about the layout algorithm. For example, you may
be able to avoid pieces of the layout work if you know they aren't
affected by a change. Once you get6 back to optimization of the
painting code, you could even use quadtrees to avoid walking the entire
list of nodes or edges when repainting, but I seriously doubt you'll get
enough of the graph on one computer screen to justify something that
complex.
So test, identify if there's a problem, and then apply small
optimizations as needed to solve that problem.
--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation