2015-04-18 6 views
1

Я пытаюсь изучить javafx. Я сделал большую часть кода, но у меня возникают проблемы с методом start.Javafx KeyEvent и MousEevent

Что я хотел сделать, это добавить пятна на экран, щелкнув по нему. И если я нажму 1 или 0 будущих пятен, которые будут добавлены, изменится на другой цвет. Поэтому я знаю, что я должен использовать методы setOnMouseClicked и setOnKeyPressed, но в Интернете их мало.

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; 
     }   
    } 
} 

ответ

2

причина, по которой круг не принимает, заключается в том, что он не сфокусирован. Чтобы узлы реагировали на ключевые события, они должны быть 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(); 
} 

принять Также посмотрите на ответы на следующие ссылки:

+0

Спасибо! Но как это сделать, когда я нажимаю на экран, появляется новое пятно? – Lin

+0

Моя основная проблема - событие мыши. – Lin

+0

Большое спасибо! Теперь я понимаю с вашей помощью. – Lin

0

Как правило, вы будете использовать 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!"); 
     } 
    }); 
1

Solution Approach

Вы можете следить за сценой для к набранные события и переключить режим цвета на основе этого. Вы можете поместить обработчик события мыши на свою корневую панель сцены и добавить в сцену круг (соответствующего цвета для преобладающего цветового режима), когда пользователь нажимает в любом месте панели.

Пример кода

spots

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); 
    } 
} 

Дополнительная информация

  • Для получения более подробной информации о событии обработки в JavaFX см Oracle JavaFX event tutorial.
+0

Спасибо! Если бы я использовал группу вместо панели, как мне это сделать? Я хочу воспользоваться предоставленным мною dotList. – Lin

+0

Использование панели или группы не имеет отношения к вашему dotList. Панели и Группа - [Родители] (https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Parent.html), и у обоих есть дети, поэтому реализация в отношении передачи списка дочерних элементов не отличается, если вы используете панель или группу. – jewelsea

Смежные вопросы