2017-10-10 96 views
0

我創建了自定義JavaFX組件,如http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm中所述。將自定義類型的FXML屬性設置爲自定義javafx組件的屬性

// Component.fxml 
<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.scene.control.Label?> 
<?import javafx.scene.layout.VBox?> 
<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml"> 
    <Label fx:id="label"/> 
</fx:root> 

// Component.java 
public class Component extends VBox { 

    private final Entity entity; 
    @FXML private Label label; 

    public Component(@NamedArg("entity") Entity entity) { 
     this.entity = entity; 
     FXMLLoader fxmlLoader = new FXMLLoader(); 
     fxmlLoader.setLocation(Component.class.getResource("/Component.fxml")); 
     fxmlLoader.setRoot(this); 
     fxmlLoader.setController(this); 

     try { 
      fxmlLoader.load(); 
     } catch (IOException exception) { 
      throw new RuntimeException(exception); 
     } 
    } 

    @FXML 
    private void initialize() { 
     label.textProperty().set(this.entity.toString()); 
    } 
} 

現在我將它導入根佈局(自定義組件)。

// Root.fxml 
<?xml version="1.0" encoding="UTF-8"?> 

<?import foo.bar.javafx.Component?> 
<?import javafx.scene.layout.AnchorPane?> 
<fx:root type="javafx.scene.layout.AnchorPane"xmlns:fx="http://javafx.com/fxml"> 
// TODO How to pass entity? 
<Component entity=?> 
</Component> 

// Root.java 
public class Root extends AnchorPane { 

    public Root() { 
     FXMLLoader fxmlLoader = new FXMLLoader(); 
     fxmlLoader.setLocation(Root.class.getResource("/Root.fxml")); 
     fxmlLoader.setRoot(this); 
     fxmlLoader.setController(this); 

     try { 
      fxmlLoader.load(); 
     } catch (IOException exception) { 
      throw new RuntimeException(exception); 
     } 
    } 

} 

如何傳遞實體組件? 我知道如何傳遞字符串 - 它只是<Component entity="text">。但是如何通過任意類的實例呢? P.S.不希望爲此使用Singleton模式。

+0

要使用'entity'標籤,你應該有'setEntity'方法,但是'Entity'是最終的,你不能這樣做。你爲什麼要這樣做?你想要做什麼? – Sunflame

+0

@Sunflame我想通過這個分解視圖和模型。實體是一個模型。它與組件視圖有關。在我的主要方法我實例化模型(實體類),並希望將其傳遞到視圖(組件)。 – McMerphy

+0

問題是,你如何得到你的模型?你想用你的模型做什麼? – Sunflame

回答

1

爲您的問題的解決方案可能是將部件從控制器等爲每個控制器的創建控制器類中分離: 雖然所述部件是垂直框可以定義一個.fxml它喜歡:

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

<?import javafx.scene.layout.VBox?> 
<VBox xmlns="http://javafx.com/javafx" 
     xmlns:fx="http://javafx.com/fxml" 
     fx:controller="stackoverflow.one.ComponentController"> 

</VBox> 

它的控制器,它包含一個實體:

public class ComponentController implements Initializable{ 

    private Entity entity; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 

    } 

    public Entity getEntity() { 
     return entity; 
    } 

    public void setEntity(Entity entity) { 
     this.entity = entity; 
    } 
} 

您還可以更改ROOR這樣的:

<?import javafx.scene.layout.AnchorPane?> 
<AnchorPane xmlns="http://javafx.com/javafx" 
      xmlns:fx="http://javafx.com/fxml" 
      fx:controller="stackoverflow.one.RootController"> 
    <fx:include source="ComponentController.java" fx:id="component"/> 

</AnchorPane> 

然後在控制器中,您可以獲得ComponentController的引用,您可以設置實例,例如您從服務中獲得的實體。

public class RootController implements Initializable { 

    @FXML 
    private ComponentController componentController; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 
     // getting Entity from a service or from any other sources 
     //You may replace this line with an appropriate one for you. 
     Entity entity = getEntity(); 
     componentController.setEntity(entity); 
    } 
} 

現在你已經分開控制器和視圖組件,事件並不需要,因爲FXMLLoader確實爲你加載它們。 這將是如何將對象傳遞給其他視圖的控制器的基本概念。