質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.49%

Controller同士の参照について

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 1,752

前提のソースコード

// Main.java
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

// Pane1Controller.java
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

public class Pane1Controller {
    @FXML
    private Label label;
    @FXML
    private Button button;

    private SampleController sampleController;

    public SampleController getSampleController() {
        return sampleController;
    }

    public void setSampleController(SampleController sampleController) {
        this.sampleController = sampleController;
    }

    @FXML
    private void onButton(ActionEvent event) {
        label.setText(sampleController.getPane2Controller().getTextField().getText());
    }
}

// Pane2Controller.java
import javafx.fxml.FXML;
import javafx.scene.control.TextField;

public class Pane2Controller {
    @FXML
    private TextField textField;

    private SampleController sampleController;

    public SampleController getSampleController() {
        return sampleController;
    }

    public void setSampleController(SampleController sampleController) {
        this.sampleController = sampleController;
    }

    public TextField getTextField() {
        return textField;
    }
}

// SampleController.java
import javafx.fxml.FXML;
import javafx.fxml.Initializable;

import java.net.URL;
import java.util.ResourceBundle;

public class SampleController implements Initializable {
    @FXML
    private Pane1Controller pane1Controller;

    @FXML
    private Pane2Controller pane2Controller;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        pane1Controller.setSampleController(this);
        pane2Controller.setSampleController(this);
    }

    public Pane1Controller getPane1Controller() {
        return pane1Controller;
    }

    public Pane2Controller getPane2Controller() {
        return pane2Controller;
    }
}
<!-- pane1.fxml -->
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.HBox?>
<HBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
      prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="Pane1Controller">
    <children>
        <Label fx:id="label"/>
        <Button fx:id="button" mnemonicParsing="false" onAction="#onButton" text="Button"/>
    </children>
</HBox>


<!-- pane2.fxml -->
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
      prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
        fx:controller="Pane2Controller">
    <children>
        <TextField fx:id="textField"/>
    </children>
</Pane>

<!-- sample.fxml -->
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
         prefWidth="600.0" tabClosingPolicy="UNAVAILABLE" xmlns:fx="http://javafx.com/fxml/1"
         xmlns="http://javafx.com/javafx/8.0.111"
        fx:controller="SampleController">
    <tabs>
        <Tab text="Pane1">
            <content>
                <fx:include source="pane1.fxml" fx:id="pane1"/>
            </content>
        </Tab>
        <Tab text="Pane2">
            <content>
                <fx:include source="pane2.fxml" fx:id="pane2"/>
            </content>
        </Tab>
    </tabs>
</TabPane>

上記ソースでPane1ControllerからPane2Controllerを参照する上記以外の良い, 汎用性のある書き方は無いでしょうか?

動作環境: JDK8 - 111

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

Pane1/Pane2での情報の共有はそのままにすると仮定しますと、例えば以下のようにしてPane1/Pane2の結合を無くしておくというのはどうでしょう。SampleとPane1の間に新たにインターフェースが生じるので単純に結合度が下がる訳ではないのですが、この文字列情報がPane2ではなく他の場所に置くような変更になったとしてもPane1に影響がない点に価値が見いだせるならありかもしれません。

public class Sample ... {
  ...
  public ObjectProperty<String> somethingProperty() {
    return pane2.somethingProperty();
  }
}

public class Pane1Controller ... {
  ...
  void foo() {
    // Pane2と直接やりとりする代わりにParent(Sample)とのやりとりとしてみる
    ... sampleController.somethingProperty().get() ...
    ...
  }
}

public class Pane2Controller ... {
  ...
  public ObjectProperty<String> somethingProperty() {
    return textField.textProperty();
  }
}

もしこうしたことが多いならTabPaneで分ける情報が充分独立していない点に問題があるのかも知れません。ご質問のコードは実際より単純化してあると思いますので実際の複雑さはわかりませんが、例えばFXMLは分けてControllerは単一にするといった道もあるかも知れません。

Sample, Pane1, Pane2でどんな情報をどう操作したいかにより何に注目して設計したいかが変わってくる気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る