如何为现有布局设置其他FXML布局

时间:2019-04-17 17:25:05

标签: java javafx

所以我有两个控制器:MainControllerImageContainer都具有FXML布局。在我的MainController中,我设置了一个SplitPane,并在其中设置了FlowPane,现在我想在运行时在流窗格中加载ImageContainer的布局:

问题
如何将布局与文本字段中的预填充值一起放置在流窗内,设置图像等?

想法
ImageContainer必须扩展Pane,在MainController中,我必须调用ImageContainer的构造函数并将ImageContainer添加到流窗格中:

ImageContainer imgC = new ImageContainer(4,2,"location");
fp_contentFlowPane.getChildren().add(imgC);
  

由以下原因引起:java.lang.NullPointerException
  造成原因:java.lang.reflect.InvocationTargetException

如果有人有想法,我们将不胜感激!

ImageContainer Contoller的代码段部分:

public class ImageContainer extends Pane {

public HBox hbx_elementContainer;
public Label lb_likeCount;
public Label lb_commentCount;
public Label lb_location;

public ImageContainer(int likeCount, int commentCount, String location) {
    this.lb_likeCount.setText(String.valueOf(likeCount));
    this.lb_commentCount.setText(String.valueOf(commentCount));
    this.lb_location.setText(location);

    Image image = new Image("/sampleFoto.JPG");
    iv_feedImage.setImage(image);

    }
}

MainController的代码段的一部分请注意,这不是完整的代码:

public class MainScreenController{

public TextField tf_userName;
public ListView lv_listView;
public FlowPane fp_contentFlowPane;
public SplitPane sp_splitPane;

public void onItemClicked(MouseEvent mouseEvent) throws IOException {
    int index = lv_listView.getSelectionModel().getSelectedIndex();

    if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {
        if (index >= 0) {
            lv_listView.getItems().remove(index);
            userList.remove(index);
        }
    }
    else{
        //fp_contentFlowPane.getChildren().add(new 
      ImageContainer(5,5,"test"));

        ImageContainer imgC = new ImageContainer(4,2,"location");
        fp_contentFlowPane.getChildren().add(imgC);


    }
}}

代码段主要

public class Main extends Application {

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

    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("/sample.fxml"));
    Parent root = loader.load();

    primaryStage.setTitle("Get Viral");
    primaryStage.setScene(new Scene(root, 1000, 700));
    primaryStage.show();
    primaryStage.getIcons().add(new Image("/iconSpectures.jpg"));

    }


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

ImageContainer的FXML:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" 
minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" 
xmlns="http://javafx.com/javafx/8.0.172-ea" 
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.ImageContainer">
   <bottom>
      <HBox fx:id="hbx_elementContainer" prefHeight="31.0" prefWidth="600.0" 
    BorderPane.alignment="CENTER">
         <children>
            <Label fx:id="lb_likeCount" contentDisplay="TOP" text="Label">
               <HBox.margin>
                  <Insets right="10.0" />
               </HBox.margin></Label>
            <Label fx:id="lb_commentCount" text="Label">
               <HBox.margin>
                  <Insets right="20.0" />
               </HBox.margin></Label>
            <Label fx:id="lb_location" text="Label" />
            <Label fx:id="lb_accountHolder" text="Label" />
          <Button mnemonicParsing="false" text="Download">
               <font>
                  <Font name="Arial Bold" size="11.0" />
               </font>
               <HBox.margin>
                  <Insets right="10.0" />
               </HBox.margin>
            </Button>
         </children>
       </HBox>
   </bottom>
<center>
  <AnchorPane prefHeight="200.0" prefWidth="200.0" 
BorderPane.alignment="CENTER">
        <children>
             <ImageView fx:id="iv_feedImage" fitHeight="150.0" 
fitWidth="200.0" 
pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" 
AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" 
AnchorPane.topAnchor="0.0" />
         </children>
      </AnchorPane>
   </center>
</BorderPane>

1 个答案:

答案 0 :(得分:2)

如果您希望ImageContainer使用FXML,则可以简单地使用FXMLLoader将其加载到构造函数中,并从FXML中删除fx:controller="sample.ImageContainer"

Here's上有关何时使用哪种方法为fxml文件设置控制器的信息(fx:controllerFXMLLoader);由于您的ImageContainer构造函数需要参数,因此imo使用FXMLLoader方法更容易。

public class ImageContainer extends Pane {

private static final PATH_FXML = "/internal/path/to/layout.fxml"

@FXML public HBox hbx_elementContainer;
@FXML public Label lb_likeCount;
@FXML public Label lb_commentCount;
@FXML public Label lb_location;

public ImageContainer(int likeCount, int commentCount, String location) {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(PATH_FXML));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
    try {
        fxmlLoader.load();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    this.lb_likeCount.setText(String.valueOf(likeCount));
    this.lb_commentCount.setText(String.valueOf(commentCount));
    this.lb_location.setText(location);

    Image image = new Image("/sampleFoto.JPG");
    iv_feedImage.setImage(image);
}
}

一些有趣的东西:如果在自定义控件上定义getter和setter,则可以在FXML中该控件的属性中使用它们。

用例并非完全必要,但是您可以执行类似的操作。

自定义控件:

package path.to.my_package;

public class MyControl extends Control {
    private String myField;

    public String getMyField() { return myField; }
    public void setMyField(String myField) { this.myField = myField; }
}

FXML:

<?import path.to.my_package.MyControl ?>

<BorderPane xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
    <center>
        <MyControl myField="myValue"/>
    </center>
</BorderPane>