- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一个最近学习JavaFX的初学者,我一直在尝试制作一个程序,在单击节点时在节点上执行动画。我试图看看是否有其他人尝试过类似的事情,但我无法找到与我尝试做的事情类似的案例。
时间轴对 Pane 进行动画处理,其中包含水平穿过屏幕的矩形和文本,执行完成后舞台将更改场景。当用户单击按钮返回原始场景时,按钮应该执行另一个动画。
我已经验证不是场景转换导致它停止,并且我还验证了程序确实在时间轴上执行 .play()
。时间线是在自定义监听器中执行的,因此据我所知,监听器不是问题。
这是重现我遇到的问题的代码示例,运行脚本并继续。在这里您可以看到 done
正在打印到 Main_Button_Animation.play();
下面的控制台,但是没有任何动画。
import java.util.ArrayList;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class main extends Application{
Scene scene1;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("test");
Main_Screen MainScreen = new Main_Screen(800, 480);
scene1 = MainScreen.MainScreen(primaryStage);
MainScreen.getInitiater().Calibration_Listener(() -> {
MainScreen.getInitiater().Back_Button_Pressed();
});
primaryStage.setScene(scene1);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
//custom listeners
interface Calibration {
void menu();
}
interface Back {
void back();
}
class Initiater {
private List<Calibration> calilist = new ArrayList<Calibration>();;
private List<Back> Go_Back = new ArrayList<Back>();
public void Calibration_Listener(Calibration toAdd) {
calilist.add(toAdd);
}
public void Back_Listener(Back toAdd) {
Go_Back.add(toAdd);
}
public void Calibration_Pressed() {
System.out.println("Calibration Pressed");
for (Calibration hl : calilist)
hl.menu();
}
public void Back_Button_Pressed() {
System.out.println("Back Pressed");
for (Back hl : Go_Back)
hl.back();
}
}
//animations and setup
class Main_Screen {
Initiater initiater;
private int X;
private int Y;
public Main_Screen(int X, int Y) {
this.initiater = new Initiater();
this.X = X;
this.Y = Y;
}
private Pane UI_Button(String name, int[] pos, int[] size, Color color) {
final Text text = new Text(0, 0, name);
text.setFont(new Font(20));
final Rectangle outline = new Rectangle(0, 0, size[0], size[1]);
outline.setFill(color);
final StackPane stack = new StackPane();
stack.getChildren().addAll(outline, text);
stack.setLayoutX(pos[0]);
stack.setLayoutY(pos[1]);
return stack;
}
public int getX() {
return this.X;
}
public int getY() {
return this.Y;
}
public Initiater getInitiater() {
return this.initiater;
}
public Scene MainScreen(Stage stage) {
Scene scene = new Scene(new Group(), getX(), getY());
scene.setFill(Color.WHITE);
Pane Start = UI_Button("Start", new int[] { getX() - getX() / 4, 0 }, new int[] { getX() / 4, getY() / 4 }, Color.rgb(255, 0, 0));
Pane Calibration = UI_Button("Callibration", new int[] { 0, ((getY() + (getY() / 8)) / 4) * 0 }, new int[] { getX() / 2, getY() / 4 }, Color.rgb(60, 208, 230));
System.out.println(Calibration.boundsInLocalProperty());
((Group) scene.getRoot()).getChildren().addAll(Calibration, Start);
final Timeline Main_Button_Animation = new Timeline();
final KeyFrame Cali_kf = new KeyFrame(Duration.millis(500), new KeyValue(Calibration.translateXProperty(), getX() / 2));
final KeyFrame Start_kf = new KeyFrame(Duration.millis(500), new KeyValue(Start.translateXProperty(), -getX() / 4));
Main_Button_Animation.getKeyFrames().addAll(Cali_kf, Start_kf);
Main_Button_Animation.setRate(-1);
Main_Button_Animation.jumpTo(Main_Button_Animation.getTotalDuration());
Main_Button_Animation.play();
Calibration.setOnMouseClicked(MouseEvent -> {
Calibration.setDisable(true);
Start.setDisable(true);
System.out.println(Calibration.boundsInLocalProperty());
Main_Button_Animation.setRate(1);
Main_Button_Animation.jumpTo(Duration.millis(0));
Main_Button_Animation.play();
Main_Button_Animation.setOnFinished(event -> {
Main_Button_Animation.play();
System.out.println("done");
});
});
return scene;
}
}
Edit1:为了清楚起见,上面的示例没有使用任何场景转换。这是一个场景转换的示例。
import java.util.ArrayList;
import java.util.List;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class main extends Application{
Scene scene1, scene2;
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("test");
Main_Screen MainScreen = new Main_Screen(800, 480);
scene1 = MainScreen.MainScreen(primaryStage);
MainScreen.getInitiater().Calibration_Listener(() -> {
primaryStage.setScene(scene2);
primaryStage.show();
});
Label label2 = new Label("This is the second scene");
Button button2 = new Button("Go to scene 1");
button2.setOnAction(e -> {
MainScreen.getInitiater().Back_Button_Pressed();
primaryStage.setScene(scene1);
primaryStage.show();
});
VBox layout2 = new VBox(20);
layout2.getChildren().addAll(label2, button2);
scene2 = new Scene(layout2, 800, 480);
primaryStage.setScene(scene1);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
//custom listeners
interface Calibration {
void menu();
}
interface Back {
void back();
}
class Initiater {
private List<Calibration> calilist = new ArrayList<Calibration>();;
private List<Back> Go_Back = new ArrayList<Back>();
public void Calibration_Listener(Calibration toAdd) {
calilist.add(toAdd);
}
public void Back_Listener(Back toAdd) {
Go_Back.add(toAdd);
}
public void Calibration_Pressed() {
System.out.println("Calibration Pressed");
for (Calibration hl : calilist)
hl.menu();
}
public void Back_Button_Pressed() {
System.out.println("Back Pressed");
for (Back hl : Go_Back)
hl.back();
}
}
//animations and setup
class Main_Screen {
Initiater initiater;
private int X;
private int Y;
public Main_Screen(int X, int Y) {
this.initiater = new Initiater();
this.X = X;
this.Y = Y;
}
private Pane UI_Button(String name, int[] pos, int[] size, Color color) {
final Text text = new Text(0, 0, name);
text.setFont(new Font(20));
final Rectangle outline = new Rectangle(0, 0, size[0], size[1]);
outline.setFill(color);
final StackPane stack = new StackPane();
stack.getChildren().addAll(outline, text);
stack.setLayoutX(pos[0]);
stack.setLayoutY(pos[1]);
return stack;
}
public int getX() {
return this.X;
}
public int getY() {
return this.Y;
}
public Initiater getInitiater() {
return this.initiater;
}
public Scene MainScreen(Stage stage) {
Scene scene = new Scene(new Group(), getX(), getY());
scene.setFill(Color.WHITE);
Pane Start = UI_Button("Start", new int[] { getX() - getX() / 4, 0 }, new int[] { getX() / 4, getY() / 4 }, Color.rgb(255, 0, 0));
Pane Calibration = UI_Button("Callibration", new int[] { 0, ((getY() + (getY() / 8)) / 4) * 0 }, new int[] { getX() / 2, getY() / 4 }, Color.rgb(60, 208, 230));
System.out.println(Calibration.boundsInLocalProperty());
((Group) scene.getRoot()).getChildren().addAll(Calibration, Start);
final Timeline Main_Button_Animation = new Timeline();
final KeyFrame Cali_kf = new KeyFrame(Duration.millis(500), new KeyValue(Calibration.translateXProperty(), getX() / 2));
final KeyFrame Start_kf = new KeyFrame(Duration.millis(500), new KeyValue(Start.translateXProperty(), -getX() / 4));
Main_Button_Animation.getKeyFrames().addAll(Cali_kf, Start_kf);
Main_Button_Animation.setRate(-1);
Main_Button_Animation.jumpTo(Main_Button_Animation.getTotalDuration());
Main_Button_Animation.play();
Calibration.setOnMouseClicked(MouseEvent -> {
Calibration.setDisable(true);
Start.setDisable(true);
System.out.println(Calibration.boundsInLocalProperty());
Main_Button_Animation.setRate(1);
Main_Button_Animation.jumpTo(Duration.millis(0));
Main_Button_Animation.play();
Main_Button_Animation.setOnFinished(event -> {
this.initiater.Calibration_Pressed();
System.out.println("done");
});
});
this.initiater.Back_Listener(() -> {
Main_Button_Animation.setRate(-1);
Main_Button_Animation.jumpTo(Main_Button_Animation.getTotalDuration());
Main_Button_Animation.play();
Main_Button_Animation.setOnFinished(e -> {
Calibration.setDisable(false);
Start.setDisable(false);
});
});
return scene;
}
}
最佳答案
您只需为 Timeline
动画末尾的帧定义 KeyValue
。这只允许时间轴在动画开始时的值和目标值之间进行插值。在动画开头插入另一个 KeyFrame
应该可以解决此问题:
public Scene MainScreen(Stage stage) {
final Group root = new Group();
Scene scene = new Scene(root, getX(), getY());
scene.setFill(Color.WHITE);
Pane Start = UI_Button("Start", new int[] { getX() * 3 / 4, 0 }, new int[] { getX() / 4, getY() / 4 }, Color.RED);
Pane Calibration = UI_Button("Callibration", new int[] { 0, 0 }, new int[] { getX() / 2, getY() / 4 }, Color.rgb(60, 208, 230));
System.out.println(Calibration.boundsInLocalProperty());
root.getChildren().addAll(Calibration, Start);
final Timeline Main_Button_Animation = new Timeline(
new KeyFrame(Duration.ZERO,
new KeyValue(Calibration.translateXProperty(), 0),
new KeyValue(Start.translateXProperty(), 0)),
new KeyFrame(Duration.millis(500),
new KeyValue(Calibration.translateXProperty(), getX() / 2),
new KeyValue(Start.translateXProperty(), -getX() / 4)));
Main_Button_Animation.setRate(-1);
Main_Button_Animation.playFrom(Main_Button_Animation.getTotalDuration());
Calibration.setOnMouseClicked(MouseEvent -> {
Calibration.setDisable(true);
Start.setDisable(true);
System.out.println(Calibration.boundsInLocalProperty());
Main_Button_Animation.playFromStart();
Main_Button_Animation.setOnFinished(event -> {
this.initiater.Calibration_Pressed();
System.out.println("done");
});
});
this.initiater.Back_Listener(() -> {
Main_Button_Animation.setRate(-1);
Main_Button_Animation.playFrom(Main_Button_Animation.getTotalDuration());
Main_Button_Animation.setOnFinished(e -> {
Calibration.setDisable(false);
Start.setDisable(false);
});
});
return scene;
}
请注意,这里有一些额外的更改:
KeyFrame
组合为具有多个 KeyValue
的单个帧playFrom
和 playFromStart
代替 jumpTo
/play
UI_Button
方法的一些参数(但四舍五入可能会使结果相差 1)关于Javafx 时间线在经过多个监听器时停止播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54544107/
当单击复选框(或选择所有复选框)时,我想向 CheckboxSelectionModel 添加一个监听器。 var smSensors = new xg.CheckboxSelectionModel(
我有一个简单的程序,允许 2 个客户端连接到服务器。 连接后,他们可以轮流点击空白卡片图像。 一旦 2 个客户中的任何一个点击空白卡片图片,卡片图片将变为 Ace 俱乐部图片。 更改将显示在客户端的两
我在这里看到了一个代码,该代码以字符串的形式检索鼠标的当前图标,但是此代码使用了TTimer来实现。 因此,我想知道是否存在某些事件(侦听器)来检测鼠标光标图标上的这些更改。 下面是使用TTimer的
我想在我的配置对象上获得一个 onload 事件。 以下工作,除非我创建一个 config.listeners={..} (我认为这就是我需要的?)替换 this.onload({...}); 我什至
通常,在 Java 中,当我有一个向其他对象提供某种通知的对象时,我将使用 Listener/Observer 模式。 有没有更类似于 Scala 的方式来做到这一点?我应该在 Scala 中使用这种
我有一个带有动画器的游戏对象和一些可以触发事件的动画(具有特定的回调函数)。 只要我将脚本添加到与动画器相同的游戏对象(包括接收器),一切都会正常工作: public class AnimatorEv
我有一个带有监听器的 DialogFragment,用于单击按钮以调用 fragment 中的函数。 我收到 lateinit property listener has not been initi
这个问题已经有答案了: Java ActionListener error: incompatible types (4 个回答) 已关闭 5 年前。 我最近刚刚开始学习 Java 代码。我在添加监听
我的代码遇到问题。我想知道是否有一种更简单的方法来使用监听器,而不是不断地这样做: example.addActionListener(new java.awt.event.ActionListene
有没有办法使用 .net 创建控制台应用程序。或通过某个端口监听 SMTP 消息的服务? 我需要创建一个中间层对象来捕获和处理 smtp 消息。也就是说,我希望该监听器发送和接收 smtp 消息,然后
我有一个带有动画器的游戏对象和一些可以触发事件的动画(具有特定的回调函数)。 只要我将脚本添加到与动画器相同的游戏对象(包括接收器),一切都会正常工作: public class AnimatorEv
我有许多向主事件生成服务注册的监听器。然而,我想告诉听众,事件流在某个时刻将会结束。您会通过简单地调用监听器上的方法(例如 finish())来完成此操作,还是有一个单独的事件方法 streamFin
我的代码有什么问题。 我创建了一个 JList,添加了项目并将其推到左侧(BorderLayout.WEST)。每次单击列表项时,我希望在列表右侧显示一个面板。但问题是,当选择列表项并运行监听器时,到
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
这可能是一个简单的问题,但我没有看到它。 我有一个界面 public interface RenderableListener{ public void update(T element);
有人可以直接指出我的正确方向吗?当从组合框中选择适当的选项时,我希望小程序中的 Action 监听器显示从 html 文件检索的 jlabel 中的 3 个参数之一。 干杯 最佳答案 对于组合框,您需
我有一个网站,每个页面上都有许多 jQuery 事件处理程序,所有这些都在一个大型 .js 文件中。 这意味着对于任何页面,大多数事件处理程序都是针对不存在且根本不会使用的 HTML。 这会影响我的表
我有一些 jQuery 监听器设置,用于监听 type="text" 字段上的表单输入。但是,当用户从自动完成下拉框中选择一个选项(即他们之前输入的值已被记住以供将来使用)时,下面的监听器不会收集该值
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我正在用 unity (c#) 做一个类似国际象棋的游戏,但我在尝试进行向上转换以将信息从一个 child 发送到另一个抽象类时遇到了困难。 基本上,我有一个抽象类,它有一个带有函数的事件/委托(de
我是一名优秀的程序员,十分优秀!