javafx - 如何在节点处于活动状态时停止隐藏节点?
问题描述
我参考的代码:Show / Hide a Node within a stage
按照上一个关于自动隐藏的问题和答案:如何显示/隐藏/自动隐藏节点
感谢 c0der 解决了前面的问题。
它有一个问题,好像它处于活动状态(如移动光标或单击),Vbox 节点仍将自动隐藏。当我移动光标或发生某些事件时,如何使 Vbox 节点保持可见而不隐藏?
当前的行为是,如果我移动光标或单击 VBox 节点上的某些东西,5 秒后它仍然会隐藏。
测试gg.java:
package testinggg;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Testinggg extends Application {
private TestController controller;
@Override
public void start(Stage stage) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Test.fxml"));
Parent root = loader.load();
controller = loader.getController();
stage.setScene(new Scene(root));
stage.setFullScreen(true);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
测试控制器.java:
package testinggg;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.PauseTransition;
import javafx.animation.TranslateTransition;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
public class TestController implements Initializable {
@FXML private VBox statusContainer;
private TranslateTransition showStatus;
private TranslateTransition hideStatus;
private boolean showsStatus = false;
private static final int AUTO_HIDE_DELAY = 5;
public void toggleStatus() {
if( showsStatus ) {
hide();
}
else {
show();
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
showStatus = new TranslateTransition(Duration.millis(250), statusContainer);
showStatus.setByY(-1080.0);
showStatus.setOnFinished(event -> {
showsStatus = true;
autoHide();
});
hideStatus = new TranslateTransition(Duration.millis(250), statusContainer);
hideStatus.setByY(1080.0);
hideStatus.setOnFinished(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {
showsStatus = false;
}
});
}
private void show(){
hideStatus.stop();
showStatus.play();
}
private void hide(){
showStatus.stop();
hideStatus.play();
}
private void autoHide(){
Duration duration = Duration.seconds(AUTO_HIDE_DELAY);
PauseTransition transition = new PauseTransition(duration);
transition.setOnFinished(evt ->{
if( showsStatus ) {
hide();
}
});
transition.play();
}
}
测试.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testinggg.TestController">
<children>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" prefHeight="1080.0" prefWidth="1920.0" StackPane.alignment="TOP_LEFT">
<children>
<Button mnemonicParsing="false" onAction="#toggleStatus" prefHeight="1080.0" prefWidth="1920.0" text="Button" />
</children>
</AnchorPane>
<VBox fx:id="statusContainer" maxHeight="1080.0" prefHeight="1080.0" translateY="1080.0" StackPane.alignment="BOTTOM_LEFT">
<children>
<AnchorPane prefHeight="668.0" prefWidth="1266.0">
<VBox.margin>
<Insets bottom="50.0" left="50.0" right="50.0" top="50.0" />
</VBox.margin>
<children>
<ImageView fitHeight="540.0" fitWidth="1820.0" layoutY="43.0" pickOnBounds="true">
<image>
<Image url="@../Rainbow%20Poro.png" />
</image>
</ImageView>
<ImageView fitHeight="44.0" fitWidth="153.0" layoutX="857.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../logo.png" />
</image>
</ImageView>
<ScrollPane layoutY="582.0" prefHeight="391.0" prefViewportHeight="208.0" prefViewportWidth="1266.0" prefWidth="1820.0">
<content>
<TextArea editable="false" layoutY="460.0" prefHeight="515.0" prefWidth="1804.0" text="Sometexthere SometexthereSometexthereSometexthereSometexthereSometexthereSometexthereSometexthereSometexthereSometexthere Some Text Here Some Text Here Some Text Here Some Text Here Some Text Here Some Text HereSome Text HereSome Text HereSome Text HereSome Text HereSome Text HereSome Text Here Some Text Here" />
</content>
</ScrollPane>
<Button layoutX="1775.0" mnemonicParsing="false" onAction="#toggleStatus" text="Close" />
</children>
</AnchorPane>
</children>
</VBox>
</children>
<stylesheets>
<URL value="@test1.css" />
</stylesheets>
</StackPane>
解决方案
您可以向控制器添加一个控制布尔值:
private boolean isStatusContainerBusy = false;
让感兴趣的事件切换它。例如鼠标进入时设置为真,鼠标退出时设置为假:
statusContainer.setOnMouseEntered(e-> isStatusContainerBusy = true);
statusContainer.setOnMouseExited(e-> isStatusContainerBusy = false);
并用它来控制自动隐藏:
transition.setOnFinished(evt ->{
if( showsStatus ) {
if(isStatusContainerBusy) {
transition.play(); //start auto hide transition again
}else{
hide();
}
}
});
把它们放在一起:
public class TestController {
@FXML private VBox statusContainer;
private TranslateTransition showStatus;
private TranslateTransition hideStatus;
private boolean showsStatus = false;
private static final int AUTO_HIDE_DEALY = 5;
private boolean isStatusContainerBusy = false;
@FXML void initialize() {
showStatus = new TranslateTransition(Duration.millis(250), statusContainer);
showStatus.setByY(-100.0);
showStatus.setOnFinished(event -> {
showsStatus = true;
autoHide();
});
hideStatus = new TranslateTransition(Duration.millis(250), statusContainer);
hideStatus.setByY(100.0);
hideStatus.setOnFinished(event -> showsStatus = false);
statusContainer.setOnMouseEntered(e-> isStatusContainerBusy = true);
statusContainer.setOnMouseExited(e-> isStatusContainerBusy = false);
}
public void toggleStatus() {
if( showsStatus ) {
hide();
}
else {
show();
}
}
private void show(){
hideStatus.stop();
showStatus.play();
}
private void hide(){
showStatus.stop();
hideStatus.play();
}
private void autoHide() {
Duration duration = Duration.seconds(AUTO_HIDE_DEALY);
PauseTransition transition = new PauseTransition(duration);
transition.setOnFinished(evt ->{
if( showsStatus ) {
if(isStatusContainerBusy) {
transition.play(); //start auto hide transition again
}else{
hide();
}
}
});
transition.play();
}
}
推荐阅读
- python - 没有名为“django”的模块的 django/apache 问题
- python - 带有 pyspark 的 Python 单例
- python - 在已分配给新值 Python 的文本中查找字符串列表
- google-app-engine - 在 GCP(应用引擎)上运行 python Flask Restplus API 的问题
- c# - 来自类或值的 C# 可空类型参数
- java - 有人可以向我解释这个使用stream()的代码的构造吗?
- spring - spring maven 依赖项无法识别,库给出错误
- sql - 每次调用时单个 SELECT
- java - 迷宫回溯水平移动
- css - 尝试通过 scss 用 className 设置 react-select 样式,className 没有显示