Preface: So I have this, well its not really all that important what the application is, it's a tcp listener that chats it up all day with some hardware. But it's also got some display stuff going on. The display shows different custom nodes in different areas of the screen and at the bottom of the screen is a grid that displays some "stuff" but when there isn't any "stuff" it scrolls some text across the screen.
Question: As I will post in my method that builds the timeline, there is a Text element that transitions from right to left across the screen. This is working as expected for the first hour or maybe two, but after a while it becomes progressively more jittery. The TCP listener is still snappy and the threads it spawns don't have any trouble going in and out of the controller and changing the UI but that scrolling text is jumping like 2 inches at a time across the 55" screen it is displaying on. I really need a way to get text to scroll smoothly like it does when I first start up the application for an indefinite amount of time.
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();
}
}
Here is where I call the thing from, as you can see I've been trying to experiment with it thinking maybe it was a hardware resources issue, but I haven't been able to get it under control. I'm testing the thing now and it's in a super visible position in the facility I am at. Super embarassing
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;
}
}
}
}
the answer was the clear method in the pane that it's setting in. the animation needs to be stopped and deleted
don't use pane.clear(); when theres an animation use LowerGrid.getChildren().removeAll();