RotateTransition 导致 GUI 在 javaFX 中冻结
RotateTransition causing GUI to freeze in javaFX
一般来说,在修复错误时我不会寻求帮助,但是,我有一个非常奇怪的问题,我花了 2 天时间尝试修复它但没有成功。我的 class 基本上是一个有多个难度的轮盘赌,所以我使用 pieChart 来改变难度并快速重绘轮盘赌,并使用 pieChart 附带的炫酷动画,但是,使我的轮盘赌滚动到一定程度的方法角度有一个大问题,在 RotateTransition 结束后,GUI 完全冻结。我不知道为什么,因为我在其他课程中有其他 RotateTranstions,它们工作正常,而且,如果我删除 rotateTransition 或在其中使用其他组件(我尝试使用 pieChart 的图像),它工作得很好。我不知道 pieChart 是否有一些特殊的东西使得它无法与 RotateTransition 一起使用,而且冻结的唯一例外是允许我再次下注的按钮,是的我已经尝试过“Platform.runLatter()”
@Override
public void initialize(URL url, ResourceBundle rb) {
rotateTransition = new RotateTransition();
rotateTransition.setNode(pieChart);
rotateTransition.setDuration(Duration.seconds(1));
rotateTransition.setByAngle(-360);
rotateTransition.setCycleCount(1);
rotateTransition.setAutoReverse(false);
pieChart.setData(dataForX1_5);
pieChart.setStartAngle(90);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betButton.setOnAction(eh -> {
double betMultiplier=1.5;
if(rbX1_5==group.getSelectedToggle()){
pieChart.setData(dataForX1_5);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betMultiplier=1.5;
}
if(rbX2==group.getSelectedToggle()){
pieChart.setData(dataForX2);
applyDataWithCustomColor(dataForX2, "green", "red");
betMultiplier=2;
}
if(rbX5==group.getSelectedToggle()){
pieChart.setData(dataForX5);
applyDataWithCustomColor(dataForX5, "green", "red");
betMultiplier=5;
}
if(rbX10==group.getSelectedToggle()){
pieChart.setData(dataForX10);
applyDataWithCustomColor(dataForX10, "green", "red");
betMultiplier=10;
}
if(rbX25==group.getSelectedToggle()){
pieChart.setData(dataForX25);
applyDataWithCustomColor(dataForX25, "green", "red");
betMultiplier=25;
}
if(rbX50==group.getSelectedToggle()){
pieChart.setData(dataForX50);
applyDataWithCustomColor(dataForX50, "green", "red");
betMultiplier=50;
}
try {
int betAmount = betAmountSpinner.getValue();
int spectedResult = (int) (betAmount * betMultiplier);
if (coins >= betAmount) {
dataOutputStream.writeUTF("PlaceBetOnUpgrade");
dataOutputStream.writeInt(betAmount);
dataOutputStream.writeInt(spectedResult);
if (dataInputStream.readBoolean()) {
int result = dataInputStream.readInt();
int payment = dataInputStream.readInt();
coins = coins - betAmount;
rotateTo(result, payment);
updateCoinsLabel();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
private void rotateTo(int result, int payment) {
rotateTransition.setToAngle(result * 3.60);
rotateTransition.setOnFinished(rotateEvent -> {
if (0 == payment) {
resultLabel.setText("Lost");
} else {
resultLabel.setText("Win");
coins = coins + payment;
updateCoinsLabel();
}
});
rotateTransition.play();
}
private void updateCoinsLabel() {
coinsLabel.setText(String.valueOf(coins));
}
好吧,我最终找到了问题的解决方案,这正是我说的应该去的地方。问题是,即使您可以使用 RotateTransition 在技术上旋转饼图,但您必须意识到,这样做时,您不仅在旋转屏幕上看到的饼图,而且还在旋转它后面的透明层,甚至当禁用标签和图例时,将占据最大可能尺寸的矩形形式。因此,当您旋转 pieChart 时,透明层将覆盖所有组件,导致冻结,无一例外。大多数人会推荐的解决方案只是将其设置为鼠标透明并允许点击穿透但是,它不会起作用,因为它被窃听并且只会允许点击穿透饼图而不是透明层,所以如果你想要旋转一个饼图,你需要它在屏幕的中心,所以即使它旋转到 90º 角,它也只会与屏幕外的东西重叠,所以这无关紧要。如果您需要将它放在其他地方,您需要将它的最大尺寸设置为与 Max_size 不同的值,并检查它是否永远不会重叠,但是,它肯定会限制您在高分辨率下的观看质量。
一般来说,在修复错误时我不会寻求帮助,但是,我有一个非常奇怪的问题,我花了 2 天时间尝试修复它但没有成功。我的 class 基本上是一个有多个难度的轮盘赌,所以我使用 pieChart 来改变难度并快速重绘轮盘赌,并使用 pieChart 附带的炫酷动画,但是,使我的轮盘赌滚动到一定程度的方法角度有一个大问题,在 RotateTransition 结束后,GUI 完全冻结。我不知道为什么,因为我在其他课程中有其他 RotateTranstions,它们工作正常,而且,如果我删除 rotateTransition 或在其中使用其他组件(我尝试使用 pieChart 的图像),它工作得很好。我不知道 pieChart 是否有一些特殊的东西使得它无法与 RotateTransition 一起使用,而且冻结的唯一例外是允许我再次下注的按钮,是的我已经尝试过“Platform.runLatter()”
@Override
public void initialize(URL url, ResourceBundle rb) {
rotateTransition = new RotateTransition();
rotateTransition.setNode(pieChart);
rotateTransition.setDuration(Duration.seconds(1));
rotateTransition.setByAngle(-360);
rotateTransition.setCycleCount(1);
rotateTransition.setAutoReverse(false);
pieChart.setData(dataForX1_5);
pieChart.setStartAngle(90);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betButton.setOnAction(eh -> {
double betMultiplier=1.5;
if(rbX1_5==group.getSelectedToggle()){
pieChart.setData(dataForX1_5);
applyDataWithCustomColor(dataForX1_5, "green", "red");
betMultiplier=1.5;
}
if(rbX2==group.getSelectedToggle()){
pieChart.setData(dataForX2);
applyDataWithCustomColor(dataForX2, "green", "red");
betMultiplier=2;
}
if(rbX5==group.getSelectedToggle()){
pieChart.setData(dataForX5);
applyDataWithCustomColor(dataForX5, "green", "red");
betMultiplier=5;
}
if(rbX10==group.getSelectedToggle()){
pieChart.setData(dataForX10);
applyDataWithCustomColor(dataForX10, "green", "red");
betMultiplier=10;
}
if(rbX25==group.getSelectedToggle()){
pieChart.setData(dataForX25);
applyDataWithCustomColor(dataForX25, "green", "red");
betMultiplier=25;
}
if(rbX50==group.getSelectedToggle()){
pieChart.setData(dataForX50);
applyDataWithCustomColor(dataForX50, "green", "red");
betMultiplier=50;
}
try {
int betAmount = betAmountSpinner.getValue();
int spectedResult = (int) (betAmount * betMultiplier);
if (coins >= betAmount) {
dataOutputStream.writeUTF("PlaceBetOnUpgrade");
dataOutputStream.writeInt(betAmount);
dataOutputStream.writeInt(spectedResult);
if (dataInputStream.readBoolean()) {
int result = dataInputStream.readInt();
int payment = dataInputStream.readInt();
coins = coins - betAmount;
rotateTo(result, payment);
updateCoinsLabel();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
private void rotateTo(int result, int payment) {
rotateTransition.setToAngle(result * 3.60);
rotateTransition.setOnFinished(rotateEvent -> {
if (0 == payment) {
resultLabel.setText("Lost");
} else {
resultLabel.setText("Win");
coins = coins + payment;
updateCoinsLabel();
}
});
rotateTransition.play();
}
private void updateCoinsLabel() {
coinsLabel.setText(String.valueOf(coins));
}
好吧,我最终找到了问题的解决方案,这正是我说的应该去的地方。问题是,即使您可以使用 RotateTransition 在技术上旋转饼图,但您必须意识到,这样做时,您不仅在旋转屏幕上看到的饼图,而且还在旋转它后面的透明层,甚至当禁用标签和图例时,将占据最大可能尺寸的矩形形式。因此,当您旋转 pieChart 时,透明层将覆盖所有组件,导致冻结,无一例外。大多数人会推荐的解决方案只是将其设置为鼠标透明并允许点击穿透但是,它不会起作用,因为它被窃听并且只会允许点击穿透饼图而不是透明层,所以如果你想要旋转一个饼图,你需要它在屏幕的中心,所以即使它旋转到 90º 角,它也只会与屏幕外的东西重叠,所以这无关紧要。如果您需要将它放在其他地方,您需要将它的最大尺寸设置为与 Max_size 不同的值,并检查它是否永远不会重叠,但是,它肯定会限制您在高分辨率下的观看质量。