Как установить дополнительный макет FXML на существующий - PullRequest
2 голосов
/ 17 апреля 2019

, поэтому у меня есть два контроллера: MainController и ImageContainer оба имеют макет FXML.В моем MainController я настроил SplitPane, а внутри него FlowPane, теперь я хочу загрузить макет ImageContainer в потоковую область во время выполнения:

ПРОБЛЕМА
Как разместить макет внутри потоковой панели с предварительно заполненными значениями в textFields, установить изображение и т. Д.?

Идея
ImageContainer должен расширять панель, и в 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);


    }
}}

Фрагмент кода Main

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

FXML ImageContainer:

<?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 Ответ

2 голосов
/ 17 апреля 2019

Если вы хотите, чтобы ваш ImageContainer использовал ваш FXML, вы можете просто загрузить его в конструктор, используя FXMLLoader, и избавиться от fx:controller="sample.ImageContainer" из вашего FXML.

Вот пост о том, когда использовать какой метод настройки контроллера для файла fxml (fx:controller против FXMLLoader);Поскольку ваш конструктор 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);
}
}

Для некоторых дополнительных забавных вещей: если вы определяете геттеры и сеттеры в пользовательском элементе управления, товы можете использовать их в атрибутах этого элемента управления в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...