⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sortingarrayanimator.java

📁 用JAVA实现排序等简单算法的演示
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * 实际交换这两处的视图,那么 firstIndex 处视图的坐标位置就不等于 firstIndex * (元素视图宽度 + 元素之间间隔),也就是说,从屏幕展示
	 * 效果看, firstIndex 处试图并不是第 firstIndex 个矩形条,那么在后面的演示势必造成混乱。进行实际交换的目的就是为了保持 firstIndex 
	 * 处视图在屏幕上就是第 firstIndex 个矩形条。 
	 */
	public void swapElementView(int firstIndex, int secondIndex) {
		int firstData = arrayView.getElementValue(firstIndex);
		int secondData = arrayView.getElementValue(secondIndex);
		arrayView.setElementValue(firstIndex, secondData);
		arrayView.setElementValue(secondIndex, firstData);
		Point firstPos = arrayView.getElementPosition(firstIndex);
		Point secondPos = arrayView.getElementPosition(secondIndex);
		arrayView.moveElementTo(firstIndex, secondPos);
		arrayView.moveElementTo(secondIndex, firstPos);

		arrayView.setElementColor(firstIndex, dataColor);
		arrayView.setElementColor(secondIndex, dataColor);
	}
	
	/**
	 * 创建将数组元素 fromIndex 处的元素移动到 toIndex 处的动画,动画创建完毕之后交给绘制器的动画驱动器
	 * 一起运行,以便多个演示器的动画同步运作。因为我们是使用移动的目标视图(即 toIndex 处的视图)来执行
	 * 动画,因此运行动画之后无需做任何后续的处理事情。
	 */
	public void createMoveElementAnimation(int fromIndex, int toIndex) {
		AnimationPath path;
		if (Math.abs(fromIndex - toIndex) <= 1) {
			 path = createMoveElementPath(fromIndex, toIndex, 0);
		} else path = createMoveElementPath(fromIndex, toIndex, 50);

		// 将目标 toIndex 处的模型设置为与 fromIndex 处的模型一样,然后利用该模型进行
		// 动画演示,这样可使得在演示之后不用恢复 fromIndex 处的模型。
		arrayView.moveElementTo(toIndex, arrayView.getElementPosition(fromIndex));
		arrayView.setElementValue(toIndex, arrayView.getElementValue(fromIndex));
		arrayView.setElementColor(toIndex, dataColor);
		arrayView.showElement(toIndex);
		
		// 因为toIndex 处的模型已经在 fromIndex 处,因此隐藏原来的模型,使得移动 toIndex 
		// 处的模型之后,fromIndex 处可留下一个空位。
		arrayView.hideElement(fromIndex);
		
		Animation animation = new Animation(this, arrayView.getElementAnimationView(toIndex));
		animation.setPath(path);
		animationManager.add(animation);
	}
	
	/**
	 * 创建选中元素与 index 处元素交换的动画,动画创建完毕之后交给绘制器的动画驱动器运行,同样运行完动画
	 * 之后,需要调用下面的 swapElementView() 以实际交换这两个视图
	 */
	public void createSwapSelectedAnimation(int index) {
		if (selectedIndex < 0) return;

		arrayView.setElementColor(index, swapColor);
		
		AnimationPath firstPath = createMoveElementPath(selectedIndex, index, 50);
		AnimationPath secondPath = createMoveElementPath(index, selectedIndex, 50);

		Animation firstAnimation = new Animation(this, arrayView.getElementAnimationView(selectedIndex));
		Animation secondAnimation = new Animation(this, arrayView.getElementAnimationView(index));
		
		firstAnimation.setPath(firstPath);
		secondAnimation.setPath(secondPath);
		
		animationManager.add(firstAnimation);
		animationManager.add(secondAnimation);
	}
	
	/**
	 * 实际交换被选中元素与 index 处元素的视图,以保证每个视图在屏幕上正确的显示位置
	 * @param index
	 */
	public void swapElementView(int index) {
		swapElementView(selectedIndex, index);
	}
	
	/**
	 * 改变正在比较的两个数组元素的颜色值,然后驱动视图在屏幕上作相应的修改,从而展示两个正在比
	 * 较的数组元素。与方法 showCompareView() 基本相同,只是这时参与比较的一个元素是正被选中的元素,
	 * 因此使用正被选中的颜色值进行显示。
	 */
	public void showCompareSelectedScene(int index) {
		if (selectedIndex < 0) return;

		// 假定选中的元素已经设置了正确的颜色,因此这里就不再对选中的元素设置颜色
		arrayView.setElementColor(index, compareColor);
		update();
		sleep(stepDelay);
		arrayView.setElementColor(index, dataColor);
		update();
	}

	/**
	 * 设置正被选中的元素的颜色值,然后驱动视图在屏幕上作相应的修改,从而使用特别的颜色展示正被选中的元素
	 */
	public void showSelectScene(int index) {
		// 将原先选中的元素恢复成正常的颜色值
		if (selectedIndex >= 0) arrayView.setElementColor(selectedIndex, dataColor);
		// 记录新的被选中的元素的下标及整数数值
		selectedIndex = index;
		selectedData = arrayView.getElementValue(selectedIndex);
		selectedPos = arrayView.getElementPosition(selectedIndex);
		// 设置其为正被选中的颜色
		arrayView.setElementColor(selectedIndex, selectColor);
		update();
	}

	/**
	 * 创建防止将被选中的元素到 index 处的动画,动画创建完之后交给绘制器的动画驱动器运行。同样因为我们是使
	 * 用放置目标的视图(即 index 处的视图)来执行动画,因此运行动画之后无需做任何后续的处理事情。
	 */
	public void createPlaceAnimation(int index) {

		// 先利用 index 处的位置生成动画路径
		AnimationPath path;
		path = createPlaceSelectedPath(index, 50);

		// 注意,selectedIndex 处的元素(即selectedData)及其模型可能已经被改变(例如调用 move() 进行
		// 元素移动时覆盖了选中元素的模型),因此下面利用放置的目标元素的模型来重建 selectedData 的
		// 模型,这是合理的,因为放置的目标元素模型最终要被覆盖。
		arrayView.setElementColor(index, selectColor);
		arrayView.setElementValue(index, selectedData);
		arrayView.moveElementTo(index, selectedPos);
		arrayView.showElement(index);		// 目标位置处的元素通常已经被隐藏了,所以这里重新显示。

		Animation animation = new Animation(this, arrayView.getElementAnimationView(index));
		animation.setPath(path);
		animationManager.add(animation);
	}
	
	/**
	 * 创建将 fromIndex 处的视图移动到 toIndex 处视图的动画路径,该动画路径是先将这个视图向上移动 vDistance
	 * 个像素,然后水平移动到目标,再向下移动 vDistance 个像素。
	 * @return 返回所创建的动画路径
	 */
	public AnimationPath createMoveElementPath(int fromIndex, int toIndex, int vDistance) {
		AnimationPath path = new AnimationPath();

		Point startPos = arrayView.getElementPosition(fromIndex);
		Point endPos = arrayView.getElementPosition(toIndex);
		
		path.addStartPoint(startPos);
		if (vDistance > 0) path.moveUp(vDistance, unitMoving);
		int distance = endPos.x - startPos.x;
		if (distance > 0) path.moveRight(distance, unitMoving);
		else path.moveLeft(-distance, unitMoving);
		
		if (vDistance > 0) path.moveDown(vDistance, unitMoving);
		
		return path;
	}
	
	public AnimationPath createPlaceSelectedPath(int index, int vDistance) {
		AnimationPath path = new AnimationPath();

		Point endPos = arrayView.getElementPosition(index);
		
		path.addStartPoint(selectedPos);
		if (vDistance > 0) path.moveUp(vDistance, unitMoving);
		int distance = endPos.x - selectedPos.x;
		if (distance > 0) path.moveRight(distance, unitMoving);
		else path.moveLeft(-distance, unitMoving);
		
		if (vDistance > 0) path.moveDown(vDistance, unitMoving);
		
		return path;
	}
	
	/**
	 * 将 index 处的元素使用正常的颜色(即dataColor)显示
	 */
	public void showNormalColor(int index) {
		arrayView.setElementColor(index, dataColor);
		update();
	}
	/**
	 * 将 firstIndex 和 secondIndex 处的元素使用正常的颜色(即dataColor)显示
	 */
	public void showNormalColor(int firstIndex, int secondIndex) {
		arrayView.setElementColor(firstIndex, dataColor);
		arrayView.setElementColor(secondIndex, dataColor);
		update();
	}
	
	/**
	 * 显示正在排序的数组范围,这主要用于快速排序和合并排序这一类使用递归实现的排序
	 * 算法,可让用户清楚正在递归排序的范围
	 * @param startIndex 起始下标
	 * @param endIndex 终止下标
	 */
	public void showSortingScope(int startIndex, int endIndex) {
		((IntArrayStickAnimationView)arrayView).setShowScope(true);
		((IntArrayStickAnimationView)arrayView).setFocusScope(startIndex, endIndex);
	}
	
	/** 
	 * 显示排序时的基准线,即以 index 处的矩形条的高度为基准,在正排序的数组范围内在画
	 * 一条水平线,从而可比较正在排序范围内的矩形条高度,这主要是用于快速排序,帮助用户
	 * 认识划分点的确定
	 */
	public void showBaseLine(int index) {
		((IntArrayStickAnimationView)arrayView).setBaseLineElement(index);
	}
	
	/**
	 * 绘制该演示器管理的视图
	 */
	public void paint(Graphics gc) {
		if (!visible) return;
		arrayView.paint(gc);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -