【问题标题】:Javafx KeyEvent and MouseEventJavafx KeyEvent 和 MouseEvent
【发布时间】:2020-03-01 17:27:01
【问题描述】:

我正在尝试学习 javafx。我完成了大部分代码,但我在使用 start 方法时遇到了问题。

我想做的是通过点击在屏幕上添加点。如果我按下 1 或 0,未来将添加的点将变为某种不同的颜色。因此,我知道我必须使用setOnMouseClickedsetOnKeyPressed 方法,但互联网上没有太多关于它的内容。

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;


public class Spots extends Application {

    public static final int SIZE = 500;    
    public static final int SPOT_RADIUS = 20;    
    private LinkedList<Spot> spotList;    
    private Color color;

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

    public void start(Stage stage) {

        stage.setTitle("Spots");    
        dotList = new SinglyLinkedList<>();        
        Group root = new Group();
        Scene scene = new Scene(root, 500, 500, Color.BLACK);
        Spot r;

        // ...    

        stage.show(); 
    }

    private class Spot extends Circle {

        public Spot(double xPos, double yPos) {
            super(xPos, yPos, SPOT_RADIUS);
            setFill(color);
        }

        public boolean contains(double xPos, double yPos) {
            double dx = xPos - getCenterX();
            double dy = yPos - getCenterY();
            double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
            return distance <= SPOT_RADIUS;
        }        
    }
}

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    圈子不接受的原因是它没有专注。对于响应关键事件的节点,它们应该是focusTraversable。你可以这样做 在节点上调用 setFocusTraversable(true)。我编辑了你的 start() 方法,这是我最终得到的代码。

    public void start(Stage primaryStage) throws Exception {
    
        Pane pane = new Pane();
        final Scene scene = new Scene(pane, 500, 500);
        final Circle circle = new Circle(250, 250, 20);
        circle.setFill(Color.WHITE);
       circle.setStroke(Color.BLACK);
        pane.getChildren().add(circle);
         circle.setFocusTraversable(true);
        circle.setOnKeyPressed(new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent e) {
                if ((e.getCode() == KeyCode.UP) && (circle.getCenterY() >= 5)) {
                    circle.setCenterY(circle.getCenterY() - 5);
                }
    
                else if ((e.getCode() == KeyCode.DOWN && (circle.getCenterY() <= scene.getHeight() - 5))) {
                    circle.setCenterY(circle.getCenterY() + 5);
                }
                else if ((e.getCode() == KeyCode.RIGHT) && (circle.getCenterX() <= scene.getWidth() - 5)) {
                    circle.setCenterX(circle.getCenterX() + 5);
                }
                else if ((e.getCode() == KeyCode.LEFT && (circle.getCenterX() >= 5))) {
    
                    circle.setCenterX(circle.getCenterX()-5);
                }
            }
        });
    
      //creates new spots by clicking anywhere on the pane
        pane.setOnMouseClicked(new EventHandler<MouseEvent>() {  
          public void handle(MouseEvent event) {
                double newX = event.getX(); //getting the x-coordinate of the clicked area
                double newY = event.getY(); //getting the y-coordinate of the clicked area
    
                Circle newSpot = new Circle(newX, newY,20);
                newSpot.setFill(Color.WHITE);
                newSpot.setStroke(Color.BLACK);
                pane.getChildren().add(newSpot);
    
            }
        });
    
        primaryStage.setTitle("Move the circle");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    还请查看以下链接的答案:

    【讨论】:

    • 谢谢!但是,当我点击屏幕时,我怎么会出现一个新的点呢?
    • 我的根本问题是鼠标事件。
    • 非常感谢!在您的帮助下,我现在明白了。
    • 不客气。我建议你看看这个tutorial。它通过从头开始创建 JavaFX 应用程序来教你。
    • 链接!我有最后一个问题。如果我想使用组而不是窗格,我该怎么做?
    【解决方案2】:

    解决方法

    您可以监控场景中的关键类型事件,并据此切换颜色模式。您可以在场景根窗格中放置一个鼠标事件处理程序,并在用户单击窗格中的任意位置时向场景添加一个圆圈(具有适合主要颜色模式的颜色)。

    示例代码

    import javafx.application.Application;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.stage.Stage;
    
    // Java 8+ code.
    public class Spots extends Application {
    
        private static final int SIZE = 500;
        private static final int SPOT_RADIUS = 20;
    
        private Color color = Color.BLUE;
    
        public void start(Stage stage) {
            Pane root = new Pane();
    
            root.setOnMouseClicked(event ->
                    root.getChildren().add(
                            new Spot(
                                    event.getX(),
                                    event.getY(),
                                    color
                            )
                    )
            );
    
            Scene scene = new Scene(root, SIZE, SIZE, Color.BLACK);
            scene.setOnKeyTyped(event -> {
                switch (event.getCharacter()) {
                    case "0":
                        color = Color.BLUE;
                        break;
                    case "1":
                        color = Color.RED;
                        break;
                }
            });
    
            stage.setScene(scene);
            stage.show();
        }
    
        private class Spot extends Circle {
            public Spot(double xPos, double yPos, Color color) {
                super(xPos, yPos, SPOT_RADIUS);
                setFill(color);
            }
        }
    
        public static void main(String... args) {
            launch(args);
        }
    }
    

    更多信息

    【讨论】:

    • 谢谢!如果我要使用 group 而不是 Pane 我将如何做呢?我想利用我提供的 dotList。
    • 使用窗格或组与您的 dotList 无关。 Pane 和 Group 都是 Parents 并且都有孩子,因此如果您使用 Pane 或 Group,则关于孩子列表处理的实现没有什么不同。
    【解决方案3】:

    通常,您会使用setOnAction,如Oracle tutorials 所示。

    例子:

        btn.setOnAction(new EventHandler<ActionEvent>() {
    
            public void handle(ActionEvent event) {
                System.out.println("Hello World");
            }
        });
    

    如果您尝试使用的特定节点没有 clickHandler 方法,请尝试执行以下操作(例如在 Group 上):

        group.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                System.out.println("Hello!");
            }
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多