web-dev-qa-db-ja.com

JavaFXのコントローラーファイルのステージで関数を呼び出す方法

fxmlを使用に沿ってjavafxを使用しているので、実際のコーディング用のコントローラーを使用します。 x軸またはy軸の位置を取得するなど、ステージ上でいくつかの操作を行う必要があります。 stage.getX()stage.getYを試しましたが、機能しません(ステージ名がエラーとして強調表示されます)。コントローラでこのような機能を使用するにはどうすればよいですか?メインファイルでこれを試してみました:

 public int locationX = stage.getX();

そして

public double locationX = stage.getX();

しかし、それは機能せず、代わりにプログラム全体を1つの大きなエラーにします。
では、コントローラーファイルでこのような機能を実行するにはどうすればよいですか?何かをインポートする必要がありますか、それとも上記のようなことを別の方法で行う必要がありますか?

error: cannot find symbol
    locationX = stage.getX();
symbol:   variable stage
location: class FXMLController


「ステージ」が欠落していることを知っています。しかし、どのように私のコントローラーで「ステージ」を取得しますか?

10
Pratik Anand

rootfxmlファイルのペインから:

@FXML
Parent root

あなたはそれからステージを得ることができます:

Stage stage = (Stage) root.getScene().getWindow()

あなたは自分のステージへの参照を持っています、あなたはあなたがやりたいことをすることができます。

25
tarrsalah

サンプルソリューション

次の手法を使用して、コントローラーのステージを初期化できます。 パラメーターの受け渡しJavaFX FXML

これは、ユーティリティウィンドウをドラッグしたときに画面のx座標とy座標を追跡するユーティリティウィンドウを作成するサンプルプログラムです。ユーティリティウィンドウの内容は、fxmlで定義されたペインに表示されます。

stagecoords

StageTrackingSample.Java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.*;

public class StageTrackingSample extends Application {

  @Override public void start(final Stage stage) throws Exception {
    final FXMLLoader loader = new FXMLLoader(
      getClass().getResource(
        "stagetracking.fxml"
      )
    );

    final Parent root = (Parent) loader.load();
    final StageTrackingController controller = loader.getController();
    controller.initData(stage);

    stage.initStyle(StageStyle.UTILITY);
    stage.setResizable(false);
    stage.setScene(new Scene(root));
    stage.show();
  }

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

StageTrackingController.Java

import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.stage.Stage;

public class StageTrackingController {
  @FXML private Label stageX;
  public void initialize() {}  
  public void initData(final Stage stage) {
    stageX.textProperty().bind(
      Bindings.format(
        "(%1$.2f, %2$.2f)", 
        stage.xProperty(), 
        stage.yProperty()
      )
    );
  }
}

stagetracking.fxml

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

<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="30" minWidth="100" xmlns:fx="http://javafx.com/fxml" fx:controller="test.StageTrackingController">
  <Label fx:id="stageX" layoutX="0" layoutY="0"/>
</AnchorPane>

代替ソリューション

コントローラーのルートコンポーネントがすでにステージに追加されているシーンにすでに追加されていることがわかっている場合は、@ FXMLコンポーネントからステージを取得するというtarrsalahの回答も良い方法です(これは、何かが起こった場合によくあることです)。ボタンイベントハンドラーが起動されるように)。

別の方法はtarrsalahの回答に似ていますが、@ FXMLノードのシーンプロパティと変更されたシーンのウィンドウプロパティでChangeListenersを使用します。これにより、ペインが新しいシーンまたはステージに移動した場合に、シーンおよびステージへの変更を追跡できます。ほとんどのペインは1つのステージにとどまる単一のシーンに追加されるだけなので、ほとんどの場合、これらの変更を追跡する必要はありません。

追加の質問とコメントへの回答

もっと簡単な答えを得ることができますか?

tarrsalahはすでにもっと簡単な答えを提供しました。

この場合のより単純な回答の唯一の問題は、回答のソリューションを複製して作業に適応させるために必要な十分なコンテキストが提供されない可能性があることです。

私は現在の答えをできるだけ単純にしましたが、残念ながら、最も基本的なJavaFX FXMLアプリケーションでさえ、機能するにはかなりのコードとマークアップが必要です。

