[解決済み] setOnKeyPressed イベントが正しく動作しない
2022-02-16 15:54:18
質問
大学のプロジェクトで、曲線を使ったトンネルのようなものを生成する必要に迫られています。インターネットで、曲線のコントロールポイント(Anchorオブジェクトに付いている)をドラッグできるコードを見つけました。
しかし、矢印キー("up"と"down")でコントロールポイントのY位置を変更できるようにしたかったのですが、なぜか全くうまくいきません。この問題を自分で解決しようと絶望的になっているのですが、出口が見つかりません。
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
/** Example of how a cubic curve works, drag the anchors around to change the curve. */
public class testsdfasdf extends Application {
public static void main(String[] args) throws Exception { launch(args); }
@Override public void start(Stage primaryStage) throws Exception {
QuadCurve curve = createStartingCurve();
final BorderPane root = new BorderPane();
Scene scene = new Scene(root, 1000, 1000);
final Anchor control2 = new Anchor(Color.GOLDENROD, curve.controlXProperty(), curve.controlYProperty());
root.getChildren().add(curve);
root.getChildren().add(control2);
primaryStage.setTitle("Quadcurve Manipulation");
primaryStage.setScene(scene);
primaryStage.show();
}
private QuadCurve createStartingCurve() {
QuadCurve curve = new QuadCurve();
curve.setStartX(100);
curve.setStartY(100);
curve.setControlX(200);
curve.setControlY(50);
curve.setEndX(300);
curve.setEndY(100);
curve.setStroke(Color.BLACK);
curve.setStrokeWidth(10);
curve.setStrokeLineCap(StrokeLineCap.ROUND);
curve.setFill(Color.CORNSILK.deriveColor(0, 1.2, 1, 0.6));
return curve;
}
// a draggable anchor displayed around a point.
class Anchor extends Circle {
Anchor(Color color, DoubleProperty x, DoubleProperty y) {
super(x.get(), y.get(), 10);
setFill(color.deriveColor(1, 1, 1, 0.5));
y.bind(centerYProperty());
enableDrag();
changeCurve();
}
private void changeCurve() {
setOnKeyPressed((event) -> {
System.out.println(event.getCode() == KeyCode.DOWN);
if (event.getCode() == KeyCode.DOWN) {
double newY = getCenterY();
while (newY > 0 && newY < getScene().getHeight()) {
setCenterY(newY);
newY+=1;
}
}
else if (event.getCode() == KeyCode.UP) {
double newY = getCenterY();
while (newY > 0 && newY < getScene().getHeight()) {
setCenterY(newY);
newY-=1;
}
}
});
setOnKeyReleased((event) -> {
if (event.getCode() == KeyCode.DOWN) {
}
if (event.getCode() == KeyCode.UP) {
}
});
}
// make a node movable by dragging it around with the mouse.
private void enableDrag() {
setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
getScene().setCursor(Cursor.MOVE);
}
});
setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
getScene().setCursor(Cursor.HAND);
}
});
setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
double newY = mouseEvent.getY();
System.out.println(newY);
if (newY > 0 && newY < getScene().getHeight()) {
setCenterY(newY);
}
}
});
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.HAND);
}
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.DEFAULT);
}
}
});
}
}
}
コードが多すぎるかもしれません。しかし、これは実際に曲線を描き、それを enableDrag() という関数があります。
チェンジカーブ() 関数が動作していないことが問題です。
どうすればいいですか?
問題点
ノードはフォーカスを当てないとイベントを聞きません。あなたのサークルはフォーカスを受けることがないため、キーイベントに反応することがありません。
解決方法
の1つです。 簡単 の解決策は、ステージが表示された後にフォーカスを要求することです。
primaryStage.show();
control2.requestFocus();
もう一つの解決策は、シーンの
onKeyPressedProperty
をサークルの
onKeyPressedProperty
. これにより、シーン上で起きているすべてのキー押下イベントがCircleにバインドされます。
このようなことをしたくない状況もあるかもしれません。
scene.onKeyPressedProperty().bind(control2.onKeyPressedProperty());
また、あなたの
handle()
もそうです。は必要ありません。
while loop
. あなたはただ
setCenterY()
を、押されたキーに応じて、前の値より小さい/大きい値に変更します。
setOnKeyPressed((event) -> {
if (event.getCode() == KeyCode.DOWN && getCenterY() < getScene().getHeight()){
setCenterY(getCenterY() + 5);
} else if (event.getCode() == KeyCode.UP && getCenterY() > 0) {
setCenterY(getCenterY() - 5);
}
});
関連
-
[解決済み】Doubleはdereferencedできない?
-
[解決済み】スレッド「main」での例外 java.lang.StringIndexOutOfBoundsException: 文字列のインデックスが範囲外です。0 [閉店]
-
[解決済み】"|="の意味は何ですか?(パイプ等号演算子)
-
[解決済み】指定された子にはすでに親がいます。先に子の親に対してremoveView()を呼び出す必要がある(Android)
-
[解決済み】スレッド "main "での例外 java.util.NoSuchElementException
-
[解決済み】Java LinkedListでNodesを使用する
-
[解決済み】koch snowflake java recursion
-
[解決済み] "java.nio.charset.MalformedInputException" を避けるために、すべての包括的なCharset。入力の長さ= 1"?
-
[解決済み] Could not find or load main class "とはどういう意味ですか?
-
[解決済み] Eclipse/Javaのコード補完が機能しない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】javaで指定されたファイルが見つからない
-
[解決済み】不正な反射的アクセスとは?
-
[解決済み】Gradleがtools.jarを見つけ出さない
-
[解決済み] intellijが自動配線リポジトリにタイプのBeanが見つからないと不正確な発言をする件
-
[解決済み】破損したjarファイル
-
[解決済み] java.sql.SQLException を取得しました。ResultSet が終了した後の操作は許可されません。
-
[解決済み】javaで無効な文字定数
-
[解決済み】Eclipseで「パッケージエクスプローラー」ビューが見つからない
-
[解決済み] SQLエラー。0, SQLState: 08S01 通信リンクの失敗 [重複]。
-
[解決済み】 executeQuery()でデータ操作文が発行できない。)