web-dev-qa-db-ja.com

FXコントローラーをメインアプリに接続する方法

メインアプリクラスとfxmlControllerクラスがありますが、接続/整理(これらがどのように呼び出され、GUIで接続されたビジネスロジックにするために整理する必要があるか)ビジネスロジックとGUIに巻き込まれています。誰かが次の関数が呼び出される順序を教えてもらえますか、または誰かが私がそれらを呼び出す方法を助けることができますか?

メインクラス:

_public void Main()        //constructor
public static void main() // our main
public void start()       //I don't know what it is, what purpose it has
                          // and where should be called
                          //Note: In main function there is a call as following
_

fxmlControllerクラス:

_public void initialize()  //I don't know what it is and what purpose it has
public fxmlController()   // which function should be called here....
_

注:FXMLLoader();について知っています。誰か説明してください

8
khan

FXMLファイルとそれに対応するコントローラーは、ユーザーインターフェイスを管理するペアとして考えます。より大きなアプリケーションでは、ユーザーインターフェイスのさまざまな部分を構成するFXMLとコントローラーのペアがいくつかある場合があります。各ペア内で、FXMLファイルはUIのレイアウトを定義し、コントローラーはロジックを定義します(つまり、通常、ユーザー入力を処理します)。

FXMLLoaderについて知っている」とおっしゃっていましたが、それを完全に理解すれば、質問した他のことのいくつかを実際に理解することになります。

FXMLファイルとそのコントローラーによって定義されたユーザーインターフェイスは、FXMLLoaderによってメモリに読み込まれます。最も簡単な設定では、コントローラーはFXMLファイルのルート要素の_fx:controller_属性によって定義されます。 load()メソッドがFXMLLoaderで呼び出されると、次のようになります。

  1. FXMLファイルをロードします
  2. 引数のないコンストラクターを呼び出して、_fx:controller_属性で指定されたコントローラークラスのインスタンスを作成します。
  3. コントローラ内の_@FXML_注釈付きフィールドの値を、一致する_fx:id_属性で定義された要素に設定します
  4. コントローラーのメソッドにマッピングするイベントハンドラーを登録します。
  5. コントローラーのinitialize()メソッドを呼び出します(存在する場合)。

これらのイベントの順序に注意してください。コンストラクタが呼び出されますbefore _@FXML_- annotatedフィールドが挿入されますが、initialize()メソッドが後に呼び出されます。つまり、initialize()メソッドの_@FXML_アノテーション付きフィールドにアクセス(および構成)できますが、コンストラクターではできません。 (少なくとも単純なアプリケーションでは)コントローラークラスでコンストラクターを定義せず、デフォルトを使用するのが一般的です。

アプリケーションには、必要な数だけFXML /コントローラーのペアを含めることができます。各FXMLファイルには、独自のコントローラークラスが必要です。それが定義するUIの複数のインスタンスが必要な場合は、FXMLファイルを必要な回数だけロードできます。つまり、FXMLLoaderは、ロードしたUI要素に関連付けられた新しいコントローラーインスタンスを作成します。

Applicationサブクラス(これをMainと呼びます)は、アプリケーション全体を表します。アプリケーションごとにそのようなクラスを1つだけと、そのインスタンスを1つだけ持つ必要があります。これは、FXツールキットによって作成されます。

FXアプリケーション(以下で説明します)を起動すると、FXツールキットが起動します。次に、Applicationサブクラスのインスタンスが作成され、そのinit()メソッドが呼び出されます(定義しない場合、デフォルトの実装は何もしません)。次に、FXアプリケーションスレッドが開始され、そのスレッドでApplicationサブクラスインスタンスのstart()メソッドが呼び出されます。

start()メソッドは、最小限の作業を行う必要があります。通常は、「メイン」のfxmlファイルを読み込み、結果のUIをシーンに配置し、シーンをステージに配置して、ステージを表示します。すべてのロジックは、Applicationサブクラスではなく、FXMLファイルのコントローラーによって処理されます。

より高度なアプリケーションでは、バックグラウンドサービスを開始したり、init()メソッドでデータモデルを作成したり、start()メソッドでコントローラーに接続したりできますが、上記のアイデアは基本です。

実際の起動プロセスは、いくつかの方法で発生する可能性があります。標準のOracle JREを使用している場合は、Applicationサブクラスを

_Java Main
_

(ここで_Main extends Application_)は、上記のプロセスを発生させます。つまり、FXツールキットが開始され、Mainのインスタンスが作成され、そのinit()メソッドが呼び出され、そのstart()メソッドがFXアプリケーションスレッドで呼び出されます。

他の環境(特にIDE)はJavaFX起動プロセスを認識せず、実行しているクラスには、標準のJavaアプリケーションクラスのように、public static void main(String[] args)メソッドがあることを期待します。これらの環境をサポートするには、Applicationサブクラスがmain(...)を単に呼び出すlaunch(...)メソッドを定義するのが一般的です(Applicationから継承された静的メソッド) )launchメソッドは、FXツールキットを強制的に起動します。これは、アプリケーションの有効期間中に一度だけ呼び出すことができます。

だから今あなたは次のようなものを持っています:

_package com.example ;

// imports...

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        // just load fxml file and display it in the stage:

        FXMLLoader loader = new FXMLLoader(getClass().getResource("mainUI.fxml"));
        Parent root = loader.load();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    // main method to support non-JavaFX-aware environments:

    public static void main(String[] args) {
        // starts the FX toolkit, instantiates this class, 
        // and calls start(...) on the FX Application thread:
        launch(args); 
    }
}
_

次に、mainUI.fxmlを作成します。

_<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import Java.util.ArrayList?>

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.MyController">
    <Label  fx:id="label1"/>
    <Label  fx:id="label2"/>
</VBox>
_

そしてコントローラー

_package com.example ;

// imports...

public class MyController {

    @FXML
    private Label label1 ;
    @FXML
    private Label label2 ;

    // called by the FXML loader after the labels declared above are injected:
    public void initialize() {

        // do initialization and configuration work...

        // trivial example, could also be done directly in the fxml:
        label1.setText("Foo");
        label2.setText("Bar");
    }
}
_
47
James_D

コントローラーは、fxmlファイル、またはメインビューを初めて呼び出す場所にバインドされています。

したがって、ランチャーからxmlの_fx:controller_属性またはFXMLLoader#setController()メソッドを使用できます。

2
antoniodvr