Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaFX中同时处理KeyEvent和MouseeEvent_Java_Javafx_Event Handling - Fatal编程技术网

在JavaFX中同时处理KeyEvent和MouseeEvent

在JavaFX中同时处理KeyEvent和MouseeEvent,java,javafx,event-handling,Java,Javafx,Event Handling,我正在制作一个游戏,用户需要将ImageView拖到网格窗格上,当他们拖动它时,我希望他们能够按键旋转ImageView。我只希望他们能够在拖动ImageView时旋转它,因此我在拖动事件开始时设置KeyEvent处理程序,然后将其删除 以下是设置处理程序的代码: private void setPlacementHandlers() { setOnMouseMoved(event -> trackMouse(event)); setOnDragDetected(event

我正在制作一个游戏,用户需要将ImageView拖到网格窗格上,当他们拖动它时,我希望他们能够按键旋转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();
}
我试过setFocusTraversable(真);和请求焦点()

出于调试的目的,我删除了在拖动完成后删除KeyEvent处理程序的代码,结果表明,KeyEvent在DrageEvent之后可以正常工作,但在拖动过程中不能正常工作

总之,问题似乎不是ImageView没有获得KeyEvent,而是几乎似乎由于DrageEvent而没有生成KeyEvent

感谢您的帮助


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

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

由于拖动的对象不是JavaFX节点,因此无法侦听(大多数)关键事件。事实上,在拖动过程中,程序中很可能没有节点具有键盘焦点

如果拖动源和拖动目标都在同一场景中,您可以自己模拟拖动,方法是将场景的内容放置在堆栈窗格中,然后将“拖动窗格”放置在同一堆栈窗格中,使其位于内容的顶部,并使用确保不会阻止内容的键盘或鼠标事件的剪辑。拖动窗格包含可拖动节点的副本(本例中为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;
    }
}
import java.nio.file.path;
导入java.util.List;
导入javafx.application.application;
导入javafx.beans.Observable;
导入javafx.geometry.Bounds;
导入javafx.geometry.Insets;
导入javafx.geometry.Point2D;
导入javafx.geometry.Pos;
导入javafx.stage.stage;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.SplitPane;
导入javafx.scene.image.ImageView;
导入javafx.scene.shape.Polyline;
导入javafx.scene.shape.Rectangle;
导入javafx.scene.shape.shape;
导入javafx.scene.layout.ancorpane;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.Region;
导入javafx.scene.layout.StackPane;
导入javafx.scene.input.KeyEvent;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.paint.Color;
公共类ImageDrageExample
扩展应用程序{
私有静态最终字符串默认\u图像=
"http://solarsystem.nasa.gov/images/galleries/618486main_earth_320.jpg";
私有网格;
私有图像视图预览;
私人影像绘图;
专用窗格拖板;
私有矩形拖拽;
私有点2D dragStart;
专用节点dragTarget;
私人形状的牵引灯;
@凌驾
公众假期开始(阶段){
grid=新的GridPane();
网格。setHgap(24);
网格设置间隙(24);
网格设置填充(新插图(12));
int id=0;
对于(int行=0;行<3;行++){
节点p1=createPlaceholder(String.valueOf(row*4+1));
节点p2=createPlaceholder(String.valueOf(row*4+2));
节点p3=创建占位符(String.valueOf(row*4+3));
节点p4=createPlaceholder(String.valueOf(row*4+4));
grid.addRow(第1行、第2行、第3行、第4行);
}
List args=getParameters().getRaw();
预览=新图像视图(args.isEmpty()?默认图像:
path.get(args.get(0)).toUri().toString();
BorderPane imageArea=新边框窗格(预览);
设置填充(新插图(12));
区域内容=新边框窗格(新拆分窗格(网格、图像区域));
dragImage=newimageview();
dragImage.imageProperty().bind(preview.imageProperty());
dragImage.setFocusTraversable(真);
dragImage.setOpacity(0);
dragImage.setOnMousePressed(e->startDrag(e));
setonmousedrag(e->updateDrag(e));
dragImage.setOnMouseReleased(e->endDrag(e));
dragImage.setOnKeyPressed(e->rotate(e));
dragPane=新锚烷(dragImage);
dragPaneClip=新矩形();
dragPane.setClip(dragPaneClip);
StackPane=新的StackPane(目录,拖板);
场景=新场景(窗格);
舞台场景;
preview.boundsInParentProperty().addListener(this::placeDragImage);
imageArea.boundsInParentProperty().addListener(this::placeDragImage);
stage.widthProperty().addListener(this::placeDragImage);
stage.heightProperty().addListener(this::placeDragImage);
placeDragImage(空);
stage.setTitle(“图像拖动示例”);
stage.show();
}
私有空间旋转(关键事件e){
System.out.println(e.getCode()+“按下”);
}
私有void startDrag(MouseEvent事件){
dragStart=newpoint2D(event.getScreenX(),event.getScreenY());
不透明度(0.5);
dragImage.requestFocus();
dragPane.setClip(空);
}
私有void updateDrag(MouseEvent事件){
double x=event.getScreenX();
double y=event.getScreenY();
double-xDelta=x-dragStart.getX();
double yDelta=y-dragStart.g
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;
    }
}