JavaFXの基本フローパネルは、ウィンドウのサイズを変更するたびにアイテムをレイアウトします。しかし、アニメーションはありませんし、結果はむしろびっくりします。レイアウト変更時のアニメーション
FlowPane内の各NodeのlayoutXプロパティとlayoutYプロパティに変更リスナーを追加しましたが、結果は多少なりとも機能しますが、ウィンドウのサイズをすばやく変更すると要素が矛盾した場所に残ることがあります。
私には何が欠けていますか?
package javafxapplication1;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.animation.Transition;
import javafx.animation.TranslateTransition;
import javafx.beans.property.DoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.util.Duration;
/**
* Animates an object when its position is changed. For instance, when
* additional items are added to a Region, and the layout has changed, then the
* layout animator makes the transition by sliding each item into its final
* place.
*/
public class LayoutAnimator implements ChangeListener, ListChangeListener<Node> {
private Map<Node, Transition> nodesInTransition;
public LayoutAnimator() {
this.nodesInTransition = new HashMap<>();
}
/**
* Animates all the children of a Region.
* <code>
* VBox myVbox = new VBox();
* LayoutAnimator animator = new LayoutAnimator();
* animator.observe(myVbox.getChildren());
* </code>
*
* @param nodes
*/
public void observe(ObservableList<Node> nodes) {
for (Node node : nodes) {
this.observe(node);
}
nodes.addListener(this);
}
public void unobserve(ObservableList<Node> nodes) {
nodes.removeListener(this);
}
public void observe(Node n) {
n.layoutXProperty().addListener(this);
n.layoutYProperty().addListener(this);
}
public void unobserve(Node n) {
n.layoutXProperty().removeListener(this);
n.layoutYProperty().removeListener(this);
}
@Override
public void changed(ObservableValue ov, Object oldValue, Object newValue) {
final Double oldValueDouble = (Double) oldValue;
final Double newValueDouble = (Double) newValue;
final Double changeValueDouble = newValueDouble - oldValueDouble;
DoubleProperty doubleProperty = (DoubleProperty) ov;
Node node = (Node) doubleProperty.getBean();
final TranslateTransition t;
if ((TranslateTransition) nodesInTransition.get(node) == null) {
t = new TranslateTransition(Duration.millis(150), node);
} else {
t = (TranslateTransition) nodesInTransition.get(node);
}
if (doubleProperty.getName().equals("layoutX")) {
Double orig = node.getTranslateX();
if (Double.compare(t.getFromX(), Double.NaN) == 0) {
t.setFromX(orig - changeValueDouble);
t.setToX(orig);
}
}
if (doubleProperty.getName().equals("layoutY")) {
Double orig = node.getTranslateY();
if (Double.compare(t.getFromY(), Double.NaN) == 0) {
t.setFromY(orig - changeValueDouble);
t.setToY(orig);
}
}
t.play();
}
@Override
public void onChanged(ListChangeListener.Change change) {
while (change.next()) {
if (change.wasAdded()) {
for (Node node : (List<Node>) change.getAddedSubList()) {
this.observe(node);
}
} else if (change.wasRemoved()) {
for (Node node : (List<Node>) change.getRemoved()) {
this.unobserve(node);
}
}
}
}
}
A要旨は、読みやすくするために、ここで利用可能であり、テストケースが付属しています:https://gist.github.com/teyc/5668517
普遍性のために、translateX/Yの元の値を保持することは可能ですか?アニメーションを確認してください.STATUSは役に立たないようです。私はそれがjfxtrasに入る前にそれをきれいにするのが大好きです。 –
translateX/Yの元の値を保存するためのアイデアを提供するために、「レイアウトアニメーションの変更を独立フォームのユーザーTranslateX/Y設定」セクションに追加しました。 – jewelsea
「ユーザーTranslateX/Y設定から独立したレイアウトアニメーションの変更を行う」を実装したソリューションに[フォークリンク](https://gist.github.com/jewelsea/5683558)を追加しました。 – jewelsea