protected void recursiveSortLines(AreaImpl root)
    {
        sortChildLines(root);
        for (int i = 0; i < root.getChildCount(); i++)
            recursiveSortLines((AreaImpl) root.getChildAt(i));
    }
    
    /**
     * Goes through the grid of areas and sorts the adjacent visual areas that are not
     * separated by anything
     */
    protected void sortChildLines(AreaImpl root)
    {
        if (root.getChildCount() > 1)
        {
            List<Area> src = new Vector<Area>(root.getChildren());
            List<Area> dest = new Vector<Area>(src.size());
            while (!src.isEmpty())
            {
                final AreaImpl seed = (AreaImpl) src.get(0);
                List<Area> line = findAreasOnLine(root, seed, src);
                dest.addAll(line);
                src.removeAll(line);
            }
            
            root.removeAllChildren();
            root.appendChildren(dest);
        }
    }

    private List<Area> findAreasOnLine(AreaImpl parent, AreaImpl area, List<Area> candidates)
    {
        Vector<Area> ret = new Vector<Area>();
        ret.add(area);
        
        final int nx1 = area.getGridPosition().getX1();
        final int ny1 = area.getGridPosition().getY1();
        final int nx2 = area.getGridPosition().getX2();
        final int ny2 = area.getGridPosition().getY2();
        final AreaTopology t = parent.getTopology();
        
        //try to expand to the right
        int dist = 1;
        while (nx2 + dist < t.getTopologyWidth())
        {
            //try to find some node at the right in the given distance
            for (int y = ny1; y <= ny2; y++)
            {
                AreaImpl neigh = (AreaImpl) t.findAreaAt(nx2 + dist, y);
                if (neigh != null && candidates.contains(neigh)) //something found
                {
                    //the maximal Y difference to consider other areas to be on the same line
                    int threshold = (Math.min(area.getHeight(), neigh.getHeight()) / 2);
                    if (threshold < 0) threshold = 0;
                    //check if the nodes could be on the same line
                    if (AreaUtils.isOnSameLine(area, neigh, threshold))
                    {
                        ret.add(neigh);
                        break;
                    }
                }
            }
            dist++;
        }
        //try to expand to the left
        dist = 1;
        while (nx1 - dist >= 0)
        {
            //try to find some node at the right in the given distance
            for (int y = ny1; y <= ny2; y++)
            {
                AreaImpl neigh = (AreaImpl) t.findAreaAt(nx1 - dist, y);
                if (neigh != null && candidates.contains(neigh)) //something found
                {
                    //the maximal Y difference to consider other areas to be on the same line
                    int threshold = (Math.min(area.getHeight(), neigh.getHeight()) / 2);
                    if (threshold < 0) threshold = 0;
                    //check if the nodes could be on the same line
                    if (AreaUtils.isOnSameLine(area, neigh, threshold))
                    {
                        ret.insertElementAt(neigh, 0);
                        break;
                    }
                }
            }
            dist++;
        }
            
        return ret;
    }
    
}
protected void recursiveSortLines ( AreaImpl root ) { sortChildLines ( root ) ; for ( int i = 0 ; i < root . getChildCount ( ) ; i ++ ) recursiveSortLines ( ( AreaImpl ) root . getChildAt ( i ) ) ; } protected void sortChildLines ( AreaImpl root ) { if ( root . getChildCount ( ) > 1 ) { List < Area > src = new Vector < Area > ( root . getChildren ( ) ) ; List < Area > dest = new Vector < Area > ( src . size ( ) ) ; while ( ! src . isEmpty ( ) ) { final AreaImpl seed = ( AreaImpl ) src . get ( 0 ) ; List < Area > line = findAreasOnLine ( root , seed , src ) ; dest . addAll ( line ) ; src . removeAll ( line ) ; } root . removeAllChildren ( ) ; root . appendChildren ( dest ) ; } } private List < Area > findAreasOnLine ( AreaImpl parent , AreaImpl area , List < Area > candidates ) { Vector < Area > ret = new Vector < Area > ( ) ; ret . add ( area ) ; final int nx1 = area . getGridPosition ( ) . getX1 ( ) ; final int ny1 = area . getGridPosition ( ) . getY1 ( ) ; final int nx2 = area . getGridPosition ( ) . getX2 ( ) ; final int ny2 = area . getGridPosition ( ) . getY2 ( ) ; final AreaTopology t = parent . getTopology ( ) ; int dist = 1 ; while ( nx2 + dist < t . getTopologyWidth ( ) ) { for ( int y = ny1 ; y <= ny2 ; y ++ ) { AreaImpl neigh = ( AreaImpl ) t . findAreaAt ( nx2 + dist , y ) ; if ( neigh != null && candidates . contains ( neigh ) ) { int threshold = ( Math . min ( area . getHeight ( ) , neigh . getHeight ( ) ) / 2 ) ; if ( threshold < 0 ) threshold = 0 ; if ( AreaUtils . isOnSameLine ( area , neigh , threshold ) ) { ret . add ( neigh ) ; break ; } } } dist ++ ; } dist = 1 ; while ( nx1 - dist >= 0 ) { for ( int y = ny1 ; y <= ny2 ; y ++ ) { AreaImpl neigh = ( AreaImpl ) t . findAreaAt ( nx1 - dist , y ) ; if ( neigh != null && candidates . contains ( neigh ) ) { int threshold = ( Math . min ( area . getHeight ( ) , neigh . getHeight ( ) ) / 2 ) ; if ( threshold < 0 ) threshold = 0 ; if ( AreaUtils . isOnSameLine ( area , neigh , threshold ) ) { ret . insertElementAt ( neigh , 0 ) ; break ; } } } dist ++ ; } return ret ; } }
Goes through all the areas in the tree and sorts their sub-areas.