2015-08-24 21 views
3

我正在使用Java 8桌面應用程序使用JavaFX 8
我在MainApp類(擴展應用程序類的那個)中有此方法。如何編寫接受類類型作爲參數並使用它來投射某些對象的方法

public void showUserLayout() { 
    try { 
     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(MainApp.class.getResource("view/userLayout.fxml")); 
     AnchorPane userPane = (AnchorPane) loader.load(); 

     rootAnchorPane.getChildren().clear(); 
     rootAnchorPane.getChildren().add(userPane); 

     userLayoutController controller = loader.getController(); 
     controller.setMainApp(this); 
    } catch (IOException e) { 
     // Handle Exception 
    } 
} 

我對每個我想要加載的佈局使用相同的代碼。

有什麼辦法來創建一個接受類類型作爲參數並做完全相同的工作,例如方法:

public void genericLayoutLoader(String fxmlFilename, Class rootFXMLElement, Class fxmlController) { 
    try { 
     FXMLLoader loader = new FXMLLoader(); 
     loader.setLocation(MainApp.class.getResource(fxmlFilename)); 
     // Not sure for the Object below 
     Object chooseUserAndInterval = (rootFXMLElement) loader.load(); 
     // rootAnchorPane is same for every layout 
     rootAnchorPane.getChildren().clear(); 
     rootAnchorPane.getChildren().add((rootFXMLElement) chooseUserAndInterval); 

     Object controller = (fxmlController) loader.getController(); 
     ((fxmlController)controller).setMainApp(this); 
    } catch (IOException e) { 
     // Handle Exception 
    } 
} 

我會用這樣的:

public void showUserLayout() { 
    genericLayoutLoader("view/userLayout.fxml", AnchorPane, userLayoutController); 
} 

有什麼辦法可以實現這種行爲?

+3

難道你不能通過讓所有人都實現一些通用接口來解決它嗎? – KDM

+0

你的意思是類似[在這個答案](http://stackoverflow.com/questions/14524751/cast-object-to-generic-type-for-returning/14524815#14524815)? – SpaceTrucker

+0

@KDM'showSomeLayout'方法全部在MainApp類中定義。所以,考慮到這一點,我認爲這不可行,對吧? – Chris

回答

1

如果你要堅持使用類作爲參數,你的代碼應該看起來有點像這樣:

public void genericLayoutLoader(String fxmlFilename, Class rootFXMLElement, Class fxmlController) { 
     try { 
      FXMLLoader loader = new FXMLLoader(); 
      loader.setLocation(MainApp.class.getResource(fxmlFilename)); 
      // Not sure for the Object below 
      Object chooseUserAndInterval = loader.load(); 
      // rootAnchorPane is same for every layout 
      rootAnchorPane.getChildren().clear(); 
      rootAnchorPane.getChildren().add(chooseUserAndInterval); 

      Object controller = loader.getController(); 
      fxmlController.getMethod("setMainApp", new Class[] { MainApp.class }).invoke(controller, this); 
     } catch (IOException e) { 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      e.printStackTrace(); 
     } catch (NoSuchMethodException e) { 
      e.printStackTrace(); 
     } catch (SecurityException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void showUserLayout() { 
     genericLayoutLoader("view/userLayout.fxml", AnchorPane.class, Controller.class); 
    } 

不過,我還是建議嘗試解決這個ü如果可能的話唱歌接口

+0

我正在嘗試這個,因爲我發佈了這個問題,但無法通過調用setMainApp方法。我試過你的方式,並且我得到了'java.lang.NoSuchMethodException:com.nomad.view.userLayoutController.setMainApp()'。你能指出我如何使用接口來做到這一點? – Chris

+0

'setMainApp'的簽名是什麼? – KDM

+0

它是'public void setMainApp(MainApp mainApp)' - 謝謝你的時間! – Chris

0

您可以使用接口作爲方法中的參數。然後在調用該方法時將該接口的實現作爲參數傳遞。

interface Loader { 
    void load(); 
} 

interface Controller { 
    void setMainApp(Object mainApp); 
} 

這裏是實現加載程序接口的類:

class AnchorPane implements Loader { 
    void load() { 
     System.out.println("Loading..."); 
    } 
} 

這裏是實現控制器接口的類:

class UserLayoutController implements Controller { 
    void setMainApp(Object mainApp) { 
     System.out.println("Setting main app..."); 
    } 
} 

更改方法定義的:

public void genericLayoutLoader(String fxmlFilename, Loader loader, Controller controller) { 
    try { 
     FXMLLoader fxmlLoader = new FXMLLoader(); 
     fxmlLoader.setLocation(MainApp.class.getResource(fxmlFilename)); 

     // rootAnchorPane is same for every layout 
     rootAnchorPane.getChildren().clear(); 
     rootAnchorPane.getChildren().add(loader); 

     controller.setMainApp(this); 
    } catch (IOException e) { 
     // Handle Exception 
    } 
} 

然後某處調用它在你的代碼:

genericLayoutLoader("view/userLayout.fxml", new AnchorPane(), new UserLayoutController()); 
+0

1。在JavaFX中,提供了AnchorPane類,我不擴展它,而只是將它用作成員。所以'loader接口'將在每個控制器中實現?在那種情況下,這意味着每個控制器都有一個新的加載方法。我想避免創建方法來做同樣的事情,只能使用不同的對象。 2.我認爲這行'rootAnchorPane.getChildren()。add(loader);'並不等同於從FXML加載器加載它後傳遞實際的AnchorPane對象。但是,我可能會忘記這個符號,因爲我還沒有用過Java的經驗。 – Chris

+0

[2-continue]另外,加載器接口有一個不返回任何內容的方法,那麼'.add(loader)'將如何工作? – Chris

0

1)爲對象,你不知道的類型,可以考慮使用通配符。

請參閱本:When to use generic methods and when to use wild-card?

2)一旦你的對象,現在你可以使用實例操作來檢查對象的類型,並執行特定的步驟,以這個對象,如: -

if(object instanceof AnchorPane){ 
//do this 
} else if(object instance of BorderPane){ 
//do this 
} 
相關問題