gpt4 book ai didi

java - 在 JavaFX 中同时处理 KeyEvent 和 MouseEvent

转载 作者:行者123 更新时间:2023-11-30 06:50:46 25 4
gpt4 key购买 nike

我正在制作一个游戏,用户需要将 ImageView 拖到 GridPane 上,当他们拖动它时,我希望他们能够按一个键来旋转 ImageView。我只希望它们能够在拖动时旋转 ImageView,因此我在拖动事件开始时设置 KeyEvent 处理程序,然后将其删除。

这是设置处理程序的代码:

private void setPlacementHandlers()
{
setOnMouseMoved(event -> trackMouse(event));
setOnDragDetected(event -> pickedUp(event));
setOnDragDone(event -> placed(event));
}

这是 OnDragDetected 的代码:

private void pickedUp(MouseEvent event)
{
//Get variables from Ship
ShipPart[] parts = ship.getParts();
int shipSize = ship.getSize();

Dragboard db = this.startDragAndDrop(TransferMode.MOVE);

ship.getBoard().setDraggedPart(this);

ClipboardContent cbContent = new ClipboardContent();
cbContent.putImage(this.getImage());

db.setDragView(shipImage);

db.setDragViewOffsetX((partIndex * 50) + mouseX);
db.setDragViewOffsetY(mouseY);

db.setContent(cbContent);

setFocusTraversable(true);
requestFocus();

setOnKeyPressed(keyEvent -> rotate(keyEvent, db, cbContent));
getScene().onKeyPressedProperty().bind(this.onKeyPressedProperty());

for(int i = 0; i < shipSize; i++)
parts[i].setVisible(false);

event.consume();
}

这是我用于测试目的的 OnKeyPressed 临时版本:

private void rotate(KeyEvent keyEvent, Dragboard db, ClipboardContent cbContent)
{
System.out.println("Potato");
}

我尝试过 setFocusTraversable(true);和 requestFocus();

出于调试目的,我删除了在拖动完成后删除 KeyEvent 处理程序的代码,结果发现 KeyEvent 在 DragEvent 之后工作正常,但在 DragEvent 期间工作正常。

总而言之,问题不在于 ImageView 没有获取 KeyEvent,而似乎 KeyEvent 甚至没有由于 DragEvent 而生成。

感谢任何帮助。

更新:我还尝试将 KeyEvent 处理程序添加到另一个对象,然后将更改应用到我想要更改的对象,但是这不起作用。我还尝试了线程和任务的各种组合。

最佳答案

拖放操作是 native 系统操作。它显示的任何图形都是 native 对象,而不是 Java 应用程序的一部分,尽管系统为应用程序提供了有限的配置它的能力,Java 通过 Dragboard 等类提供了访问权限。

由于拖动的对象不是 JavaFX 节点,因此无法监听其上的(大多数)按键事件。事实上,当拖动发生时,程序中很可能没有节点具有键盘焦点。

如果拖动源和拖动目标都在同一个场景中,您可以自己模拟拖动,方法是将场景的内容放在 StackPane 中,然后在同一个 StackPane 中放置一个“拖动 Pane ”,使其处于打开状态内容顶部,带有一个剪辑,确保它不会阻止内容的键盘或鼠标事件。拖动 Pane 包含可拖动节点的副本(在您的情况下为 ImageView)和用于突出显示当前拖动下的任何节点的形状。

import java.nio.file.Paths;
import java.util.List;

import javafx.application.Application;

import javafx.beans.Observable;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.geometry.Pos;

import javafx.stage.Stage;

import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.image.ImageView;

import javafx.scene.shape.Polyline;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;

import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;

import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;

import javafx.scene.paint.Color;