私はJavaの単なる初心者です

最初のJavaおよびJavaFXアプリケーションの開発を開始するときは、FXMLを使用しないでください。代わりに、JavaFXコードの標準 Java API を使用してください。他にもたくさんあります tutorials だけでなく、優れた Ensemble Sample を参照してください。

JavaFXを開始する前に、すべての 基本をカバーするJavaチュートリアルトレイル を完了していることを確認してください。 JavaFXの使用を開始するには、Javaの基本のみが必要です。学習に分岐する必要はなく、Java Enterprise Editionであり、Swingを忘れることができます。

いくつかの基本的なJavaFXアプリケーションを作成し、Java APIに従っていくつかのレイアウトを手動でコーディングし、快適なレベルに達したら、より大きなアプリケーションに SceneBuilder およびFXMLを使用することを検討してください。コアテクノロジーを使用します。その時点で、FXMLの学習は非常に簡単であることに気付くでしょう。FXMLの属性と要素は、Java APIを反映したものにすぎません。

コードの通常以外の部分について説明してください

あなたにとって何が珍しいのかわからないので、私は本当にそれをすることはできません。

自分の知識や調査では理解できないコードの特定の部分がある場合は、 新しいStackOverflowの質問を作成してください 難しい概念ごとに。

14
jewelsea

さて、それに対する最も簡単な答えは...

メインクラスコントローラークラスのインスタンス(オブジェクト)を作成します。



    FXMLLoader loader = new FXMLLoader(getClass().getResource("Example.fxml"));
    MyController controller = loader.getController();
    controller.setStage(this.stage);

コントローラークラスに「抽出」(セッター)のメソッドを配置する必要があります。



    private Stage primaryStage;

    public void setStage(Stage stage) {
         this.primaryStage = stage;
    }

そして、フルスクリーンボタンを追加できます;)



    @FXML
    private Button btnFullScreen = new Button();

    public void setFullscreen(ActionEvent event){       
         if(primaryStage.isFullScreen()){
              primaryStage.setFullScreen(false);
         } else {
              primaryStage.setFullScreen(true);
         }
    }

3

* .FXMLファイルとコントローラーおよびメインまたはイベントではないの場合、これを使用します:

@FXML private Stage stage;
stage = (Stage) elemen.getScene().getWindow();

要素は、FXML内の任意のコントロールまたは要素にすることができます。私の場合はAnchorPaneです。

@FXML  private AnchorPane element;
1

このスレッドは古いですが、偶然に関連するものを発見しました。私が思ったのは、動作するはずのないコーディングエラーでしたが、動作しました。コントローラクラスで、次のメンバー変数を宣言するだけです。

@FXMLプライベートステージステージ。

fxmlドキュメントのウィジェットにアクセスできるのと同じように、コントローラーのステージにアクセスできました。これが当てはまるドキュメントは見つかりませんでしたが、私はJavaFXに慣れていないことを認めます(Swingの古い手ですが)。しかし、それはうまくいくようです。たぶんそれを頼りにするのは危険ですか?

1
Paul

最善のアプローチは、新しいコントローラーを作成し、コンストラクターを介してstageを渡すことです(FXMLファイルでfx:controllerを使用しないでください)。そうしないと、initialize()が呼び出されたときにstagenullになります(その時点で) load()initialize()を呼び出すと、stagesceneに付加されないため、scenestagenullになります。

public class AppEntryPoint extends Application
{
    private FXMLLoader loader;

    @Override
    public void init() throws Exception
    {
        loader = new FXMLLoader(getClass().getResource("path-to-fxml-file"));
    }

    @Override
    public void start(Stage initStage) throws Exception
    {
        MyController controller = new MyController(initStage);
        loader.setController(controller);
        Scene scene = loader.load();
        initStage.setScene(scene);
        initStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
public class MyController
{
    private Stage stage;

    @FXML private URL location;
    @FXML private ResourceBundle resources;

    public MyController(Stage stage)
    {
        this.stage = stage;
    }

    @FXML
    private void initialize()
    {
        // You have access to the stage right here
    }
}
0
Eng.Fouad