Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
647 views
in Technique[技术] by (71.8m points)

javafx - Show / Hide a Node within a stage

I am aware that there are already answers for this question but somehow, it was not able to solve my problem.

When I click the textfield in IMAGE1, I want the keyboard FXML(IMAGE2) to appear as is in IMAGE3. But the thing is, I can't seem to find the solution. How do I do this?

I need your help please.

IMAGE1

enter image description here

IMAGE2

enter image description here

IMAGE3

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I am experimenting with something similar, here is what I came up with (one of many possible solutions):

You need to wrap your main layout (IMAGE1) in a StackPane. Its usage is to overlay what needs be overlaid (the keyboard in your case). The keyboard is placed in another pane (a VBox in the following example). The VBox:

  • is placed in the StackPane after the main layout to sit on top of it
  • is given a maximum height, so that it doesn't fill the entire window
  • is given a translateY equal to the height
  • and bottom alignment

The relevant code n FXML:

<VBox fx:id="statusContainer" maxHeight="100.0" prefHeight="100.0"
    translateY="100.0" StackPane.alignment="BOTTOM_LEFT" />

This will always be outside of the view. Toggling the keyboard requires 2 TranslateTransitions (can it be done with 1, I wonder?), one to move the keyboard up, one down.

The example code:

1) Java:

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test1 extends Application
{
    @FXML private VBox statusContainer;

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

    @Override
    public void start(Stage primaryStage) {
        try {
            StackPane page = (StackPane) FXMLLoader.load(this.getClass().getResource("test1.fxml"));
            Scene scene = new Scene(page);

            primaryStage.setTitle(this.getClass().getName());
            primaryStage.setScene(scene);
            primaryStage.sizeToScene();
            primaryStage.show();
        }
        catch (IOException e) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, e);
        }
    }

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

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

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

2) FXML (call it test1.fxml to match the code):

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

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="fancymsg.FancyMsg1">
  <children>
    <AnchorPane prefHeight="200.0" prefWidth="200.0">
      <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" translateY="100.0" StackPane.alignment="BOTTOM_LEFT" />
  </children>
  <stylesheets>
    <URL value="@test1.css" />
  </stylesheets>
</StackPane>

3) The CSS for the VBox to stand out (call it test1.css):

#statusContainer {
    -fx-background-color: -fx-color;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...