public class ImageDragExample
extends Application {
private static final String DEFAULT_IMAGE =
"http://solarsystem.nasa.gov/images/galleries/618486main_earth_320.jpg";

private GridPane grid;

private ImageView preview;
private ImageView dragImage;
private Pane dragPane;
private Rectangle dragPaneClip;

private Point2D dragStart;
private Node dragTarget;
private Shape dragHighlight;

@Override
public void start(Stage stage) {
grid = new GridPane();
grid.setHgap(24);
grid.setVgap(24);
grid.setPadding(new Insets(12));
int id = 0;
for (int row = 0; row < 3; row++) {
Node p1 = createPlaceholder(String.valueOf(row * 4 + 1));
Node p2 = createPlaceholder(String.valueOf(row * 4 + 2));
Node p3 = createPlaceholder(String.valueOf(row * 4 + 3));
Node p4 = createPlaceholder(String.valueOf(row * 4 + 4));
grid.addRow(row, p1, p2, p3, p4);
}

List<String> args = getParameters().getRaw();
preview = new ImageView(args.isEmpty() ? DEFAULT_IMAGE :
Paths.get(args.get(0)).toUri().toString());

BorderPane imageArea = new BorderPane(preview);
imageArea.setPadding(new Insets(12));

Region contents = new BorderPane(new SplitPane(grid, imageArea));

dragImage = new ImageView();
dragImage.imageProperty().bind(preview.imageProperty());
dragImage.setFocusTraversable(true);
dragImage.setOpacity(0);
dragImage.setOnMousePressed(e -> startDrag(e));
dragImage.setOnMouseDragged(e -> updateDrag(e));
dragImage.setOnMouseReleased(e -> endDrag(e));
dragImage.setOnKeyPressed(e -> rotate(e));

dragPane = new AnchorPane(dragImage);
dragPaneClip = new Rectangle();
dragPane.setClip(dragPaneClip);
StackPane pane = new StackPane(contents, dragPane);

Scene scene = new Scene(pane);
stage.setScene(scene);

preview.boundsInParentProperty().addListener(this::placeDragImage);
imageArea.boundsInParentProperty().addListener(this::placeDragImage);
stage.widthProperty().addListener(this::placeDragImage);
stage.heightProperty().addListener(this::placeDragImage);
placeDragImage(null);

stage.setTitle("Image Drag Example");
stage.show();
}

private void rotate(KeyEvent e){
System.out.println(e.getCode() + " pressed");
}

private void startDrag(MouseEvent event){
dragStart = new Point2D(event.getScreenX(), event.getScreenY());
dragImage.setOpacity(0.5);
dragImage.requestFocus();
dragPane.setClip(null);
}

private void updateDrag(MouseEvent event){
double x = event.getScreenX();
double y = event.getScreenY();
double xDelta = x - dragStart.getX();
double yDelta = y - dragStart.getY();
dragImage.setTranslateX(xDelta);
dragImage.setTranslateY(yDelta);

Node newDragTarget = null;
for (Node node : grid.getChildren()) {
if (node.contains(node.screenToLocal(x, y))) {
newDragTarget = node;
break;
}
}

removeDragHighlight();
dragTarget = newDragTarget;
addDragHighlight(dragTarget);
}

private void endDrag(MouseEvent event){
if (dragTarget != null) {
removeDragHighlight();
System.out.println("Dropped on " + dragTarget.getId());
}

dragImage.setOpacity(0);
dragImage.setTranslateX(0);
dragImage.setTranslateY(0);
dragPane.setClip(dragPaneClip);
dragStart = null;
dragTarget = null;
}

private void placeDragImage(Observable o) {
if (preview.getScene() != null && dragImage.getScene() != null) {
Point2D point = preview.localToScene(0, 0);
if (point != null) {
point = dragImage.getParent().sceneToLocal(point);
AnchorPane.setLeftAnchor(dragImage, point.getX());
AnchorPane.setTopAnchor(dragImage, point.getY());
dragPaneClip.setX(point.getX());
dragPaneClip.setY(point.getY());
dragPaneClip.setWidth(dragImage.getLayoutBounds().getWidth());
dragPaneClip.setHeight(dragImage.getLayoutBounds().getHeight());
}
}
}

private void addDragHighlight(Node node) {
if (node != null) {
Bounds bounds = node.getBoundsInLocal();

dragHighlight = null;
if (node instanceof Region) {
dragHighlight = ((Region) node).getShape();
}
if (dragHighlight == null) {
dragHighlight = new Rectangle(
bounds.getMinX(), bounds.getMinY(),
bounds.getWidth(), bounds.getHeight());
} else {
// Clone the node's shape by subtracting an empty shape from it.
dragHighlight = Shape.subtract(dragHighlight, new Polyline());
}
dragHighlight.setStrokeWidth(2);
dragHighlight.setStroke(Color.RED);
dragHighlight.setFill(null);

bounds = dragHighlight.getBoundsInLocal();
Point2D shapeOrigin =
node.localToScene(bounds.getMinX(), bounds.getMinY());
shapeOrigin = dragPane.sceneToLocal(shapeOrigin);

dragPane.getChildren().add(dragHighlight);
AnchorPane.setLeftAnchor(dragHighlight, shapeOrigin.getX());
AnchorPane.setTopAnchor(dragHighlight, shapeOrigin.getY());
}
}

private void removeDragHighlight() {
if (dragHighlight != null) {
dragPane.getChildren().remove(dragHighlight);
dragHighlight = null;
}
}

private Node createPlaceholder(String id) {
Label label = new Label(id);
label.setId(id);
label.setAlignment(Pos.CENTER);
label.setStyle("-fx-background-color: #c0c0ff;");
label.setPrefSize(200, 200);
return label;
}
}

关于java - 在 JavaFX 中同时处理 KeyEvent 和 MouseEvent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42832007/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com