JavaFXでMVCの練習を兼ねて簡単なアプリを作っているのですが、うまく作れません。  
特にViewの入力をControllerに伝えるのが上手くできません。

以下が今作っているソースですが、View内でsetOnActionして、idと共にControllerへ渡すという方法をとってます。ただ、これだとViewがControllerのインスタンスを持っていないため、Controllrer側の受け取るメソッドをstaticにする必要があり、そこからModelのメソッドを呼ぶとstaticのものしか使えないという連鎖が起きてしまい困っています。

対応策としては、

  * ControllerのインスタンスをViewに渡す ・・・MVC的に...?
  * ControllerのコンストラクタでModelのインスタンスを作っておく ・・・static内で読んでいるので、結局詰んでる

というのを考えたのですが、よくよく考えると問題があるように感じました。  
そもそもControllerに渡す方法自体怪しく思えてきました。  
どなたかアドバイスを頂けないでしょうか。  
よろしくお願いします。

ちなみに、今回はfxmlの使用予定はないです。  
また、以下のコードは長いのでimportを省略してます。

* * *

MainController

```

    public class MainController extends Application {
        public static Stage stage;
        @Override
        public void start(Stage primaryStage) {
            //初期設定
            primaryStage.setWidth(1000);
            primaryStage.setHeight(500);
            primaryStage.setTitle("タイトル");
            primaryStage.show();
    
            stage = primaryStage;
            new MainView(primaryStage);//画面表示
        }
    
        //ボタン処理
        public static void inButton(Event e, String id){
            switch (id) {
            case "0"://マイページ
                break;
            case "1"://計算ページ
                new CalController(stage);
                break;
         }
    
        public static void main(String[] args) {
          launch(args);
        }
    }
    
```

* * *

MainView

```

    public class MainView {
        EcMainView(Stage stage) {
            VBox root = new VBox();
            Button[] button = new Button[2];
            button[0] = new Button("マイページ");
            button[1] = new Button("計算");
            for(int i=0; i<2; i++){
                int tmpI = i;
                button[tmpI].setId(""+tmpI);
                button[tmpI].setOnAction(e ->EcMainController.inButton(e,button[tmpI].getId()));
            }
            root.getChildren().addAll(button);
            stage.setScene(new Scene(root));
        }
    }
    
```

## \----------

CalController

```

    public class CalController {
        private Stage stage;
        private CalView calView;
        private CalModel calModel;
        CalController(Stage stage) {
            this.stage = stage;
            calView = new CalView(stage);// 表示
            calModel = new CalModel();
        }
        public static void inButton(Event e, String id) {
            switch (id) {
            case "0":// ファイル選択
                /*----この辺が特に困る----*/
                CalModel.getFileList();
                break;
            case "1":// 編集
                break;
            }
        }
    }
    
```

* * *

CalView

```

    public class CalView {
        CalView(Stage stage){
            calViewMain(stage);
        }
        void calViewMain(Stage stage){
            VBox root = new VBox();
            Button[] button = new Button[2];
            button[0] = new Button("ファイル読み込み");
            button[1] = new Button("編集");
            //ボタンの共通初期設定
            for(int i=0; i<button.length; i++){
                int tmpI = i;
                button[i].setId(i + "");
                button[i].setOnAction(e -> CalController.inButton(e, button[tmpI].getId()));
            }
            HBox hBox = new HBox();
            hBox.getChildren().addAll(button);
            //表示
            root.getChildren().addAll(hBox);
            stage.setScene(new Scene(root));
        }
    }
    
```

* * *

CalModel

```

    public class CalModel {
        static String filePath = "data";
        public static String[] getFileList() {
            String[] list;
            readText();
            //リスト化
            return list;
        }
        public static String readText() {
            String text = "";
                //ファイル読み込み
            return text;
        }
    }
    
```
CC BY-SA 3.0
2016-12-01T15:16:15.203
30817
2016-12-03T13:11:30.143
2016-12-01T15:33:33.643
19793
19793
question
java mvc javafx
JavaFX MVC クラス・メソッドについて
java swingでのmvcを参考にして自己解決しました。  
具体的には

  * View  
Modelのインスタンスを持たせる  
ボタン系を取得できるメソッドを用意

  * Controllrer  
Viewのボタン系の取得できるメソッドを呼んで、リスナ登録(setOnAction)  
View, Modelはインスタンス生成して、Viewにmodelのインスタンスを紐付け

といった感じにしました。

主な参考サイト  
<http://d.hatena.ne.jp/dounanda/20110505/1304586226>

* * *

Controller

```

    public class ExamCalC {
        ExamCalV calV;
        ExamCalM calM;
        ExamCalC(Stage stage){
            calV = new ExamCalV(stage);
            calM = new ExamCalM();
            calV.bindModel(calM);
            //ボタン時の動作
            calV.getButton(0).setOnAction(e -> button1());//ボタン1
            calV.getButton(1).setOnAction(e -> button2());//ボタン2
        }
        void button1(){}
        void button2(){}
    }
    
```

* * *

View

```

    public class ExamCalV {
        ExamCalM calM;
        private Button[] button;
        private BorderPane root;
        private VBox vBoxScore;
        private AnchorPane topBar;
        private AnchorPane bottomBar;
    
        ExamCalV(Stage stage){
            root = new BorderPane();
            //ボタン
            button = new Button[4];
            button[0] = new Button("1");
            button[1] = new Button("2");
            button[2] = new Button("3");
            button[3] = new Button("4");
            //ボタンの共通初期設定
            for(int i=0; i<button.length; i++){
                button[i].setId(i + "");
            }
    
            //上のボタン
            AnchorPane.setLeftAnchor(button[0], 10.0);
            AnchorPane.setRightAnchor(button[1], 10.0);
            topBar = new AnchorPane();
            topBar.getChildren().addAll(button[0],button[1]);
    
            //中央のレイアウト
            vBoxScore = new VBox();
    
            //下のボタン
            AnchorPane.setLeftAnchor(button[2], 10.0);
            AnchorPane.setRightAnchor(button[3], 10.0);
            bottomBar = new AnchorPane();
            bottomBar.getChildren().addAll(button[2],button[3]);
            //表示
            root.setTop(topBar);
            root.setCenter(vBoxScore);
            root.setBottom(bottomBar);
            stage.setScene(new Scene(root));
        }
        Button getButton(int id){
            for(int i=0; i<button.length; i++){
                    if(button[i].getId().equals(id + "")){
                    return button[i];
                }
            }
            return null;
        }
        //参照modelの設定
        void bindModel(ExamCalM calM){
            this.calM = calM;
        }
    }
    
```
CC BY-SA 3.0
2016-12-03T13:11:30.143
30871
2016-12-03T13:11:30.143
19793
30817
answer