Ignore:
Timestamp:
02/18/13 09:31:15 (11 years ago)
Author:
pharms
Message:
  • improved performance of showing GUI models
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-core-events/src/main/java/de/ugoe/cs/autoquest/eventcore/guimodel/GUIModel.java

    r927 r1086  
    2121import java.util.LinkedList; 
    2222import java.util.List; 
     23import java.util.Stack; 
    2324import java.util.logging.Level; 
    2425 
     
    198199        return roots; 
    199200    } 
     201     
     202    /** 
     203     * returns a traverser for the GUI model to have efficient access to the tree of GUI elements 
     204     * without having direct access. 
     205     *  
     206     * @return a traverser 
     207     */ 
     208    public Traverser getTraverser() { 
     209        return new Traverser(); 
     210    } 
    200211 
    201212    /** 
     
    226237        } 
    227238 
    228         for (IGUIElement root : getRootElements()) { 
    229             dumpGUIElement(stream, root, ""); 
     239        for (TreeNode node : root.children) { 
     240            dumpGUIElement(stream, node, ""); 
    230241        } 
    231242    } 
     
    459470     * <p> 
    460471     * dumps a GUI element to the stream. A dump contains the toString() representation of the GUI 
    461      * element as well as a indented list of its children surrounded by braces. 
     472     * element as well as a indented list of its children surrounded by braces. Therefore, not the 
     473     * GUI element itself but its tree node is provided to have an efficient access to its children 
    462474     * </p> 
    463475     *  
    464476     * @param out 
    465477     *            {@link PrintStream} where the guiElement is dumped to 
    466      * @param guiElement 
    467      *            the guiElement whos string represenation is dumped 
     478     * @param node 
     479     *            the guiElement's tree node of which the string representation is dumped 
    468480     * @param indent 
    469481     *            indent string of the dumping 
    470482     */ 
    471     private void dumpGUIElement(PrintStream out, IGUIElement guiElement, String indent) { 
     483    private void dumpGUIElement(PrintStream out, TreeNode node, String indent) { 
    472484        out.print(indent); 
    473         out.print(guiElement); 
    474  
    475         List<IGUIElement> children = getChildren(guiElement); 
    476  
    477         if ((children != null) && (children.size() > 0)) { 
     485        out.print(node.guiElement); 
     486 
     487        if ((node.children != null) && (node.children.size() > 0)) { 
    478488            out.println(" {"); 
    479489 
    480             for (IGUIElement child : children) { 
     490            for (TreeNode child : node.children) { 
    481491                dumpGUIElement(out, child, indent + "  "); 
    482492            } 
     
    523533    /** 
    524534     * <p> 
     535     * Used externally for tree traversal without providing direct access to the tree nodes 
     536     * </p> 
     537     *  
     538     * @version 1.0 
     539     * @author Patrick Harms, Steffen Herbold 
     540     */ 
     541    public class Traverser { 
     542         
     543        /** 
     544         * <p> 
     545         * the stack of nodes on which the traverser currently works 
     546         * </p> 
     547         */ 
     548        private Stack<StackEntry> nodeStack = new Stack<StackEntry>(); 
     549         
     550        /** 
     551         * <p> 
     552         * initializes the traverser by adding the root node of the GUI model to the stack 
     553         * </p> 
     554         */ 
     555        private Traverser() { 
     556            nodeStack.push(new StackEntry(root, 0)); 
     557        } 
     558         
     559        /** 
     560         * <p> 
     561         * returns the first child of the current GUI element. On the first call of this method on 
     562         * the traverser the first of the root GUI elements of the GUI model is returned. If the 
     563         * current GUI element does not have children, the method returns null. If the GUI model 
     564         * is empty, then a call to this method will return null. The returned GUI element is the 
     565         * next one the traverser points to. 
     566         * </p> 
     567         * 
     568         * @return as described. 
     569         */ 
     570        public IGUIElement firstChild() { 
     571            return pushChild(0); 
     572        } 
     573         
     574        /** 
     575         * <p> 
     576         * returns true, if the current GUI element has a first child, i.e. if the next call to the 
     577         * method {@link #firstChild()} would return a GUI element or null. 
     578         * </p> 
     579         * 
     580         * @return as described 
     581         */ 
     582        public boolean hasFirstChild() { 
     583            return 
     584                (nodeStack.peek().treeNode.children != null) && 
     585                (nodeStack.peek().treeNode.children.size() > 0); 
     586        } 
     587         
     588        /** 
     589         * <p> 
     590         * returns the next sibling of the current GUI element. If there is no further sibling, 
     591         * null is returned. If the current GUI element is one of the root nodes, the next root 
     592         * node of the GUI model is returned. The returned GUI element is the next one the 
     593         * traverser points to. 
     594         * </p> 
     595         * 
     596         * @return as described 
     597         */ 
     598        public IGUIElement nextSibling() { 
     599            int lastIndex = nodeStack.pop().index; 
     600             
     601            IGUIElement retval = pushChild(lastIndex + 1); 
     602            if (retval == null) { 
     603                pushChild(lastIndex); 
     604            } 
     605             
     606            return retval; 
     607        } 
     608         
     609        /** 
     610         * <p> 
     611         * returns true, if the current GUI element has a further sibling, i.e. if a call to the 
     612         * method {@link #nextSibling()} will return a GUI element; 
     613         * </p> 
     614         * 
     615         * @return as described 
     616         */ 
     617        public boolean hasNextSibling() { 
     618            StackEntry entry = nodeStack.pop(); 
     619            boolean result = nodeStack.peek().treeNode.children.size() > (entry.index + 1); 
     620            pushChild(entry.index); 
     621            return result; 
     622        } 
     623         
     624        /** 
     625         * <p> 
     626         * returns the parent GUI element of the current GUI element. If the current GUI element 
     627         * is a root node, null is returned. If there is no current GUI element yet as the method 
     628         * {@link #firstChild()} was not called yet, null is returned. 
     629         * </p> 
     630         * 
     631         * @return as described 
     632         */ 
     633        public IGUIElement parent() { 
     634            IGUIElement retval = null; 
     635             
     636            if (nodeStack.size() > 1) { 
     637                nodeStack.pop(); 
     638                retval = nodeStack.peek().treeNode.guiElement; 
     639            } 
     640             
     641            return retval; 
     642        } 
     643         
     644        /** 
     645         * <p> 
     646         * internal method used for changing the state of the traverser. I.e. to switch to a 
     647         * specific child GUI element of the current one. 
     648         * </p> 
     649         */ 
     650        private IGUIElement pushChild(int index) { 
     651            IGUIElement retVal = null; 
     652             
     653            if ((nodeStack.peek().treeNode.children != null) && 
     654                (nodeStack.peek().treeNode.children.size() > index)) 
     655            { 
     656                nodeStack.push 
     657                    (new StackEntry(nodeStack.peek().treeNode.children.get(index), index)); 
     658                retVal = nodeStack.peek().treeNode.guiElement; 
     659            } 
     660             
     661            return retVal; 
     662        } 
     663         
     664        /** 
     665         * <p> 
     666         * internal class needed to fill the stack with nodes of the GUI models and their 
     667         * respective index in the children of the parent node. 
     668         * </p> 
     669         */ 
     670        private class StackEntry { 
     671             
     672            /** */ 
     673            private TreeNode treeNode; 
     674             
     675            /** */ 
     676            private int index; 
     677             
     678            /** 
     679             * <p> 
     680             * creates a new stack entry. 
     681             * </p> 
     682             */ 
     683            private StackEntry(TreeNode treeNode, int index) { 
     684                this.treeNode = treeNode; 
     685                this.index = index; 
     686            } 
     687        } 
     688    } 
     689 
     690    /** 
     691     * <p> 
    525692     * Used internally for building up the tree of GUI elements. 
    526693     * </p> 
Note: See TracChangeset for help on using the changeset viewer.