0

我想设计一个包含 BorderPane 的 GUI 在容器的顶部有一个 MenuBar,在容器的左侧有一个带有不同按钮的手风琴,用于更改不同 FXML 文件的容器中心的内容,例如Spotify 的桌面应用程序

http://s32.postimg.org/4qw5qbr45/Spoty_Like.png

我有一个工作原型,它看起来像这样

http://s32.postimg.org/w9g4rqfid/muestra.png

FXML 发生了变化并且按钮反应很好,我遇到的问题是填充 BoderPane 中心部分的 FXML 不会自动调整,如果是 FXML 的大部分没有显示,如果 FXML比中心部分的空间更小

这是我调用新 FXML 的代码

public void lanzaUno(){
        try {
            // load first FXML
            FXMLLoader loader = new FXMLLoader();

            loader.setLocation(Coordinador.class.getResource(
                    "VistaControlador/Usuario/Uno.fxml"));

            /*i put the AnchorPane inside of a 
            ScrollPane  for the desire funcionality of alot 
            of vertical space for many nodes in a single FXML file  
            */
            ScrollPane unoAnchorPane = (ScrollPane) loader.load();

            UnoController controller = loader.getController();
            //example method for passing variables to the FXML controler 
            controller.pasoPrincipal(this, primaryStage, "Rhutt");
            //puts the FXML in the center of the BorderPane
            rootLayout.setCenter(unoAnchorPane);
            //this if for trying to accommodate the content en the BorderPane 
            BorderPane.setAlignment(unoAnchorPane, Pos.TOP_LEFT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

我的第一个问题是在调用 FXML 以获取此内容占用 BorderPane 中的可用空间时,我缺少什么?

我的第二个问题是关于 FXML 的变化,当我从一个传递到另一个时,BorderPane 中的变化是瞬间的,看起来很糟糕有没有一种方法可以使转换就像调用的 FXML 的内容推送FXML 的内容在中心?,它不必很详细,只是让过渡更好一点

编辑

我有一个协调器类,我在其中发送和接收所有 FXML 的参数,并在其中声明调用新 FXML 的方法,所以我有一个协调器类,一个带有其控制器的 FXML 根和两个 FXML 及其控制器,每个都有不同的东西一、这两个FXML是在根的BorderPane中心变化的

这是协调器类

//Variables
        private Stage primaryStage;
        private BorderPane rootLayout;

    /**
     * launh 
     * @param primaryStage
     *  
     */
    @Override
    public void start(Stage primaryStage) throws Exception{
        // Inicializa la escena
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("Login");
        this.primaryStage.centerOnScreen();
        //star method 
        iniLogin();
    }

     /**
     *load the root scene
     */
    public void iniLogin(){
        try {
            // Carga el loader.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(com.aohys.rehabSys.MVC.Coordinador.class.getResource(
                    "VistaControlador/Pricipal/Principal.fxml"));
            rootLayout = (BorderPane) loader.load();
            //the root scene
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            // Da acceso al programa principal.
            PrincipalController controller = loader.getController();
            controller.pasoPrincipal(this, primaryStage);
            primaryStage.centerOnScreen();
            // Muesta la escena,
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

在此方法之后有两种相同的方法,例如我在开始时调用 2 个不断变化的 FXML 调用 LanzaUno、LanzaDos 的方法

这是我的最佳 FXML 控制器

public class PrincipalController implements Initializable {
    //variable of the coordinator class
    private Coordinador cordi;
    private Stage stage;

    /**
     * method for passing parameters to the FXML
     * @param cordi
     * @param stage 
     */
    public void pasoPrincipal(Coordinador cordi, Stage stage) {
        this.cordi = cordi;
        this.stage = stage;
    }

    //FXML in root 
    @FXML private Button btt1;
    @FXML private Button btt2;
    @FXML public static StackPane stackPane;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        //Call the firts FXML
        btt1.setOnAction((evento)->{
            cordi.lanzaUno();
        });

        //Call the second FXML
        btt2.setOnAction((evento)->{
            cordi.lanzaDos();
        });
    }  

目前两个 FXML 上的控制器不做任何事情

4

1 回答 1

1

您应该阅读Adam Bien 的 AfterburnerFX库,用于管理应用程序中的依赖注入和控制器。它改变了我的生活。:)

对于转换,我使用此代码。这是一个很好的从一个屏幕到下一个屏幕的淡出/淡入。在这种情况下,stackPane是您在 FXML 中定义StackPane的中心。BorderPane

这是一个带有上述 stackPane 的简单 FXML:

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

<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<BorderPane fx:id="borderPane" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.tada.gui.tada.TadaPresenter">
   <center>
      <StackPane fx:id="stackPane" minHeight="-Infinity" minWidth="-Infinity" prefHeight="240.0" prefWidth="320.0" BorderPane.alignment="CENTER" />
   </center>
</BorderPane>

以及传入的更改为新的 setScreen 方法:

/**
 * Set Screen 
 * 
 * @param view
 * @return boolean
 */
public boolean setScreen(Parent view) {       
    final DoubleProperty opacity = stackPane.opacityProperty();

    if (!stackPane.getChildren().isEmpty()) {    //if there is more than one screen
        Timeline fade = new Timeline(
                new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)),
                new KeyFrame(new Duration(TRANSITION_TIMER), new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent t) {
                        stackPane.getChildren().remove(0);        //remove the displayed screen
                        stackPane.getChildren().add(0, view);     //add the screen
                        Timeline fadeIn = new Timeline(
                                new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
                                new KeyFrame(new Duration(TRANSITION_TIMER), new KeyValue(opacity, 1.0)));
                        fadeIn.play();
                    }
                }, new KeyValue(opacity, 0.0)));
        fade.play();

    } else {
        stackPane.setOpacity(0.0);
        stackPane.getChildren().add(view);       //no one else been displayed, then just show
        Timeline fadeIn = new Timeline(
                new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
                new KeyFrame(new Duration(TRANSITION_TIMER), new KeyValue(opacity, 1.0)));
        fadeIn.play();
    }
    return true;
}

您还需要在控制器中使用它...

private static final double TRANSITION_TIMER = 200;

编辑:

我试图把一个非常基本的“应用程序”放在一起。它很简陋,但我认为它很好地说明了 AfterburnerFX 的使用和屏幕渐变过渡。AfterburnerFX 还有很多其他功能。我只是在没有依赖注入的情况下使用了视图切换,当您开始想要处理应用程序中的对象时,这非常重要。此外,属性绑定对于良好的用户体验非常重要。无论如何,这是在 GitHub 上的示例的链接。

于 2016-05-18T05:03:51.000 回答