├── .idea ├── artifacts │ └── JavaFXTest_jar.xml ├── compiler.xml ├── description.html ├── encodings.xml ├── gradle.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── vcs.xml ├── JavaFXTest.iml ├── META-INF └── MANIFEST.MF ├── README.md ├── bobblesort.gif ├── out.png ├── sortcompare.gif ├── src ├── META-INF │ └── MANIFEST.MF └── sample │ ├── BTREE │ ├── B+Tree.html │ ├── B-Tree.html │ └── Controller │ │ ├── Algorithm.js │ │ ├── AnimatedBTreeNode.js │ │ ├── AnimatedCircle.js │ │ ├── AnimatedLabel.js │ │ ├── AnimatedLinkedList.js │ │ ├── AnimatedObject.js │ │ ├── AnimatedRectangle.js │ │ ├── AnimationMain.js │ │ ├── BPlusTree.js │ │ ├── BTree.js │ │ ├── CustomEvents.js │ │ ├── HighlightCircle.js │ │ ├── Line.js │ │ ├── ObjectManager.js │ │ ├── UndoFunctions.js │ │ ├── jquery-1.5.2.min.js │ │ ├── jquery-ui-1.8.11.custom.css │ │ ├── jquery-ui-1.8.11.custom.min.js │ │ └── visualizationPageStyle.css │ ├── DataProcess │ ├── BTest.java │ ├── BTree.java │ └── dataProcess.java │ ├── DemoTest │ ├── BarChartSample.java │ ├── Input.java │ ├── databar.css │ ├── input.fxml │ └── label.css │ ├── GraphViz │ ├── CreateGraph.java │ ├── Graphviz.java │ ├── Settings.java │ ├── bean.java │ ├── setting.properties │ ├── settings.fxml │ └── showSettings.java │ ├── Graphics2DTest │ ├── GMain.java │ ├── graphics2DTest.java │ └── graphicsTest.java │ ├── HeapSort │ ├── Code.java │ ├── HeapNode.java │ ├── HeapSort.java │ ├── Main.java │ ├── heapsort.fxml │ ├── inputNode.java │ └── newThread.java │ ├── JavaFXUI │ ├── MainUI.java │ ├── mainUI.fxml │ ├── out.png │ └── showImage.java │ ├── Main.java │ ├── MazeBFS │ ├── AlgoFrame.java │ ├── AlgoVisHelper.java │ ├── AlgoVisualizer.java │ ├── MazeData.java │ └── Position.java │ ├── MazeDFS │ ├── AlgoFrame.java │ ├── AlgoVisHelper.java │ ├── AlgoVisualizer.java │ └── MazeData.java │ ├── MazePath │ ├── Maze.java │ ├── maze.fxml │ ├── maze_101_101.txt │ ├── maze_30_30.txt │ └── maze_50_101.txt │ ├── MenuItemEvent │ ├── GYBRJ │ │ └── about.html │ ├── SJGJS │ │ ├── BT.html │ │ ├── BTree.html │ │ ├── Gnjs.java │ │ ├── HFMT.html │ │ ├── REDBLACKT.html │ │ ├── SDBSF.html │ │ ├── gnjs.fxml │ │ └── sdgn.html │ ├── images │ │ ├── sdbsf-hzbsf.PNG │ │ ├── sdbsf-hzxd1.PNG │ │ ├── sdbsf-hzxd2.PNG │ │ ├── sdbsf-sqbsf.PNG │ │ ├── sdgn.PNG │ │ └── 二叉树.jpg │ └── styles │ │ └── style.css │ ├── Robot │ ├── InputRobot.java │ ├── Main.java │ ├── Rectangle.java │ ├── Robot.java │ ├── inputRobot.fxml │ └── paintRobot.java │ ├── SearchBT │ ├── HeapNode.java │ ├── Main.java │ ├── dataProcess.java │ ├── newThread.java │ └── searchBT.java │ ├── SortCompare │ ├── SortCompare.java │ ├── databar.css │ ├── sortCompare.fxml │ ├── sortCompareUI.java │ └── sortResult.java │ ├── SortCreate │ ├── bubbleSort.java │ ├── heapSort.java │ ├── insertSort.java │ ├── mergeSort.java │ ├── quickSort.java │ ├── redixSort.java │ ├── selectSort.java │ └── shellSort.java │ ├── inputTree │ ├── Defaultui.java │ ├── Inputbtree.java │ ├── Searchtree.java │ ├── defaultui.fxml │ ├── inputbtree.fxml │ └── searchtree.fxml │ └── start.java └── tree.gif /.idea/artifacts/JavaFXTest_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/JavaFXTest_jar 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/description.html: -------------------------------------------------------------------------------- 1 | Simple JavaFX 2.0 application that includes simple .fxml file with attached controller and Main class to quick start. Artifact to build JavaFX application is provided. 2 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /JavaFXTest.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JavaFXTest 2 | JavaFX,树,排序算法可视化 3 | 4 | 使用的Java第三方库GraphViz实现二叉树等静态可视化 5 | 6 | 使用JavaFX中的BarChart以及Timeline实现排序算法动态可视化 7 | 8 | 未完待续... 9 | 10 | 部分实现结果如下 11 | 12 | 二叉树的静态可视化: 13 | 14 | ![Image text](https://github.com/fanghuiX/JavaFXTest/blob/master/tree.gif) 15 | 16 | 冒泡排序可视化: 17 | 18 | ![Image text](https://github.com/fanghuiX/JavaFXTest/blob/master/bobblesort.gif) 19 | 20 | 排序算法比较可视化: 21 | 22 | 23 | ![Image text](https://github.com/fanghuiX/JavaFXTest/blob/master/sortcompare.gif) -------------------------------------------------------------------------------- /bobblesort.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanghuiX/JavaFXTest/8756557954e5bc9ce9670715a7577bc9553eaa76/bobblesort.gif -------------------------------------------------------------------------------- /out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanghuiX/JavaFXTest/8756557954e5bc9ce9670715a7577bc9553eaa76/out.png -------------------------------------------------------------------------------- /sortcompare.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fanghuiX/JavaFXTest/8756557954e5bc9ce9670715a7577bc9553eaa76/sortcompare.gif -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: sample.JavaFXUI.Main 3 | 4 | -------------------------------------------------------------------------------- /src/sample/BTREE/B+Tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | B+ Tree Visualization 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | 45 |
46 | 47 |
48 | 49 | 50 |
51 |
52 | 53 | 54 | 55 | 56 | 57 |
58 | 59 | 60 |
61 |
62 | 63 |
64 | 65 |
66 | 67 | 68 |
-------------------------------------------------------------------------------- /src/sample/BTREE/B-Tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | B-Tree Visualization 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
42 | 43 | 44 |
45 | 46 |
47 | 48 | 49 |
50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
59 | 60 | 61 |
62 |
63 | 64 |
65 | 66 | 67 |
68 | 69 | 70 |
-------------------------------------------------------------------------------- /src/sample/BTREE/Controller/AnimatedCircle.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | var AnimatedCircle = function(objectID, objectLabel) 5 | { 6 | this.objectID = objectID; 7 | this.label = objectLabel; 8 | this.radius = 20; 9 | this.thickness = 3; 10 | this.x = 0; 11 | this.y = 0; 12 | this.alpha = 1.0; 13 | this.addedToScene = true; 14 | this.highlightIndex = -1; 15 | /* this.foregroundColor = '#007700'; 16 | this.backgroundColor = '#EEFFEE'; 17 | */ 18 | } 19 | 20 | AnimatedCircle.prototype = new AnimatedObject(); 21 | AnimatedCircle.prototype.constructor = AnimatedCircle; 22 | 23 | AnimatedCircle.prototype.getTailPointerAttachPos = function(fromX, fromY, anchorPoint) 24 | { 25 | return this.getHeadPointerAttachPos(fromX, fromY); 26 | } 27 | 28 | 29 | AnimatedCircle.prototype.getWidth = function() 30 | { 31 | return this.radius * 2; 32 | } 33 | 34 | AnimatedObject.prototype.setWidth = function(newWidth) 35 | { 36 | this.radius = newWidth / 2; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | AnimatedCircle.prototype.getHeadPointerAttachPos = function(fromX, fromY) 44 | { 45 | var xVec = fromX - this.x; 46 | var yVec = fromY - this.y; 47 | var len = Math.sqrt(xVec * xVec + yVec*yVec); 48 | if (len == 0) 49 | { 50 | return [this.x, this.y]; 51 | } 52 | return [this.x+(xVec/len)*(this.radius), this.y +(yVec/len)*(this.radius)]; 53 | } 54 | 55 | 56 | AnimatedCircle.prototype.setHighlightIndex = function(hlIndex) 57 | { 58 | this.highlightIndex = hlIndex; 59 | this.highlightIndexDirty = true; 60 | 61 | } 62 | 63 | AnimatedCircle.prototype.draw = function(ctx) 64 | { 65 | ctx.globalAlpha = this.alpha; 66 | 67 | if (this.highlighted) 68 | { 69 | ctx.fillStyle = "#ff0000"; 70 | ctx.beginPath(); 71 | ctx.arc(this.x,this.y,this.radius + this.highlightDiff,0,Math.PI*2, true); 72 | ctx.closePath(); 73 | ctx.fill(); 74 | } 75 | 76 | 77 | ctx.fillStyle = this.backgroundColor; 78 | ctx.strokeStyle = this.foregroundColor; 79 | ctx.lineWidth = 1; 80 | ctx.beginPath(); 81 | ctx.arc(this.x,this.y,this.radius,0,Math.PI*2, true); 82 | ctx.closePath(); 83 | ctx.fill(); 84 | ctx.stroke(); 85 | ctx.textAlign = 'center'; 86 | ctx.font = '10px sans-serif'; 87 | ctx.textBaseline = 'middle'; 88 | ctx.lineWidth = 1; 89 | ctx.fillStyle = this.foregroundColor; 90 | 91 | var strList = this.label.split("\n"); 92 | if (strList.length == 1) 93 | { 94 | if (this.highlightIndexDirty && this.highlightIndex != -1) 95 | { 96 | this.leftWidth = ctx.measureText(this.label.substring(0,this.highlightIndex)).width; 97 | this.centerWidth = ctx.measureText(this.label.substring(this.highlightIndex, this.highlightIndex+1)).width; 98 | this.textWidth = ctx.measureText(this.label).width; 99 | this.highlightIndexDirty = false; 100 | } 101 | if (this.highlightIndex != -1 && this.highlightIndex < this.label.length) //this.highlghtIndex < this.label.length) 102 | { 103 | var startingXForHighlight = this.x - this.textWidth / 2; 104 | ctx.textAlign = 'left'; 105 | var leftStr = this.label.substring(0, this.highlightIndex); 106 | var highlightStr = this.label.substring(this.highlightIndex, this.highlightIndex + 1) 107 | var rightStr = this.label.substring(this.highlightIndex + 1) 108 | ctx.fillText(leftStr, startingXForHighlight, this.y) 109 | ctx.strokeStyle = "#FF0000"; 110 | ctx.fillStyle = "#FF0000"; 111 | ctx.fillText(highlightStr, startingXForHighlight + this.leftWidth, this.y) 112 | 113 | 114 | ctx.strokeStyle = this.labelColor; 115 | ctx.fillStyle = this.labelColor; 116 | ctx.fillText(rightStr, startingXForHighlight + this.leftWidth + this.centerWidth, this.y) 117 | 118 | 119 | 120 | } 121 | else 122 | { 123 | ctx.fillText(this.label, this.x, this.y); 124 | } 125 | } 126 | else if (strList.length % 2 == 0) 127 | { 128 | var i; 129 | var mid = strList.length / 2; 130 | for (i = 0; i < strList.length / 2; i++) 131 | { 132 | ctx.fillText(strList[mid - i - 1], this.x, this.y - (i + 0.5) * 12); 133 | ctx.fillText(strList[mid + i], this.x, this.y + (i + 0.5) * 12); 134 | 135 | } 136 | } 137 | else 138 | { 139 | var mid = (strList.length - 1) / 2; 140 | var i; 141 | ctx.fillText(strList[mid], this.x, this.y); 142 | for (i = 0; i < mid; i++) 143 | { 144 | ctx.fillText(strList[mid - (i + 1)], this.x, this.y - (i + 1) * 12); 145 | ctx.fillText(strList[mid + (i + 1)], this.x, this.y + (i + 1) * 12); 146 | } 147 | 148 | } 149 | 150 | } 151 | 152 | 153 | AnimatedCircle.prototype.createUndoDelete = function() 154 | { 155 | return new UndoDeleteCircle(this.objectID, this.label, this.x, this.y, this.foregroundColor, this.backgroundColor, this.layer, this.radius); 156 | } 157 | 158 | 159 | function UndoDeleteCircle(id, lab, x, y, foregroundColor, backgroundColor, l, radius) 160 | { 161 | this.objectID = id; 162 | this.posX = x; 163 | this.posY = y; 164 | this.nodeLabel = lab; 165 | this.fgColor = foregroundColor; 166 | this.bgColor = backgroundColor; 167 | this.layer = l; 168 | this.radius = radius; 169 | } 170 | 171 | UndoDeleteCircle.prototype = new UndoBlock(); 172 | UndoDeleteCircle.prototype.constructor = UndoDeleteCircle; 173 | 174 | UndoDeleteCircle.prototype.undoInitialStep = function(world) 175 | { 176 | world.addCircleObject(this.objectID, this.nodeLabel); 177 | world.setWidth(this.objectID, this.radius * 2); 178 | world.setNodePosition(this.objectID, this.posX, this.posY); 179 | world.setForegroundColor(this.objectID, this.fgColor); 180 | world.setBackgroundColor(this.objectID, this.bgColor); 181 | world.setLayer(this.objectID, this.layer); 182 | } 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /src/sample/BTREE/Controller/AnimatedObject.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function AnimatedObject() 4 | { 5 | this.init(); 6 | } 7 | 8 | AnimatedObject.prototype.init = function() 9 | { 10 | this.backgroundColor = "#FFFFFF"; 11 | this.foregroundColor = "#000000"; 12 | this.highlighted = false; 13 | this.objectID = -1; 14 | this.layer = 0; 15 | this.addedToScene = true; 16 | this.label = ""; 17 | this.labelColor = "#000000"; 18 | this.alpha = 1.0; 19 | this.x = 0; 20 | this.y = 0; 21 | this.minHeightDiff = 3; 22 | this.range = 5; 23 | this.highlightIndex = -1; 24 | this.highlightIndexDirty = true; 25 | } 26 | 27 | AnimatedObject.prototype.alwaysOnTop = false; 28 | 29 | AnimatedObject.prototype.setBackgroundColor = function(newColor) 30 | { 31 | this.backgroundColor = newColor; 32 | } 33 | 34 | AnimatedObject.prototype.setForegroundColor = function(newColor) 35 | { 36 | this.foregroundColor = newColor; 37 | } 38 | 39 | AnimatedObject.prototype.setNull = function() 40 | { 41 | 42 | } 43 | 44 | AnimatedObject.prototype.getNull = function() 45 | { 46 | return false; 47 | } 48 | 49 | AnimatedObject.prototype.setAlpha = function(newAlpha) 50 | { 51 | this.alpha = newAlpha; 52 | } 53 | 54 | AnimatedObject.prototype.getAlpha = function() 55 | { 56 | return this.alpha; 57 | } 58 | 59 | AnimatedObject.prototype.setForegroundColor = function(newColor) 60 | { 61 | this.foregroundColor = newColor; 62 | this.labelColor = newColor; 63 | } 64 | 65 | 66 | AnimatedObject.prototype.getHighlight = function() 67 | { 68 | return this.highlighted; 69 | } 70 | 71 | AnimatedObject.prototype.getWidth = function() 72 | { 73 | // TODO: Do we want to throw here? Should always override this ... 74 | return 0; 75 | } 76 | 77 | AnimatedObject.prototype.getHeight = function() 78 | { 79 | // TODO: Do we want to throw here? Should always override this ... 80 | return 0; 81 | } 82 | 83 | AnimatedObject.prototype.setHighlight = function(value) 84 | { 85 | this.highlighted = value; 86 | } 87 | 88 | AnimatedObject.prototype.centerX = function() 89 | { 90 | return this.x; 91 | } 92 | 93 | AnimatedObject.prototype.setWidth = function(newWidth) 94 | { 95 | // TODO: Do we want to throw here? Should always override this ... 96 | } 97 | 98 | 99 | 100 | AnimatedObject.prototype.centerY = function() 101 | { 102 | return this.y; 103 | } 104 | 105 | 106 | AnimatedObject.prototype.getAlignLeftPos = function(otherObject) 107 | { 108 | return [otherObject.right()+ this.getWidth() / 2, otherObject.centerY()]; 109 | } 110 | 111 | AnimatedObject.prototype.getAlignRightPos = function(otherObject) 112 | { 113 | 114 | return [otherObject.left() - this.getWidth() / 2, otherObject.centerY()]; 115 | } 116 | 117 | AnimatedObject.prototype.getAlignTopPos = function(otherObject) 118 | { 119 | 120 | return [otherObject.centerX(), otherObject.top() - this.getHeight() / 2]; 121 | } 122 | AnimatedObject.prototype.getAlignBottomPos = function(otherObject) 123 | { 124 | return [otherObject.centerX(), otherObject.bottom() + this.getHeight() / 2]; 125 | } 126 | 127 | 128 | AnimatedObject.prototype.alignLeft = function(otherObject) 129 | { 130 | // Assuming centering. Overridden method could modify if not centered 131 | // (See AnimatedLabel, for instance) 132 | this.y = otherObject.centerY(); 133 | this.x = otherObject.right() + this.getWidth() / 2; 134 | } 135 | 136 | AnimatedObject.prototype.alignRight = function(otherObject) 137 | { 138 | // Assuming centering. Overridden method could modify if not centered 139 | // (See AnimatedLabel, for instance) 140 | this.y = otherObject.centerY(); 141 | this.x = otherObject.left() - this.getWidth() / 2; 142 | } 143 | 144 | 145 | AnimatedObject.prototype.alignTop = function(otherObject) 146 | { 147 | // Assuming centering. Overridden method could modify if not centered 148 | 149 | this.x = otherObject.centerX(); 150 | this.y = otherObject.top() - this.getHeight() / 2; 151 | 152 | 153 | } 154 | 155 | 156 | AnimatedObject.prototype.alignBottom = function(otherObject) 157 | { 158 | this.x = otherObject.centerX(); 159 | this.y = otherObject.bottom() + this.getHeight() / 2; 160 | 161 | } 162 | 163 | 164 | 165 | /* TODO: Do we need these in the base? 166 | function left(): Number 167 | { 168 | return x - getWidth() / 2; 169 | } 170 | 171 | function right():Number 172 | { 173 | return x + getWidth() / 2; 174 | } 175 | 176 | function top():Number 177 | { 178 | return y - getHeight() / 2; 179 | } 180 | 181 | function bottom():Number 182 | { 183 | return y + getHeight() / 2; 184 | } 185 | 186 | function centerX():Number 187 | { 188 | return x; 189 | } 190 | 191 | function centerY():Number 192 | { 193 | return y; 194 | } 195 | */ 196 | 197 | 198 | AnimatedObject.prototype.getClosestCardinalPoint = function(fromX, fromY) 199 | { 200 | var xDelta; 201 | var yDelta; 202 | var xPos; 203 | var yPos; 204 | 205 | if (fromX < this.left()) 206 | { 207 | xDelta = this.left() - fromX; 208 | xPos = this.left(); 209 | } 210 | else if (fromX > this.right()) 211 | { 212 | xDelta = fromX - this.right(); 213 | xPos = this.right(); 214 | } 215 | else 216 | { 217 | xDelta = 0; 218 | xPos = this.centerX(); 219 | } 220 | 221 | if (fromY < this.top()) 222 | { 223 | yDelta = this.top() - fromY; 224 | yPos = this.top(); 225 | } 226 | else if (fromY > this.bottom()) 227 | { 228 | yDelta = fromY - this.bottom(); 229 | yPos = this.bottom(); 230 | } 231 | else 232 | { 233 | yDelta = 0; 234 | yPos = this.centerY(); 235 | } 236 | 237 | if (yDelta > xDelta) 238 | { 239 | xPos = this.centerX(); 240 | } 241 | else 242 | { 243 | yPos = this.centerY(); 244 | } 245 | 246 | return [xPos, yPos]; 247 | } 248 | 249 | 250 | AnimatedObject.prototype.centered = function() 251 | { 252 | return false; 253 | } 254 | 255 | 256 | AnimatedObject.prototype.pulseHighlight = function(frameNum) 257 | { 258 | if (this.highlighted) 259 | { 260 | var frameMod = frameNum / 7.0; 261 | var delta = Math.abs((frameMod) % (2 * this.range - 2) - this.range + 1) 262 | this.highlightDiff = delta + this.minHeightDiff; 263 | } 264 | 265 | } 266 | 267 | AnimatedObject.prototype.getTailPointerAttachPos = function(fromX, fromY, anchorPoint) 268 | { 269 | return [this.x, this.y]; 270 | } 271 | 272 | 273 | AnimatedObject.prototype.getHeadPointerAttachPos = function(fromX, fromY) 274 | { 275 | return [this.x, this.y]; 276 | } 277 | 278 | /*public function createUndoDelete() : UndoBlock 279 | { 280 | // Must be overriden! 281 | return null; 282 | } 283 | */ 284 | AnimatedObject.prototype.identifier = function() 285 | { 286 | return this.objectID; 287 | } 288 | 289 | AnimatedObject.prototype.getText = function(index) 290 | { 291 | return this.label; 292 | } 293 | 294 | AnimatedObject.prototype.getTextColor = function(textIndex) 295 | { 296 | return this.labelColor 297 | } 298 | 299 | AnimatedObject.prototype.setTextColor = function(color, textIndex) 300 | { 301 | this.labelColor = color; 302 | } 303 | 304 | AnimatedObject.prototype.setText = function(newText, textIndex) 305 | { 306 | this.label = newText; 307 | } 308 | 309 | AnimatedObject.prototype.setHighlightIndex = function(hlIndex) 310 | { 311 | this.highlightIndex = hlIndex; 312 | this.highlightIndexDirty = true; 313 | } 314 | 315 | 316 | AnimatedObject.prototype.getHighlightIndex = function() 317 | { 318 | return this.highlightIndex; 319 | } 320 | -------------------------------------------------------------------------------- /src/sample/BTREE/Controller/CustomEvents.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Function.prototype.bind = function() { 5 | var _function = this; 6 | 7 | var args = Array.prototype.slice.call(arguments); 8 | var scope = args.shift() 9 | return function() { 10 | for (var i = 0; i < arguments.length; i++) 11 | { 12 | args.push(arguments[i]); 13 | } 14 | return _function.apply(scope, args); 15 | } 16 | } 17 | 18 | function EventListener() 19 | { 20 | this.events = []; 21 | } 22 | 23 | 24 | EventListener.prototype.removeListener = function(kind, scope, func) 25 | { 26 | if (this.events[kind] == undefined) 27 | { 28 | return; 29 | } 30 | var scopeFunctions = null; 31 | var i; 32 | for (i = 0; i < this.events[kind].length; i++) 33 | { 34 | if (this.events[kind][i].scope == scope) 35 | { 36 | scopeFunctions = this.events[kind][i]; 37 | break; 38 | } 39 | } 40 | if (scopeFunctions == null) 41 | { 42 | return; 43 | } 44 | for (i = 0; i < scopeFunctions.functions.length; i++) 45 | { 46 | if (scopeFunctions.functions[i] == func) 47 | { 48 | scopeFunctions.functions.splice(i,1); 49 | return; 50 | } 51 | } 52 | } 53 | 54 | 55 | EventListener.prototype.addListener = function(kind, scope, func) 56 | { 57 | if (this.events[kind] === undefined) 58 | { 59 | this.events[kind] = []; 60 | } 61 | var i; 62 | var scopeFunctions = null; 63 | for (i = 0; i < this.events[kind].length; i++) 64 | { 65 | if (this.events[kind][i].scope == scope) 66 | { 67 | scopeFunctions = this.events[kind][i]; 68 | break; 69 | } 70 | } 71 | if (scopeFunctions === null) 72 | { 73 | this.events[kind].push({scope:scope, functions:[] }); 74 | scopeFunctions = this.events[kind][this.events[kind].length - 1]; 75 | } 76 | for (i = 0; i < scopeFunctions.functions.length; i++) 77 | { 78 | if (scopeFunctions.functions[i] == func) 79 | { 80 | return; 81 | } 82 | } 83 | scopeFunctions.functions.push(func); 84 | } 85 | 86 | EventListener.prototype.fireEvent = function(kind, event) 87 | { 88 | // TODO: Should add a deep clone here ... 89 | if (this.events[kind] !== undefined) 90 | { 91 | for (var i = 0; i < this.events[kind].length; i++) 92 | { 93 | var objects = this.events[kind][i]; 94 | var functs = objects.functions; 95 | var scope = objects.scope 96 | for (var j = 0; j 0) 71 | { 72 | return 1; 73 | } 74 | else 75 | { 76 | return -1; 77 | } 78 | } 79 | 80 | 81 | this.drawArrow = function(pensize, color, context) 82 | { 83 | context.strokeStyle = color; 84 | context.fillStyle = color; 85 | context.lineWidth = pensize; 86 | var fromPos = this.Node1.getTailPointerAttachPos(this.Node2.x, this.Node2.y, this.anchorPoint); 87 | var toPos = this.Node2.getHeadPointerAttachPos(this.Node1.x, this.Node1.y); 88 | 89 | var fromPos = this.Node1.getTailPointerAttachPos(this.Node2.x, this.Node2.y, this.anchorPoint); 90 | var toPos = this.Node2.getHeadPointerAttachPos(this.Node1.x, this.Node1.y); 91 | 92 | var deltaX = toPos[0] - fromPos[0]; 93 | var deltaY = toPos[1] - fromPos[1]; 94 | var midX = (deltaX) / 2.0 + fromPos[0]; 95 | var midY = (deltaY) / 2.0 + fromPos[1]; 96 | var controlX = midX - deltaY * this.curve; 97 | 98 | var controlY = midY + deltaX * this.curve; 99 | 100 | context.beginPath(); 101 | context.moveTo(fromPos[0], fromPos[1]); 102 | context.quadraticCurveTo(controlX, controlY, toPos[0], toPos[1]); 103 | context.stroke(); 104 | //context.closePath(); 105 | 106 | // Position of the edge label: First, we will place it right along the 107 | // middle of the curve (or the middle of the line, for curve == 0) 108 | var labelPosX = 0.25* fromPos[0] + 0.5*controlX + 0.25*toPos[0]; 109 | var labelPosY = 0.25* fromPos[1] + 0.5*controlY + 0.25*toPos[1]; 110 | 111 | // Next, we push the edge position label out just a little in the direction of 112 | // the curve, so that the label doesn't intersect the cuve (as long as the label 113 | // is only a few characters, that is) 114 | var midLen = Math.sqrt(deltaY*deltaY + deltaX*deltaX); 115 | if (midLen != 0) 116 | { 117 | labelPosX += (- deltaY * this.sign(this.curve)) / midLen * 10 118 | labelPosY += ( deltaX * this.sign(this.curve)) / midLen * 10 119 | } 120 | 121 | 122 | 123 | context.textAlign = 'center'; 124 | context.font = '10px sans-serif'; 125 | context.textBaseline = 'middle'; 126 | context.fillText(this.edgeLabel, labelPosX, labelPosY); 127 | 128 | if (this.directed) 129 | { 130 | var xVec = controlX - toPos[0]; 131 | var yVec = controlY - toPos[1]; 132 | var len = Math.sqrt(xVec * xVec + yVec*yVec); 133 | 134 | if (len > 0) 135 | { 136 | xVec = xVec / len 137 | yVec = yVec / len; 138 | 139 | context.beginPath(); 140 | context.moveTo(toPos[0], toPos[1]); 141 | context.lineTo(toPos[0] + xVec*this.arrowHeight - yVec*this.arrowWidth, toPos[1] + yVec*this.arrowHeight + xVec*this.arrowWidth); 142 | context.lineTo(toPos[0] + xVec*this.arrowHeight + yVec*this.arrowWidth, toPos[1] + yVec*this.arrowHeight - xVec*this.arrowWidth); 143 | context.lineTo(toPos[0], toPos[1]); 144 | context.closePath(); 145 | context.stroke(); 146 | context.fill(); 147 | } 148 | 149 | } 150 | 151 | } 152 | 153 | 154 | this.draw = function(ctx) 155 | { 156 | if (!this.addedToScene) 157 | { 158 | return; 159 | } 160 | ctx.globalAlpha = this.alpha; 161 | 162 | if (this.highlighted) 163 | this.drawArrow(this.highlightDiff, "#FF0000", ctx); 164 | this.drawArrow(1, this.edgeColor, ctx); 165 | } 166 | 167 | 168 | } 169 | 170 | 171 | 172 | function UndoConnect(from, to, createConnection, edgeColor, isDirected, cv, lab, anch) 173 | { 174 | this.fromID = from; 175 | this.toID = to; 176 | this.connect = createConnection; 177 | this.color = edgeColor; 178 | this.directed = isDirected; 179 | this.curve = cv; 180 | this.edgeLabel = lab; 181 | this.anchorPoint = anch; 182 | } 183 | 184 | 185 | UndoConnect.prototype.undoInitialStep = function(world) 186 | { 187 | if (this.connect) 188 | { 189 | world.connectEdge(this.fromID, this.toID, this.color, this.curve, this.directed, this.edgeLabel,this.anchorPoint); 190 | } 191 | else 192 | { 193 | world.disconnect(this.fromID,this.toID); 194 | } 195 | } 196 | 197 | 198 | UndoConnect.prototype.addUndoAnimation = function(animationList) 199 | { 200 | return false; 201 | } 202 | -------------------------------------------------------------------------------- /src/sample/BTREE/Controller/visualizationPageStyle.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | 4 | body { 5 | font: 100% Verdana, Arial, Helvetica, sans-serif; 6 | /*background: #666666; */ 7 | margin: 0; /* it's good practice to zero the margin and padding of the body element to account for differing browser defaults */ 8 | padding: 0; 9 | text-align: center; /* this centers the container in IE 5* browsers. The text is then set to the left aligned default in the #container selector */ 10 | color: #000000; 11 | } 12 | 13 | 14 | 15 | 16 | .VisualizationMainPage #mainContent { 17 | /*padding: 0 20px; /* remember that padding is the space inside the div box and margin is the space outside the div box */ 18 | background: #FFFFFF; 19 | } 20 | 21 | 22 | 23 | .VisualizationMainPage #container { 24 | 25 | 26 | background: #FFFFFF; 27 | /*margin: 0 auto; /* the auto margins (in conjunction with a width) center the page */ 28 | text-align: left; /* this overrides the text-align: center on the body element. */ 29 | } 30 | 31 | 32 | .VisualizationMainPage #algoControlSection 33 | { 34 | background: #DDEEDD; 35 | color:#000000; 36 | 37 | } 38 | 39 | 40 | .VisualizationMainPage #generalAnimationControlSection 41 | { 42 | background: #DDEEDD; 43 | color:#006600; 44 | 45 | } 46 | 47 | .VisualizationMainPage #header { 48 | background: #006633; 49 | color:#ffCC33; 50 | padding: 0 10px 0 20px; 51 | 52 | } 53 | 54 | .VisualizationMainPage #header A:visited 55 | { text-decoration:none; 56 | color:#ffCC33; 57 | } 58 | 59 | 60 | .VisualizationMainPage #header h1 { 61 | margin: 0; 62 | padding: 10px 0; 63 | } 64 | 65 | .VisualizationMainPage #header A:link { 66 | text-decoration:none; 67 | color:#ffCC33; 68 | } 69 | 70 | 71 | .VisualizationMainPage #container { 72 | background: #FFFFFF; 73 | margin: 0 auto; /* the auto margins (in conjunction with a width) center the page */ 74 | text-align: left; /* this overrides the text-align: center on the body element. */ 75 | } 76 | 77 | 78 | .VisualizationMainPage #footer A:visited { text-decoration:none; 79 | color:ffcc33; 80 | } 81 | 82 | .VisualizationMainPage #footer A:link { 83 | text-decoration:none; 84 | color:#ffCC33; 85 | } 86 | 87 | 88 | 89 | 90 | .VisualizationMainPage #mainContent h1{ 91 | padding: 0 20px; 92 | background: #FFFFFF; 93 | color:#006633 94 | } 95 | 96 | .VisualizationMainPage #mainContent h2{ 97 | padding: 0 20px; 98 | background: #FFFFFF; 99 | color:#006633 100 | } 101 | 102 | .VisualizationMainPage #mainContent h3{ 103 | padding: 0 20px; 104 | background: #FFFFFF; 105 | color:#006633 106 | } 107 | 108 | 109 | 110 | .VisualizationMainPage #footer { 111 | padding: 0 10px; 112 | background: #006633; 113 | color:#ffcc33; 114 | } 115 | .VisualizationMainPage #footer p { 116 | margin: 0; padding: 10px 0; 117 | } 118 | 119 | EM {text-decoration: bold;} 120 | 121 | 122 | -------------------------------------------------------------------------------- /src/sample/DataProcess/BTest.java: -------------------------------------------------------------------------------- 1 | package sample.DataProcess; 2 | 3 | public class BTest { 4 | /*public static void main(String[] args){ 5 | //"ABCDE#FG#####HI" 6 | String str = "ABCDE#FG#####HI"; 7 | String string1[] = dataProcess.getSTNodesvalue(str); 8 | String string2[] = dataProcess.getCom(str); 9 | String string3[] = dataProcess.getPre(str,"pre"); 10 | String string4[] = dataProcess.getPost(str,"pre"); 11 | for(int i=0;i datas; 12 | ArrayList prelist = new ArrayList(); 13 | ArrayList inlist = new ArrayList(); 14 | ArrayList postlist = new ArrayList(); 15 | public BTree(Object obj){ 16 | this.val = obj; 17 | } 18 | public BTree getRoot(){ 19 | return this.root; 20 | } 21 | //创建二叉树 22 | public void CreateTree(Object[] objs){ 23 | datas = new ArrayList(); 24 | for(Object obj : objs){ 25 | datas.add(new BTree(obj)); 26 | } 27 | root = datas.get(0); 28 | for(int i=0;i result,int[] num,String str,String time) { 29 | StringBuffer inidata = new StringBuffer(); 30 | for(int i=0;i() { 62 | @Override 63 | public void handle(javafx.event.ActionEvent event) { 64 | speed = speed/2; 65 | System.out.println(speed); 66 | } 67 | }); 68 | Button slow = new Button("减速"); 69 | slow.setPrefWidth(80); 70 | slow.setPrefHeight(30); 71 | slow.setLayoutX(400); 72 | slow.setLayoutY(610); 73 | slow.setOnAction(new EventHandler() { 74 | @Override 75 | public void handle(javafx.event.ActionEvent event) { 76 | speed += 500; 77 | System.out.println(speed); 78 | } 79 | }); 80 | //设置label的属性 81 | ArrayList