10

私はjava(fx)の初心者です。
JavaFXでマウスの位置をxとyで取得するにはどうすればよいですか? AWT を使用してみMouseInfoました (これもインポートしました) が、機能しません。Ensembles でそのコードも見ました(「高度なステージ」でボールウィンドウをドラッグする、それが私がする必要があることです、装飾されていない JavaFX ステージをドラッグします)が、それも機能しません。私はコントローラーで FXML を使用していますが、それが主な問題だと思います。単一ファイルの単純な JavaFX に戻す必要がありますか? UI のレイアウトには FXML の方が適していることはわかっていますが、そのようなコードの多くを機能させることができません。または、コントローラーに他の種類のコードが必要ですか? 可能な限りコメント付きで適切なコードを入力してください。
調べるために私のコードが少し必要な場合は、お気軽にお問い合わせください。

4

3 に答える 3

29

あなたの質問にはいくつかの項目があります。一度に 1 つずつ取り組みます。

JavaFXでマウスの位置をxとyで取得するにはどうすればよいですか?

マウスの位置を追跡する適切な JavaFX コンポーネントにマウス イベント ハンドラーを追加します。JavaFX マウス イベントは、複数の異なる種類の座標を報告します。x 座標と y 座標は、位置が監視されているノードの左上隅を基準にしています。シーン X とシーン Y の座標は、シーンの左上の 0,0 座標を基準にしています。screenX と screenY の座標は、現在の画面の左上の 0,0 座標を基準にしています。

これらの座標は、MouseEventのドキュメントに記載されています。ノードシーンのドキュメントには、座標系を理解するための追加情報があります。

マウス位置モニター

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.stage.*;

public class MouseLocationReporter extends Application {
  private static final String OUTSIDE_TEXT = "Outside Label";

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

  @Override public void start(final Stage stage) {
    final Label reporter = new Label(OUTSIDE_TEXT);
    Label monitored = createMonitoredLabel(reporter);

    VBox layout = new VBox(10);
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10px;");
    layout.getChildren().setAll(
      monitored,
      reporter
    );
    layout.setPrefWidth(500);

    stage.setScene(
      new Scene(layout)
    );

    stage.show();
  }

  private Label createMonitoredLabel(final Label reporter) {
    final Label monitored = new Label("Mouse Location Monitor");

    monitored.setStyle("-fx-background-color: forestgreen; -fx-text-fill: white; -fx-font-size: 20px;");

    monitored.setOnMouseMoved(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent event) {
        String msg =
          "(x: "       + event.getX()      + ", y: "       + event.getY()       + ") -- " +
          "(sceneX: "  + event.getSceneX() + ", sceneY: "  + event.getSceneY()  + ") -- " +
          "(screenX: " + event.getScreenX()+ ", screenY: " + event.getScreenY() + ")";

        reporter.setText(msg);
      }
    });

    monitored.setOnMouseExited(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent event) {
        reporter.setText(OUTSIDE_TEXT);
      }
    });

    return monitored;
  }
}

AWT の MouseInfo を使ってみました(インポートもしました)が、うまくいきません。

これをしないでください。異なるグラフィカル ツールキット (Swing/AWT と JavaFX など) を混在させることは、高度なトピックです。一般に、JavaFX アプリケーションを作成している場合は、java.awt名前空間と名前空間から何もインポートしないでくださいjavax.swing。これらを実際に使用する必要があるのは、JavaFX アプリケーションと相互運用する必要がある大規模な既存の Swing ベースのアプリケーションまたはフレームワークがある場合のみです。この場合、そのような状況はありません。

Ensembles でそのコードも見ました(「高度なステージ」でボールウィンドウをドラッグする、それが私がする必要があることです、装飾されていない JavaFX ステージをドラッグします)が、それも機能しません。

Ensemble Advanced Stage サンプルを試してみたところ、そのステージをドラッグするだけでうまくいきました。

JavaFX で装飾されていないステージをドラッグする別のサンプルは、How to draw a clock with JavaFX 2? への回答にあります。サンプルコードが関連付けられています。時計サンプルの装飾されていないステージをドラッグ可能にするために使用される方法は次のとおりです。

/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
  final Delta dragDelta = new Delta();
  byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
      // record a delta distance for the drag and drop operation.
      dragDelta.x = stage.getX() - mouseEvent.getScreenX();
      dragDelta.y = stage.getY() - mouseEvent.getScreenY();
      byNode.setCursor(Cursor.MOVE);
    }
  });
  byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
      byNode.setCursor(Cursor.HAND);
    }
  });
  byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
      stage.setX(mouseEvent.getScreenX() + dragDelta.x);
      stage.setY(mouseEvent.getScreenY() + dragDelta.y);
    }
  });
  byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
      if (!mouseEvent.isPrimaryButtonDown()) {
        byNode.setCursor(Cursor.HAND);
      }
    }
  });
  byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
      if (!mouseEvent.isPrimaryButtonDown()) {
        byNode.setCursor(Cursor.DEFAULT);
      }
    }
  });
}

私はコントローラーで FXML を使用していますが、それが主な問題だと思います。単一ファイルの単純な JavaFX に戻す必要がありますか? UI のレイアウトには FXML の方が適していることはわかっていますが、そのようなコードの多くを機能させることはできません。

おそらく、FXML の使用よりも、基盤となる JavaFX API に対する理解と慣れの欠如が主な問題です。ただし、fxml が意味する追加の複雑さは、Web 上のより軽量なドキュメントやサンプルと相まって、あなたの困難に貢献している可能性があります。FXML を使用すると、一部の JavaFX 関数を動作させる方法を理解するのが難しくなる場合は、今のところ FXML の使用を停止することをお勧めします。Java API を使用して手動でロジックをコーディングし、難しい問題に遭遇した場合は 、 Oracle JavaFX チュートリアルEnsemble サンプル コードを参照してください。

JavaFX API に直接コーディングできるようになったら、多くの GUI 要素を含む大規模なプロジェクトで FXML の使用に切り替えます。FXML 要素と属性自体は、標準の JavaFX API を反映してほぼ完全に構築されています。したがって、コア JavaFX API を理解すれば、FXML に関するほとんどすべてを理解することにもなります。

この回答にフォローアップのコメントを投稿しないでください (この回答はそのままで十分に長いため)。新しい質問がある場合は、新しい質問を作成します (質問ごとに 1 つの質問)。

于 2013-05-20T21:59:26.683 に答える