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
88 views
in Technique[技术] by (71.8m points)

java - How to transfer a container from one window to another in JavaFX

I got a Button called "Transfer" with the onclick method and a VBox with 3 Buttons in one window. The second window only has a HBox container. I wanna understand how to send the VBox to the HBox in the other window by pressing the transfer Button.

And what would also help is feedback regarding my code/file organization.

Main Class:

package testproject;
import javafx.application.Application;
import testproject.screen1.Screen1;
import testproject.screen2.Screen2;
import javafx.stage.Stage;

public class Main extends Application {

private Screen1 screen1;
private Screen2 screen2;

@Override
public void start(Stage primaryStage) throws Exception{

    screen1 = new Screen1(this, new Stage());
    screen2 = new Screen2(this, primaryStage);
}
public static void main(String[] args) {
    Application.launch(args);
}
}

Screen1 Class:

package testproject.screen1;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import testproject.Main;
import java.io.IOException;

public class Screen1 {

public Screen1(Main main, Stage stage){

    FXMLLoader loader = new FXMLLoader();
 
  try {
        Parent root = 
        loader.load(getClass().getResourceAsStream("/testproject/screen1/screen1.fxml"));
        stage.setTitle("Screen 1");
        stage.setScene(new Scene(root, 300, 275));
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    stage.show();
}
}

Screen2 Class:

package testproject.screen2;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import testproject.Main;
import java.io.IOException;

public class Screen2 {

public Screen2(Main main, Stage stage) {

    FXMLLoader loader = new FXMLLoader();

    try {

        Parent root =        
   loader.load(getClass().getResourceAsStream("/testproject/screen2/screen2.fxml"));
        stage.setTitle("Screen 2");
        stage.setScene(new Scene(root, 300, 275));
    }
    catch (IOException e) {
        e.printStackTrace();
    }

    stage.show();
}
}

Screen1Controller Class:

package testproject.screen1;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;

public class Screen1Controller {

@FXML
private AnchorPane Pane1;
@FXML
private VBox VBoxScreen1;
@FXML
private Button TransferButton;
@FXML
void transferToScreen2(MouseEvent event){
}
}

Screen2Controller Class:

package testproject.screen2;
import javafx.fxml.FXML;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;

public class Screen2Controller {

@FXML
private AnchorPane Pane2;
@FXML
private HBox HBoxScreen2;
 }
question from:https://stackoverflow.com/questions/66053198/how-to-transfer-a-container-from-one-window-to-another-in-javafx

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

1 Answer

0 votes
by (71.8m points)

One way I can think of is to pass a callback/consumer to the screen2 controller to let it know what to do with its node. Having said that, there can be many other approaches to this requirement.

As per my view, you dont need separate classes to load the screens. You can check the below working demo.

Main.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader2 = new FXMLLoader(getClass() .getResource("screen2.fxml"));
        VBox screen2 = loader2.load();
        Screen2Controller screen2Controller = loader2.getController();
        Stage screen2Stage = new Stage();
        Scene scene2 = new Scene(screen2);
        screen2Stage.setScene(scene2);
        screen2Stage.setTitle("Screen 2");
        screen2Stage.setX(900);
        screen2Stage.setY(100);
        screen2Stage.show();

        FXMLLoader loader1 = new FXMLLoader(getClass() .getResource("screen1.fxml"));
        VBox screen1 = loader1.load();
        Screen1Controller screen1Controller = loader1.getController();
        // Set a consumer to the screen1 to let it know what to do
        screen1Controller.setTransferer(screen2Controller::moveNode);
        Scene scene1 = new Scene(screen1);
        primaryStage.setScene(scene1);
        primaryStage.setTitle("Screen 1");
        primaryStage.setX(100);
        primaryStage.setY(100);
        primaryStage.show();
    }

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

Screen1Controller.java

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import java.util.function.Consumer;

public class Screen1Controller {

    @FXML
    private VBox pane1;
    @FXML
    private VBox vBoxScreen1;
    @FXML
    private Button transferButton;
    private Consumer<Node> transferer;

    @FXML
    void transferToScreen2(ActionEvent event) {
        // First remove the node from the parent.
        pane1.getChildren().remove(vBoxScreen1);

        // Then send the node to do the other operation.
        this.transferer.accept(vBoxScreen1);
    }

    public void setTransferer(Consumer<Node> transferer) {
        this.transferer = transferer;
    }
}

screen1.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<VBox fx:id="pane1" xmlns="http://javafx.com/javafx"
           xmlns:fx="http://javafx.com/fxml"
           fx:controller="com.stackoverflow.javafx.issue7.Screen1Controller"
           prefHeight="400.0" prefWidth="600.0" spacing="10">
    <children>
        <VBox fx:id="vBoxScreen1" spacing="10" style="-fx-border-width:2px;-fx-border-color:red;-fx-background-color:yellow;" prefWidth="200" maxWidth="200" prefHeight="200">
            <children>
                <Button text="Button 1"/>
                <Button text="Button 2"/>
                <Button text="Button 3"/>
            </children>
            <padding>
                <Insets topRightBottomLeft="10" />
            </padding>
        </VBox>
        <Button fx:id="transferButton" text="Transfer" onAction="#transferToScreen2"/>
    </children>
    <padding>
        <Insets topRightBottomLeft="10" />
    </padding>
</VBox>

Screen2Controller.java

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;

public class Screen2Controller {

    @FXML
    private VBox pane2;
    @FXML
    private HBox hBoxScreen2;

    public void moveNode(Node node){
        hBoxScreen2.getChildren().add(node);
    }
}

screen2.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<VBox fx:id="pane2" xmlns="http://javafx.com/javafx"
      xmlns:fx="http://javafx.com/fxml"
      fx:controller="com.stackoverflow.javafx.issue7.Screen2Controller"
      prefHeight="400.0" prefWidth="600.0" spacing="10">
    <children>
        <HBox fx:id="hBoxScreen2" spacing="10">
            <padding>
                <Insets topRightBottomLeft="10" />
            </padding>
        </HBox>
    </children>
    <padding>
        <Insets topRightBottomLeft="10" />
    </padding>
</VBox>

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

...