How to show / hide / auto hide a node

天大地大妈咪最大 提交于 2019-12-20 07:35:29

问题


I am doing a javafx project which if i click the button, the scene is showing, but if the scene is left open for few seconds, the scene will auto hide.

The actual scene is if i left it open, it will auto hide at the below of the main scene just like the button is pressed.

But i tried alot ways, the scene will either not hiding, or moving upward which if i click the button, the scene is at upward of the scene moving but not on the main scene.

If the scene is not on main scene, nothing will happen.But only if the scene is on main scene, the scene will auto hide and move downward just like when I click the button, the scene appear on the main scene from below and if i click close, the scene will go down and hide until i click again. when i click the button after a few inactive(like move the cursor), the scene will function as usual.

The code which i follow : Call another FXML within a stage

Testinggg.java

package testinggg;
import java.io.IOException;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.InputEvent;
import javafx.stage.Stage;
import javafx.util.Duration;
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();
    Duration duration = Duration.seconds(5);
    PauseTransition transition = new PauseTransition(duration);
    transition.setOnFinished(evt -> inactive());
    stage.addEventFilter(InputEvent.ANY, evt -> transition.playFromStart());
    transition.play();
} 
private void inactive(){
    //hide the status until status is open
}
public static void main(String[] args) {
    launch(args);
}
}

TestController.java

package testinggg;
import java.net.URL;
import java.util.ResourceBundle;
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;
boolean showsStatus = false;

public void toggleStatus() {
    if( showsStatus ) {
        showStatus.stop();
        hideStatus.play();
    }
    else {
        hideStatus.stop();
        showStatus.play();
    }
}
@Override
public void initialize(URL url, ResourceBundle rb) {
    showStatus = new TranslateTransition(Duration.millis(250), statusContainer);
    showStatus.setByY(-1080.0);
    showStatus.setOnFinished(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent event) {
            showsStatus = true;
        }
    });

    hideStatus = new TranslateTransition(Duration.millis(250), statusContainer);
    hideStatus.setByY(1080.0);
    hideStatus.setOnFinished(new EventHandler<ActionEvent>() {
        @Override public void handle(ActionEvent event) {
            showsStatus = false;
        }
    });
}    
}

for Test.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>

<?import javafx.scene.web.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.image.*?>
<?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="Some paragraph 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>

回答1:


Here is an mcve version of the code you are following, to get you started :

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Test1 extends Application  {

    @Override
    public void start(Stage primaryStage) {
        try {
            StackPane page = (StackPane) FXMLLoader.load(this.getClass().getResource("test1.fxml"));
            Scene scene = new Scene(page);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

test1.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>

<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" 
minWidth="-Infinity" prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/10.0.1" 
xmlns:fx="http://javafx.com/fxml/1" fx:controller="Test1Controller">
  <children>
    <AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: blue;">
      <children>
        <Button mnemonicParsing="false" onAction="#toggleStatus" text="Status" AnchorPane.leftAnchor="50.0" AnchorPane.topAnchor="100.0" />
      </children>
    </AnchorPane>
    <VBox fx:id="statusContainer" maxHeight="100.0" prefHeight="100.0" style="-fx-background-color: yellow;" translateY="100.0" StackPane.alignment="BOTTOM_LEFT" />
  </children>
</StackPane>

and its controller:

import javafx.animation.TranslateTransition;
import javafx.fxml.FXML;
import javafx.scene.layout.VBox;
import javafx.util.Duration;

public class Test1Controller {

    @FXML private VBox statusContainer;

    private TranslateTransition showStatus;
    private TranslateTransition hideStatus;
    private boolean showsStatus = false;

    @FXML void initialize() {

        showStatus = new TranslateTransition(Duration.millis(250), statusContainer);
        showStatus.setByY(-100.0);
        showStatus.setOnFinished(event -> showsStatus = true);
        hideStatus = new TranslateTransition(Duration.millis(250), statusContainer);
        hideStatus.setByY(100.0);
        hideStatus.setOnFinished(event -> showsStatus = false);
    }

   public void toggleStatus() {
        if( showsStatus ) {
            showStatus.stop();
            hideStatus.play();
        }
        else {
            hideStatus.stop();
            showStatus.play();
        }
    }
}

Edit: you can add auto-hide of the sliding node to the controller:

public class Test1Controller {

    @FXML private VBox statusContainer;

    private TranslateTransition showStatus;
    private TranslateTransition hideStatus;
    private boolean showsStatus = false;
    private static final int AUTO_HIDE_DEALY = 5;

    @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);
    }

    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 ) {
                hide();
            }
        });
        transition.play();
    }
}


来源:https://stackoverflow.com/questions/56707361/how-to-show-hide-auto-hide-a-node

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!