2015-04-17 3 views
0

Я создаю клон Minesweeper для удовольствия w/javafx, и если кто-то сыграл оригинальную игру, они могут вспомнить, что, когда вы нажимаете на плитку и передвигаетесь, другие плитки ведут себя так, как будто они также нажаты ... и если вы отпустите - узел, на который на данный момент находится ваша мышь, будет нажат, даже если вы первоначально нажали на совершенно другой узел. Мне трудно воссоздать это, и мне нужна помощь.javafx - события, блокирующие другие события от обработки?

Я использую класс обработчика глобальных событий, и я не уверен, что это хорошо или очень плохо ... однако, он чувствует себя хорошо, если события для моего клона обрабатываются отдельно. Я попытался использовать методы на узле, в котором произошло событие, например startFullDrag() или startDragAndDrop(), который, как я думаю, позволит другим событиям произойти или использоваться другими узлами? Я думал, вызывая эти методы на узле возникновения события, он разрешает обработку других событий или передачу информации на конечный узел, но ничего действительно не работает. До этого подхода я старался обрабатывать события вложенным образом, каждый подход заканчивается событием перетаскивания, которое не позволяет ничего случиться.

Есть ли у кого-нибудь идеи о том, как я могу реализовать эту функцию ... Я как бы на кирпичной стене. Если я не был о чем-то прояснен, спросите, я попробую и уточню. Также очень ценятся любые критические замечания по моему коду. Я всегда стараюсь улучшаться.

My clone (so far) and all of its classes on Gist.

+0

Имея только один обработчик событий для всех узлов, это нормально. Я не понимаю, почему вы пытаетесь использовать события перетаскивания, в оригинальном тральщике нет поведения перетаскивания. Вместо того, чтобы запускать новые события на соседние узлы, постройте цикл, чтобы пересечь соседние узлы для проверки мин и номеров подсказок и сделать node.setOpened или setPressed и т. Д.Если это какая-то домашняя задача, постарайтесь сделать это сами. –

+0

У меня нет проблем с поиском минов и всего этого джаза, я говорю о небольшом нюансе в каждой игре «Сапер», в которую я играл, когда вы оставили клик и держись за плитку, а затем двигайте мышью, удерживая щелчок левой кнопкой мыши по каждому узлу, на который вы переходите, будет нажат до тех пор, пока вы не отпустите, чтобы открыть потенциальную шахту или w/e. В Java с любой кнопкой (включая ToggleButton) этого не происходит, когда вы нажимаете & удерживаете и перетаскиваете другие плитки, не нажимайте. Поэтому я пытаюсь подражать этой старой тонкой вещи из игры. Вы знаете, о чем я говорю? – jpdemko

ответ

0

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

startFullDrag() это путь:

@Override 
public void start(Stage primaryStage) 
{ 

    EventHandler<MouseEvent> dragDetectedHandler = ((MouseEvent event) -> 
    { 
     ((ToggleButton) event.getSource()).startFullDrag(); 
    }); 

    EventHandler<MouseDragEvent> dragEnteredHandler = ((MouseDragEvent event) -> 
    { 
     ((ToggleButton) event.getSource()).setSelected(true); 
    }); 

    EventHandler<MouseDragEvent> onMouseDragHandler = ((MouseDragEvent event) -> 
    { 
     ((ToggleButton) event.getSource()).fire(); 
    }); 

    EventHandler<ActionEvent> onActionHandler = ((ActionEvent event) -> 
    { 
     ToggleButton b = (ToggleButton) event.getSource(); 
     System.out.println("Action on " + b.getText()); 

     // without the following settings the button is not getting selected 
     // and focused when fire() is triggered within onMouseDragHandler. 
     b.setSelected(true); 
     b.requestFocus(); 
    }); 

    VBox vBox = new VBox(); 

    ToggleButton tb1 = new ToggleButton("A"); 
    ToggleButton tb2 = new ToggleButton("B"); 
    ToggleButton tb3 = new ToggleButton("C"); 

    ToggleGroup group = new ToggleGroup(); 
    tb1.setToggleGroup(group); 
    tb2.setToggleGroup(group); 
    tb3.setToggleGroup(group); 

    tb1.setOnAction(onActionHandler); 
    tb2.setOnAction(onActionHandler); 
    tb3.setOnAction(onActionHandler); 

    tb1.setOnDragDetected(dragDetectedHandler); 
    tb2.setOnDragDetected(dragDetectedHandler); 
    tb3.setOnDragDetected(dragDetectedHandler); 

    tb1.setOnMouseDragEntered(dragEnteredHandler); 
    tb2.setOnMouseDragEntered(dragEnteredHandler); 
    tb3.setOnMouseDragEntered(dragEnteredHandler); 

    tb1.setOnMouseDragReleased(onMouseDragHandler); 
    tb2.setOnMouseDragReleased(onMouseDragHandler); 
    tb3.setOnMouseDragReleased(onMouseDragHandler); 

    vBox.getChildren().addAll(tb1, tb2, tb3); 

    Scene scene = new Scene(vBox, 150, 150); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

EDIT: вопросы в комментарии.

Возможно ли это, только если у вас есть несколько обработчиков событий? Не смог бы я сделать это в одном обработчике событий?

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

if (event.getEventType().equals(MouseEvent.MOUSE_CLICKED)) { 
    // do on mouse click 
} else if (event.getEventType().equals(MouseDragEvent.MOUSE_DRAG_RELEASED)) { 
    // do other 
} 

Также почему это работает только с ToggleGroup?

Javadoc из ToggleGroup состояний:

Класс, который содержит ссылку на все Переключает которого выбраны переменные должны управляться таким образом, что только один Переключение в ToggleGroup могут быть выбраны в любом из время.

Без этого вам необходимо самостоятельно управлять одним выбором кнопок переключения.

+0

Возможно ли это только при наличии нескольких обработчиков событий? Не смог бы я сделать это в одном обработчике событий? Также почему это работает только с ToggleGroup? Однако огромная проблема с ToggleGroup заключается в том, что можно выбрать только одну плиту, чтобы я не мог играть в Minesweeper. – jpdemko

+0

@jpdemko обновлен. –