这是一个示例。
import javafx.animation.*;
import javafx.application.Application;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.List;
import java.util.stream.*;
public class NumberSwitcher extends Application {
private static final int NUM_NUMS_DISPLAYED = 3;
private static final Duration TRANSITION_TIME = Duration.seconds(0.5);
private final IntegerProperty idx = new SimpleIntegerProperty(0);
private final IntegerProperty toIdx = new SimpleIntegerProperty(0);
private final List<Label> labels =
IntStream.range(0, NUM_NUMS_DISPLAYED)
.mapToObj(
this::createLabel
)
.collect(Collectors.toList());
private final Button incrementButton = new Button("Increment");
@Override
public void start(Stage stage) {
stage.setScene(
new Scene(
createLayout(),
Color.PALEGREEN
)
);
stage.show();
enableTransitions();
}
private StackPane createLayout() {
incrementButton.setStyle("-fx-base: darkslateblue; -fx-text-fill: papayawhip; -fx-font-size: 20px;");
HBox numbers = new HBox(10);
numbers.getChildren().addAll(labels);
numbers.setPadding(new Insets(15));
numbers.setMaxWidth(HBox.USE_PREF_SIZE);
VBox layout = new VBox(
15,
numbers,
incrementButton
);
layout.setAlignment(Pos.CENTER);
layout.setPadding(new Insets(15));
layout.setStyle("-fx-background-color: null;");
StackPane centered = new StackPane(layout);
centered.setStyle("-fx-background-color: null;");
return centered;
}
private Label createLabel(final int i) {
Label label = new Label();
label.setStyle(
"-fx-font-size: 50px; -fx-font-family: monospace; -fx-text-fill: midnightblue;"
);
label.textProperty().bind(new StringBinding() {
{
super.bind(idx);
}
@Override
protected String computeValue() {
return "" + ((idx.get() + i) % 10);
}
});
return label;
}
private void enableTransitions() {
ParallelTransition changeNumbers = new ParallelTransition(
createFadeFirst()
);
IntStream.range(1, labels.size())
.mapToObj(this::createMoveLeft)
.forEachOrdered(
moveLeft -> changeNumbers.getChildren().add(moveLeft)
);
changeNumbers.setOnFinished(e -> idx.set(toIdx.get()));
toIdx.addListener((observable, oldValue, newValue) ->
changeNumbers.play()
);
// You can disable incrementing while the transition is running,
// but that is kind of annoying, so I chose not to.
// incrementButton.disableProperty().bind(
// changeNumbers.statusProperty().isEqualTo(
// PauseTransition.Status.RUNNING
// )
// );
incrementButton.setOnAction(e -> {
if (idx.get() != toIdx.get()) {
idx.set(toIdx.get());
}
toIdx.set((toIdx.get() + 1) % 10);
});
}
private FadeTransition createFadeFirst() {
FadeTransition fadeFirst = new FadeTransition(
TRANSITION_TIME,
labels.get(0)
);
fadeFirst.setFromValue(1);
fadeFirst.setToValue(0);
fadeFirst.setOnFinished(e -> labels.get(0).setOpacity(1));
return fadeFirst;
}
private TranslateTransition createMoveLeft(int i) {
TranslateTransition moveLeft = new TranslateTransition(
TRANSITION_TIME,
labels.get(i)
);
double dx =
labels.get(i).getBoundsInParent().getMinX()
- labels.get(i-1).getBoundsInParent().getMinX();
moveLeft.setFromX(0);
moveLeft.setToX(-dx);
moveLeft.setOnFinished(e -> labels.get(i).setTranslateX(0));
return moveLeft;
}
public static void main(String[] args) {
launch(args);
}
}
其他问题的答案
我看到您正在翻译节点,但是,您在什么时候更改 HBox 中的位置?
此示例的 HBox 中的位置(例如 layoutX 和 layoutY)在最初在 HBox 中布局后从未更改。 HBox 是一个布局管理器,它会自动设置 HBox 中项目的 layoutX 和 layoutY 坐标。 HBox 布局算法会将每个项目从左到右顺序放置在其子列表中(默认情况下),并将每个项目的大小调整为它的首选大小。 HBox 基于脏标志工作,因此它只会在需要时重新布局内部的组件(例如组件更改或组件的 CSS 样式更改或 HBox 的可用区域更改),这些都不会发生在此样本。
您是否只是翻译它们,切换文本,然后重置翻译?
是的。
您能否简要介绍一下这是如何工作的?
三个标签被添加到一个 HBox。每个标签使用等宽字体和相同数量的字符,因此每个标签的宽度相等。记录了两个指数。一个是显示字符在文本区域中的当前索引,另一个是 toIdx,它是要移动到的文本数组中的下一个索引。提供了一个递增按钮,它将递增 toIdx。在 toIdx 上放置一个更改侦听器,以便在更改时启动一组动画,第一个动画淡化第一个标签,其他动画将剩余的标签移动到左侧的下一个位置。动画完成后,每个标签的平移都设置为 0,因此每个移动的标签都会移回其原始位置。此外,一旦动画完成,当前索引将设置为 toIdx。当 toIdx 更新时,绑定用于自动更新每个标签中的文本。
效果是,当按下增量按钮时,第一个标签中的数字消失,右侧标签中的数字向左移动,一旦到了那里,就会返回到它们的原始位置,但它们的值设置为下一个最高数字。这提供了问题中要求的效果。