基本上就是标题。我在 JavaFX 中有一个节点,我想根据某些 CSS 规则将其显示在所有其他节点的前面。我不希望这改变我的 VBox
中节点的顺序,而 .toFront()
似乎是这样做的。参见 this问题。
这可能吗?
编辑:澄清。情况如下。我有一个 VBox
,其中包含一堆紧密打包的 ImageView
。当我将鼠标悬停在一个上时,我希望它稍微变大,给人一种图像从屏幕上移开的感觉。但是由于 ImageView
非常紧凑,只有顶部边缘(可见)增长。底部边缘增长但低于下图,无法看到。
编辑 2:根据要求,这里是我正在做的事情的屏幕截图。
不同的颜色渐变是 ImageView
,当我将鼠标悬停在一个渐变上时,它应该随着该图像中顶部渐变的顶部边缘的增长而增长(仔细观察 X 旁边的右上角).然而,在这张图片中也可以看到,此 ImageView
的底部边缘已被此 VBox
中的下一个渐变隐藏,并且增长不可见。
最佳答案
这听起来像是使用 viewOrder
的完美情况Java 9 中添加的 Node
属性。viewOrder
控制 Node
相对于其他 Node
的绘制方式相同的 Parent
而不改变子列表中 Node
的顺序。这是 Javadoc:
Defines the rendering and picking order of this Node within its parent.
This property is used to alter the rendering and picking order of a node within its parent without reordering the parent's children list. For example, this can be used as a more efficient way to implement transparency sorting. To do this, an application can assign the viewOrder value of each node to the computed distance between that node and the viewer.
The parent will traverse its children in decreasing viewOrder order. This means that a child with a lower viewOrder will be in front of a child with a higher viewOrder. If two children have the same viewOrder, the parent will traverse them in the order they appear in the parent's children list.
However, viewOrder does not alter the layout and focus traversal order of this Node within its parent. A parent always traverses its children list in order when doing layout or focus traversal.
这是一个使用此属性的示例:
import javafx.animation.ScaleTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.util.ArrayList;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
var box = new HBox(createRectangles(Color.DARKBLUE, Color.FIREBRICK, 25));
box.setAlignment(Pos.CENTER);
box.setPadding(new Insets(50, 20, 50, 20));
primaryStage.setScene(new Scene(box));
primaryStage.show();
}
private Rectangle[] createRectangles(Color start, Color end, int count) {
var list = new ArrayList<Rectangle>(count);
for (double i = 0; i < count; i++) {
var rect = new Rectangle(30, 60, start.interpolate(end, i / count));
var scaleTrans = new ScaleTransition(Duration.millis(250), rect);
scaleTrans.setFromX(1.0);
scaleTrans.setFromY(1.0);
scaleTrans.setToX(1.2);
scaleTrans.setToY(1.2);
rect.setOnMouseEntered(e -> {
scaleTrans.stop(); // <--- doesn't seem necessary*
scaleTrans.setRate(1.0);
rect.setViewOrder(-1.0);
scaleTrans.play();
});
rect.setOnMouseExited(e -> {
scaleTrans.stop(); // <--- doesn't seem necessary*
scaleTrans.setRate(-1.0);
rect.setViewOrder(0.0);
scaleTrans.play();
});
// *the "stop()"'s don't seem to be necessary. When I commented
// them out the animation still worked. In fact, the animation
// actually seems smoother in the situation where you move the
// mouse over and then away quickly (before the zoom-in completes).
list.add(rect);
}
return list.toArray(new Rectangle[0]);
}
}
它使用 Rectangle
而不是 ImageView
但概念是相同的。当鼠标悬停在 Rectangle
上时,它会将 View 顺序设置为低于其他 View 顺序,然后播放 ScaleTransition
以使其变大。当鼠标退出时,它会将 View 顺序重置回 0
,然后反转 ScaleTransition
。
注意:我使用了 Java 10 中添加的 var
关键字。
这是实际示例的 GIF:
编辑:由于您提到了 CSS,我去检查是否可以从样式表设置 View 顺序。看起来它可以。看着 CSS Reference Guide为名为 -fx-view-order
的 Node
定义了一个 CSS 属性。
关于css - JavafX 和 CSS - 将节点移到前面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51071095/