Javafx:将矩形形状与锯切数组元素交换
我正在使用JavaFx进行排序算法模拟。在对数组元素进行排序时,我想显示Javafx:将矩形形状与锯切数组元素交换,javafx,Javafx,我正在使用JavaFx进行排序算法模拟。在对数组元素进行排序时,我想显示Rectangles的交换。但是有一个问题是,矩形随机移动,并且没有按照我尝试的PathTransition数组元素排序的顺序进行。如果我尝试使用TranslateTransition,当我翻译y时,在翻译x之后,圆圈跟随对角线。为什么会发生这种情况?我还尝试将文本单独添加到矩形中,但失败了。代码如下: PathTransition pathtransition1; PathTransition pathtransition
Rectangle
s的交换。但是有一个问题是,矩形随机移动,并且没有按照我尝试的PathTransition
数组元素排序的顺序进行。如果我尝试使用TranslateTransition
,当我翻译y时,在翻译x之后,圆圈跟随对角线。为什么会发生这种情况?我还尝试将文本单独添加到矩形中,但失败了。代码如下:
PathTransition pathtransition1;
PathTransition pathtransition2;
@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
int[] a = {5, 8, 0, 3, 1};
Text[] text = new Text[5];
Rectangle[] rect = new Rectangle[5];
for (int i = 0; i < 5; i++) {
rect[i] = new Rectangle(100 * i, 300, 40, 40);
rect[i].setArcHeight(10);
rect[i].setArcWidth(10);
rect[i].setFill(Color.ORANGE);
text[i] = new Text(Integer.toString(a[i]));
text[i].setFont(Font.font("VERDANA", FontWeight.BOLD, 12));
root.getChildren().addAll(rect[i], text[i]);
}
// Selection Sort
int min;
for (int i = 0; i < a.length; i++) {
min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[j] < a[min]) {
min = j;
}
}
if (min != i) {
int temp = a[i];
a[i] = a[min];
a[min] = temp;
swap1(rect[i], 60, (int) rect[min].getX());
swap2(rect[min], 60, (int) rect[i].getX());
Rectangle temporary = rect[i];
rect[i] = rect[min];
rect[min] = temporary;
}
System.out.println(a[i]);
}
Scene scene = new Scene(root, 800, 600);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
void swap1(Rectangle rect, int d, int sx) {
Path path1 = new Path(new MoveTo(rect.getX(), rect.getY()),
new LineTo(rect.getX(), rect.getY() - d),
new MoveTo(rect.getX(), rect.getY() - d),
new LineTo(sx, rect.getY() - d),
new MoveTo(sx, rect.getY() - d),
new LineTo(sx, rect.getY())
);
pathtransition1 = new PathTransition(seconds(1), path1, rect);
pathtransition1.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathtransition1.setCycleCount(1);
pathtransition1.setAutoReverse(false);
pathtransition1.play();
}
void swap2(Rectangle rect, int d, int sx) {
Path path2 = new Path(new MoveTo(rect.getX(), rect.getY()),
new LineTo(rect.getX(), rect.getY() + d),
new MoveTo(rect.getX(), rect.getY() + d),
new LineTo(sx, rect.getY() + d),
new MoveTo(sx, rect.getY() + d),
new LineTo(sx, rect.getY())
);
pathtransition2 = new PathTransition(seconds(4), path2, rect);
pathtransition2.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pathtransition2.setCycleCount(1);
pathtransition2.setAutoReverse(false);
pathtransition2.play();
}
路径转换路径转换1;
路径转换路径转换2;
@凌驾
公共无效开始(阶段primaryStage){
窗格根=新窗格();
int[]a={5,8,0,3,1};
Text[]Text=新文本[5];
矩形[]矩形=新矩形[5];
对于(int i=0;i<5;i++){
rect[i]=新矩形(100*i,300,40,40);
rect[i].setArcHeight(10);
rect[i].setArcWidth(10);
rect[i].setFill(Color.ORANGE);
text[i]=新文本(Integer.toString(a[i]);
text[i].setFont(Font.Font(“VERDANA”,fontwweight.BOLD,12));
root.getChildren().addAll(rect[i],text[i]);
}
//选择排序
int-min;
for(int i=0;i
出了什么问题以及如何修复它
rect.setX(rect.getX() + rect.getTranslateX());
rect.setY(rect.getY() + rect.getTranslateY());
rect.setTranslateX(0);
rect.setTranslateY(0);
1
和8
的元素处于交换转换过程中:
更新的样本代码
import javafx.animation.PathTransition;
import javafx.application.*;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class Sorter extends Application {
final Pane root = new Pane();
final PathTransition[] pathtransition = new PathTransition[2];
final Lock lock = new ReentrantLock();
final Condition[] swapComplete = { lock.newCondition(), lock.newCondition() };
final int[] data = {5, 8, 0, 3, 1};
@Override
public void start(Stage stage) {
Label[] labels = createLabels(data);
root.getChildren().addAll(labels);
root.setStyle("-fx-background-color: oldlace;");
Scene scene = new Scene(root, 600, 250);
stage.setScene(scene);
stage.show();
sort(data, labels);
}
private void sort(int[] a, Label[] rect) {
// Selection Sort
Thread thread = new Thread(
() -> {
int min;
for (int i = 0; i < a.length; i++) {
min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[j] < a[min]) {
min = j;
}
}
if (min != i) {
int temp = a[i];
a[i] = a[min];
a[min] = temp;
final int finalMin = min;
final int finalI = i;
FutureTask<Void> future = new FutureTask<>(
() -> {
swap(
0,
rect[finalI],
60,
rect[finalMin].getLayoutX() - rect[finalI].getLayoutX(),
Duration.seconds(1)
);
swap(
1,
rect[finalMin],
-60,
rect[finalI].getLayoutX() - rect[finalMin].getLayoutX(),
Duration.seconds(4)
);
return null;
}
);
lock.lock();
try {
Platform.runLater(future);
future.get();
for (Condition condition: swapComplete) {
condition.await();
}
} catch (InterruptedException e) {
Thread.interrupted();
break;
} catch (ExecutionException e) {
e.printStackTrace();
break;
} finally {
lock.unlock();
}
Label temporary = rect[i];
rect[i] = rect[min];
rect[min] = temporary;
}
System.out.println(a[i]);
}
}
);
thread.setDaemon(true);
thread.start();
}
private Label[] createLabels(int[] a) {
Label[] rect = new Label[a.length];
for (int i = 0; i < a.length; i++) {
createLabel(i, a, rect);
}
return rect;
}
private void createLabel(int i, int[] a, Label[] rect) {
rect[i] = new Label(Integer.toString(a[i]));
rect[i].setMinSize(40, 40);
rect[i].setMaxSize(40, 40);
rect[i].setAlignment(Pos.CENTER);
rect[i].setStyle(
"-fx-background-radius: 10; " +
"-fx-background-color: orange; " +
"-fx-font-family: Verdana; " +
"-fx-font-size: 12pt; " +
"-fx-font-weight: bold;"
);
rect[i].relocate(100 * i + 80, 100);
}
void swap(int transitionIdx, Region node, double dy, double dx, Duration duration) {
double cx = node.getWidth() / 2;
double cy = node.getHeight() / 2;
Path path1 = new Path(
new MoveTo(cx, cy),
new LineTo(cx, cy + dy),
new LineTo(dx + cx, cy + dy),
new LineTo(dx + cx, cy)
);
pathtransition[transitionIdx] = new PathTransition(duration, path1, node);
pathtransition[transitionIdx].setOnFinished(event -> {
node.setLayoutX(node.getLayoutX() + node.getTranslateX());
node.setLayoutY(node.getLayoutY() + node.getTranslateY());
node.setTranslateX(0);
node.setTranslateY(0);
lock.lock();
try {
swapComplete[transitionIdx].signal();
} finally {
lock.unlock();
}
});
pathtransition[transitionIdx].play();
}
public static void main(String[] args) {
launch(args);
}
}
导入javafx.animation.PathTransition;
导入javafx.application.*;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.layout.*;
导入javafx.scene.shape.*;
导入javafx.stage.stage;
导入javafx.util.Duration;
导入java.util.concurrent.*;
导入java.util.concurrent.locks.*;
公共类分类器扩展应用{
最终窗格根=新窗格();
最终路径转换[]路径转换=新路径转换[2];
最终锁定=新的可重入锁定();
最终条件[]swapComplete={lock.newCondition(),lock.newCondition()};
final int[]data={5,8,0,3,1};
@凌驾
公众假期开始(阶段){
标签[]标签=创建标签(数据);
root.getChildren().addAll(标签);
root.setStyle(“-fx背景色:oldlace;”);
场景=新场景(root,600250);
舞台场景;
stage.show();
分类(数据、标签);
}
私有void排序(int[]a,Label[]rect){
//选择排序
螺纹=ne
private static class AnimationElements {
private final PathTransition transition;
private final MoveTo start;
private final LineTo horizontalMove;
public AnimationElements(double height) {
this.start = new MoveTo();
this.horizontalMove = new LineTo();
horizontalMove.setAbsolute(false);
LineTo l1 = new LineTo(0, height);
l1.setAbsolute(false);
LineTo l2 = new LineTo(0, -height);
l2.setAbsolute(false);
this.transition = new PathTransition(Duration.seconds(4), new Path(start, l1, horizontalMove, l2));
}
public void init(Node movedNode, Node moveEnd) {
// init animation according to positions of the Nodes to move
double sx = movedNode.getTranslateX();
double dx = moveEnd.getTranslateX() - sx;
start.setX(sx + movedNode.getLayoutBounds().getWidth() / 2);
start.setY(movedNode.getTranslateY() + movedNode.getLayoutBounds().getHeight() / 2);
horizontalMove.setX(dx/*+movedNode.getLayoutBounds().getWidth()/2*/);
transition.setNode(movedNode);
}
public PathTransition getTransition() {
return transition;
}
}
private static class Swap {
private final int index1;
private final int index2;
public Swap(int index1, int index2) {
this.index1 = index1;
this.index2 = index2;
}
public void init(AnimationElements animation1, AnimationElements animation2, Node[] sortNodes) {
// initialize both positions
Node n1 = sortNodes[index1];
Node n2 = sortNodes[index2];
animation1.init(n1, n2);
animation2.init(n2, n1);
// swap order to be correct for the next swap
sortNodes[index2] = n1;
sortNodes[index1] = n2;
}
}
@Override
public void start(Stage primaryStage) {
// create list of swaps to execute; could be generated by sorting algorithm
List<Swap> swaps = Arrays.asList(new Swap(0, 1), new Swap(1, 2), new Swap(3, 4), new Swap(0, 4));
AnimationElements animationElements1 = new AnimationElements(100);
AnimationElements animationElements2 = new AnimationElements(-100);
// both swap animations happen simultaniously
ParallelTransition animation = new ParallelTransition(animationElements1.getTransition(), animationElements2.getTransition());
Color[] colors = new Color[]{
Color.RED,
Color.BLUE,
Color.LIME,
Color.YELLOW,
Color.ORANGE
};
Node[] nodes = new Node[5];
for (int i = 0; i < nodes.length; i++) {
Rectangle rect = new Rectangle(100, 20, colors[i]);
rect.setTranslateY(200);
rect.setTranslateX(i * 100);
nodes[i] = rect;
}
Iterator<Swap> iterator = swaps.iterator();
animation.setOnFinished(evt -> {
if (iterator.hasNext()) {
// continue with next swap
iterator.next().init(animationElements1, animationElements2, nodes);
animation.play();
}
});
if (iterator.hasNext()) {
// execute first swap
iterator.next().init(animationElements1, animationElements2, nodes);
animation.play();
}
Pane root = new Pane(nodes);
Scene scene = new Scene(root, 500, 400);
primaryStage.setScene(scene);
primaryStage.show();
}