2017-03-28 15 views
0

機能渡すクラスのパラメータとして名前、私は以下のいる

public void loadWindowAndSendDataTest(String path, String appName, ConnectionData connectionData) { 
    try { 
     Stage subWindow = new Stage(); 
     subWindow.initModality(Modality.APPLICATION_MODAL); 
     FXMLLoader loader = new FXMLLoader(); 
     Parent parent = loader.load(getClass().getResource(path).openStream()); 
     ExitController exitController = (ExitController) loader.getController(); 
     exitController.getConnectionData(connectionData); 

     Scene scene = new Scene(parent); 

     subWindow.setScene(scene); 
     subWindow.setTitle(appName); 
     subWindow.show(); 
    } catch(IOException e) { 
     e.printStackTrace(); 
    } 

そして、何私がachiveしたいので、それは希望、私は(この場合はExitControllerで)クラス名を渡すことができ、より一般的な機能を持つことですこのような何かのように:

public void loadWindowAndSendDataTest(String path, String appName, ConnectionData connectionData, String className) { 
    try { 
     Stage subWindow = new Stage(); 
     subWindow.initModality(Modality.APPLICATION_MODAL); 
     FXMLLoader loader = new FXMLLoader(); 
     Parent parent = loader.load(getClass().getResource(path).openStream()); 
     /* do sth with className to obtain UsedClassController class */ 
     UsedClassController usedClassController = (UsedClassController) loader.getController(); 
     usedClassControler.getConnectionData(connectionData); 

     Scene scene = new Scene(parent); 

     subWindow.setScene(scene); 
     subWindow.setTitle(appName); 
     subWindow.show(); 
    } catch(IOException e) { 
     e.printStackTrace(); 
    } 

仮定私は、この関数に渡しているクラスがgetConnectionData()のfuctionを実装しているということです。これを行う方法はありますか?

+0

でこれを呼び出します。メソッド 'getConnectionData()'を呼び出すことができます。クラス名の背後にあるクラスがそのインターフェイスであるかどうかを確認してから、安全に呼び出すことができます。 –

+0

どうしたらクラス名をパラメータとして渡すことができますか? feを行う機能鋳造? –

+0

クラスオブジェクトを取得するには:Class(String)を取得した場合は、クラス String.class'を使用できます。オブジェクト(たとえばobj)がある場合は、クラス obj.getClass() '.....を使用して、クラスオブジェクトで関数Class.getName()を使用できる名前を取得します。クラスを再びクラスに変換するには、Class.forName(String)を使用することができます。 –

答えて

1

を使用することができます。

public void loadWindowAndSendDataTest(String path, String appName, ConnectionData connectionData) { 
    try { 
     Stage subWindow = new Stage(); 
     subWindow.initModality(Modality.APPLICATION_MODAL); 
     FXMLLoader loader = new FXMLLoader(); 
     Parent parent = loader.load(getClass().getResource(path).openStream()); 
     Object controller = loader.getController(); 
     Method getConnectionDataMethod = 
      controller.getClass().getMethod("getConnectionData", ConnectionData.class); 
     getConnectionDataMethod.invoke(controller, connectionData); 

     Scene scene = new Scene(parent); 

     subWindow.setScene(scene); 
     subWindow.setTitle(appName); 
     subWindow.show(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

これは特に頑強で優雅なアプローチではありません。

public interface ConnectionDataProvider { 

    public void getConnectionData(ConnectionData data) ; 

} 

とあなたのコントローラは、そのメソッドを実装持っている:

public class ExitController implements ConnectionDataProvider { 

    public void getConnectionData(ConnectionData data) { 
     // ... 
    } 

    // existing code ... 
} 

を次に、あなただけのコントローラがそのメソッドを実装するクラスからであると仮定することができますおそらく、より良いgetConnectionData方法とのインタフェースを定義することです

public void loadWindowAndSendDataTest(String path, String appName, ConnectionData connectionData) { 
    try { 
     Stage subWindow = new Stage(); 
     subWindow.initModality(Modality.APPLICATION_MODAL); 
     FXMLLoader loader = new FXMLLoader(); 
     Parent parent = loader.load(getClass().getResource(path).openStream()); 
     ConnectionDataProvider controller = loader.getController(); 
     controller.getConnectionData(connectionData); 

     Scene scene = new Scene(parent); 

     subWindow.setScene(scene); 
     subWindow.setTitle(appName); 
     subWindow.show(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

いずれの方法も、コントローラのタイプ(クラス)を渡す必要はありません。あなたは、実際にいくつかの理由のために、あなたは(インタフェース・アプローチを使用して)次の手順を実行できることが必要な場合:

public <T extends ConnectionDataProvider> void loadWindowAndSendDataTest(
     String path, String appName, 
     ConnectionData connectionData, Class<T> controllerType) { 

    try { 
     Stage subWindow = new Stage(); 
     subWindow.initModality(Modality.APPLICATION_MODAL); 
     FXMLLoader loader = new FXMLLoader(); 
     Parent parent = loader.load(getClass().getResource(path).openStream()); 
     T controller = loader.getController(); 

     // if you wanted to cast explicitly here, you could do: 
     // T controller = controllerType.cast(loader.getController()); 

     controller.getConnectionData(connectionData); 

     // do something with controllerType if you need.... 

     Scene scene = new Scene(parent); 

     subWindow.setScene(scene); 
     subWindow.setTitle(appName); 
     subWindow.show(); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

、その後、あなたも、あなたが持っているインタフェースを書くことができ

loadWindowAndSendDataTest("/path/to/fxml", "Application Name", 
    connectionData, ExitController.class); 
1

メソッドgetConnectionData()でインターフェイスを作成し、UsedClassControllerクラスでこのインターフェイスを実装する必要があります。

クラス名を取得するには、クラスオブジェクトのgetSimpleName()を使用してください。 BigDecimalの例:

BigDecimal.class.getSimpleName(); 

BigDecimalを返します。 あなたがパッケージに名前を取得したい場合、あなたは、コントローラクラスがgetConnectionData(ConnectionData)メソッドを実装していると仮定している場合は、あなただけのそのメソッドを呼び出すためにリフレクションを使用することができgetCanonicalName()

+0

'String Class.getSimpleName()'は、パッケージがないので、 'String Class.getName()'を使用することをお勧めします。 –

+1

私の投稿を編集しましたが、あなたの解決策も大丈夫です – Araneo

関連する問題