Как передать сложные объекты в FXML через пространство имен и FXMLLoader? - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть пользовательский Компонент.


public class CustomBtn extends Button{

      private ComplexObject properties;

      public void setProperties(ComplexObject properties){
           this.properties = properties;
      }

      public ComplexObject getProperties(){
           return properties
      }

}


public class ComplexObject {
    String x = "hello";
    int y = 42;
}

И в FXML я могу получить доступ к компоненту через


<Pane xmlns:fx="http://javafx.com/fxml">
  <children>
     <CustomBtn text="hello">
       <properties>
       <!-- here i want to pass the object via namespace placeholder but I don't know how -->
       <properties>
     </CustomBtn>
  </children>
</Pane>

И я хочу передать объект в Свойства через загрузчик FXML.


public class SampleAppLauncher extends Application {

    public void start(Stage primaryStage){

        URL val = FXView.class.getClassLoader().getResource("sample.fxml");
        FXMLLoader loader = new FXMLLoader(val);

        Map<String, Object> ns = getNameSpace();
        ComplexObject property = new ComplexObject();
        property.x = "Bye bye";
        property.y = 420;
        // Here is the Object i want to pass
        ns.put("props", property);
        Pane p = loader.load(); 
        Scene s = new Scene(p);
        primaryStage.setScene(s);
        primaryStage.show();

    }

Я хочу передать параметр с

$ {} Anotation

как:

<Pane xmlns:fx="http://javafx.com/fxml">
  <children>
     <CustomBtn text="hello">
       <properties>
          ${props}
       <properties>
     </CustomBtn>
  </children>
</Pane>

это возможно?

Я знаю, что мог бы просто использовать методы "code behind", такие как @FXMl, и затем устанавливать их после загрузки. Но я хочу понять, какие объекты «проходимы» в пространство имен и как настроить «более сложные» объекты пользовательских компонентов в FXML. Является ли «Карта пространства имен только для« примитивных значений »?

1 Ответ

1 голос
/ 05 ноября 2019

Есть несколько проблем:

public class CustomBtn extends Button{

    ...    

    public ComplexObject getProperties(){
        return properties
    }
}

Поскольку Node уже содержит метод getProperties с таким же количеством аргументов, а тип, возвращаемый вашим методом, не совместим по присваиванию с возвращаемым типомиз Node.getProperties, вы не можете переопределить метод с тем, что в вашем классе. Вам нужно выбрать другое имя для вашей собственности.


Map<String, Object> ns = getNameSpace();

Метод называется getNamespace и является частью FXMLLoader, а не Application. Вам нужно изменить эту строку на

Map<String, Object> ns = loader.getNamespace();

Давайте изменим имя вашего свойства на myProperty:

public class CustomBtn extends Button{

      ...

      public void setMyProperty(ComplexObject properties){
           ....
      }

      public ComplexObject getMyProperty(){
           ...
      }
}

Вы можете использовать <fx:reference> для вставки свойства через fxml:

 <CustomBtn text="hello">
   <myProperty>
     <fx:reference source="props"/>
   <myProperty>
 </CustomBtn>

В качестве альтернативы используйте атрибут, начинающийся с $:

 <CustomBtn text="hello" myProperty="$props" />
...