簡體   English   中英

JavaFx從單個FXML生成多個場景

[英]JavaFx Generate multiple scene from single FXML

我啟動了一個與數據庫交互的javafx項目(添加,編輯,刪除,查找等)。
我的數據庫包含很多表,每個表需要自己的場景(幾乎相同!!!)。
所以我的問題是:不是實現〜20 fxml文件,而是可以制作一個單獨的fxml文件,該文件將根據傳遞給其控制器的類名(例如)來更改其內容?
如果是,有什么技巧可以實現嗎?
這是我嘗試過的:
為每個TableClass添加了一個HashMap,其中包含場景中所需的所有屬性,並在ControllerClass中對其進行迭代以將控件添加到場景中! 但是失敗了!
TableSampleClass:

public class TableSampleClass{
public static final HashMap<String, String> attr;
static {
    attr = new HashMap<String, String>();
    attr.put("ref", "text");
    attr.put("name", "text");
    attr.put("adress", "text");
    attr.put("Mobile", "tel");
    attr.put("mail", "mail");
    attr.put("isalive", "checkbox");//just to illustrate what i want !
    }
     ........
   }

ControllerClass:

@FXML
private AnchorPane pane;
@Override
public void initialize(URL location, ResourceBundle resources)
{     Iterator it = TableSampleClass.attr.entrySet().iterator();
    while(it.hasNext())
    {
        Map.Entry pair = (Map.Entry)it.next();
        switch (pair.getValue().toString()){
        case "text":
            TextField txt =new TextField(pair.getValue().toString());
            txt.setPromptText(pair.getKey().toString());
            Label lbl =new Label(pair.getKey().toString());
            pane.getChildren().add(txt);
            break;
        }
    }
}

我希望我確實清楚地解釋了自己!

使用自定義組件FXML模式 它的工作方式是編寫一個控制器類,該類將相應的FXML文件加載到構造函數中。 由於通過調用構造函數來使用此功能,因此可以允許構造函數獲取參數,並在加載FXML之后使用這些參數來配置組件。

您顯示的代碼對我來說不是很清楚,但是這種結構看起來像:

public class MyCustomTableDisplay extends AnchorPane {

    @FXML
    private AnchorPane pane ;

    public MyCustomTableDisplay(Map<String, String> config) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
            loader.setRoot(this); 
            loader.setController(this);
            loader.load();
        } catch (IOException exc) {
            throw new RuntimeException(exc);
        }

        // now configure pane based on config passed in...
    }
}

FXML文件必須使用“動態根”,這意味着根元素是通過在FXMLLoader上調用setRoot(...)FXMLLoader (如上面的代碼所示)。 所以看起來

<!-- imports omitted -->
<fx:root type="AnchorPane" xmlns:fx="..." ... >
    <!-- usual fxml stuff -->
    <AnchorPane fx:id="pane" ...>

    <AnchorPane>
</fx:root>

現在你要做

Map<String, String> config = new HashMap<>();
// populate config...
MyCustomTableDisplay display = new MyCustomTableDisplay(config);
Scene scene = new Scene(display);
// etc...

type的的fx:root可以是基本上任何節點類型,但必須類的類型相匹配。 然后,您可以包含所需的任何fxml內容。 該類充當控制器,因此您可以按常規方式從FXML注入值:在加載程序上調用load()方法時,它們將被初始化(照常)。

潛在方法

有一些第三方庫可以為JavaFX動態生成表單和界面UI,例如FXForm2ControlsFX PropertySheets

也可以從數據動態生成 ,這似乎是您實際上要嘗試執行的操作。

在FXML上

對於大多數這些系統,您無需使用FXML定義小部件的內部GUI。 相反,可以通過對數據或Java類進行自省來動態生成低級字段。 您要做的就是將適當的庫添加到SceneBuilder中,並導入高級控件(例如ControlsFX PropertySheet),僅在FXML中聲明,而不在FXML中定義控件的詳細字段。

如果需要,並且鏈接庫中的系統不是您所需要的,則您還可以創建自定義控件並將其導入在SceneBuilder中使用 ,盡管它們仍然可能以類似的方式工作,即從數據或數據中動態生成詳細信息字段。通過反射進行 Java類自省。

通過自省生成動態場

基於反射創建自定義控件是一個高級主題,僅建議有經驗的Java和JavaFX開發人員使用。 您可以查看PropertySheet實現的示例代碼,以了解這種方法,該方法通過BeanPropertyUtils實用程序類使用Java BeanIntrospector Java bean是一個很大的話題,在這里我無法詳細介紹。 只有Java Bean規范的某些功能才能實現所需的功能,因為該規范的其他部分已被較新的JavaFX功能(如屬性和綁定)所取代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM