【发布时间】:2018-08-13 06:05:20
【问题描述】:
前言: 所以我有了这个,好吧,应用程序是什么并不那么重要,它是一个 tcp 侦听器,它整天与一些硬件聊天。但它也有一些显示的东西。显示屏在屏幕的不同区域显示不同的自定义节点,屏幕底部是一个显示一些“东西”的网格,但当没有任何“东西”时,它会在屏幕上滚动一些文本。
问题: 正如我将在构建时间线的方法中发布的那样,有一个 Text 元素在屏幕上从右到左转换。这在前一小时或两小时内按预期工作,但一段时间后它变得越来越紧张。 TCP 侦听器仍然很敏捷,它产生的线程进出控制器和更改 UI 没有任何问题,但滚动文本在它显示的 55 英寸屏幕上一次跳跃 2 英寸。我真的需要一种方法来让文本平滑滚动,就像我第一次无限期启动应用程序时那样。
private void buildChyron() throws IllegalArgumentException {
setMessages();
LowerGrid.getChildren().clear();
StringBuilder txtstr = new StringBuilder();
for (String s : messages) {
txtstr.append(s).append(" ");
}
txtstr = new StringBuilder(txtstr.toString().trim());
Text msg = new Text(txtstr.toString());
LowerGrid.add(msg, 0, 0);
msg.setTextOrigin(VPos.TOP);
msg.setFont(Font.font("Veranda", FontWeight.BOLD, 150));
double sceneWidth = MainGrid.getWidth();
double msgWidth = msg.getLayoutBounds().getWidth();
KeyValue initKeyValue = new KeyValue(msg.translateXProperty(), sceneWidth);
KeyFrame initFrame = new KeyFrame(Duration.ZERO, initKeyValue);
KeyValue endKeyValue = new KeyValue(msg.translateXProperty(), -1.0 * msgWidth);
KeyFrame endFrame = new KeyFrame(Duration.seconds((msgWidth + sceneWidth) / messageRate), endKeyValue);
if ((timeline != null) && (timeline.getStatus().equals(Timeline.Status.PAUSED))) {
timeline.playFromStart();
} else {
timeline = new Timeline(initFrame, endFrame);
timeline.setCycleCount(Timeline.INDEFINITE);
if (msgIndex == messages.size() - 1) msgIndex = 0;
else msgIndex++;
timeline.playFromStart();
}
}
这是我调用这个东西的地方,你可以看到我一直在尝试尝试它,认为这可能是硬件资源问题,但我无法控制它。我现在正在测试这个东西,它在我所在的设施中非常显眼。超级尴尬
private void updateStack() {
int count = 0;
System.out.println(andonStack);
andonStack.sortStack();
LowerGrid.getChildren().clear();
if (pokeyStack.size() > 0) {
AndonPane pane = new AndonPane(pokeyStack.get(0).getPokayo());
LowerGrid.add(pane, 0, 0, 9, 1);
} else {
int i;
for (i = 0; i < andonStack.size(); i++) {
if (i >= 9) break;
panes[i] = new AndonPane(((AndonSignalStack.AndonSignal) andonStack.get(i)).getType(),
((AndonSignalStack.AndonSignal) andonStack.get(i)).getStation(), this);
count++;
}
for (; i < 9; i++) {
panes[i] = new Pane();
panes[i].setStyle("-fx-background-color: rgba(0,0,0, 0)");
panes[i].setPrefWidth(MainGrid.getWidth() * (9 - i) / 9);
}
for (i = 0; i < count; i++) {
LowerGrid.add(panes[i], i, 0);
}
if (i == 0) {
Platform.runLater(this::buildChyron);
}else{
if (timeline != null) {
System.gc();
timeline.stop();
timeline = null;
}
}
}
}
【问题讨论】:
-
documentation for
Timeline有一个明确的警告:“警告:正在从 FX 运行时引用正在运行的时间线。如果不正确停止无限时间线,可能会导致内存泄漏。所有具有动画属性的对象不会被垃圾收集。”。在我看来,您肯定在做被警告的事情(即 - 不停止运行时间线)。 -
所以我想我真正的问题是:你如何停止一个不确定的时间线。如果只是调用 stop() 方法是不对的
-
在
buildChyron中,如果timeline不为空但未暂停,您不会停止它,而是创建一个新的,因此引用丢失(来自您的代码)并且它永远不会停止。我怀疑如果您确保在创建新的Timeline之前始终停止旧的Timeline,您的问题就会消失。 -
万一其他人最终发现了这个...时间线.setOnFinished(ev -> buildChyron());
标签: java animation javafx lag timeline