📄 sortingarrayanimator.java
字号:
* 实际交换这两处的视图,那么 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 + -