2016-07-24 6 views
1

J'utilise un gestionnaire d'événements de souris sur mon application java fx solitaire. C'était la conception pour le bureau seulement. Ensuite, je découvre JavaFx Port. J'ai donc essayé de tester si mon application fonctionnera sur un appareil mobile. Il se montre bien comme l'image ci-dessous.Handling d'événements dans JavaFX Port pour Android

enter image description here

Mon problème est lorsque je tente de glisser-déposer la carte. Il bloque l'application. Est-ce peut-être à cause de la gestion de mon événement?

Je l'ai essayé sur le vrai périphérique (Kindle Fire) et VM (Blue Stacks) Voici le journal des erreurs de Blue Stacks VM.

07-24 13:59:51.313 6441 6474 I System.out: don't add points, primary = -1 
07-24 13:59:51.313 6441 6474 I System.out: Top Card: 9H 
07-24 13:59:51.313 6441 6474 I System.out: Source Card: 8S 
07-24 13:59:51.313 6441 6474 I System.out: createNewCard(): Creating card... 
07-24 13:59:51.313 6441 6474 I System.out: createNewCard(): Setting card images... 
07-24 13:59:51.333 6441 6474 I System.out: createNewCard(): Setting card name... 
07-24 13:59:51.333 6441 6474 I System.out: createNewCard(): Setting card Event Filter... 
07-24 13:59:51.333 6441 6474 I System.out: createNewCard(): Setting card location.. 
07-24 13:59:51.333 6441 6474 I System.out: createNewCard(): Setting card color... 
07-24 13:59:51.333 6441 6474 I System.out: createNewCard(): Returning card... 
07-24 13:59:51.333 1881 1963 D BstCommandProcessor-Application: Application crash has been observed. 
07-24 13:59:51.333 6441 6474 I Process : Sending signal. PID: 6441 SIG: 9 
07-24 13:59:51.333 6441 6474 D AndroidRuntime: procName from cmdline: com.gluonapplication2 
07-24 13:59:51.333 6441 6474 E AndroidRuntime: in writeCrashedAppName, pkgName :com.gluonapplication2 
07-24 13:59:51.333 6441 6474 D AndroidRuntime: file written successfully with content: com.gluonapplication2 StringBuffer : ;com.gluonapplication2 
07-24 13:59:51.333 6441 6474 E AndroidRuntime: FATAL EXCEPTION: JavaFX Application Thread 
07-24 13:59:51.333 6441 6474 E AndroidRuntime: Process: com.gluonapplication2, PID: 6441 
07-24 13:59:51.333 6441 6474 E AndroidRuntime: java.lang.NoSuchMethodError: java.util.ArrayList.stream 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.gluonapplication2.views.SolitaireEvent.lambda$dragDropped$5(SolitaireEvent.java:142) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.gluonapplication2.views.SolitaireEvent.access$lambda$4(SolitaireEvent.java) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.gluonapplication2.views.SolitaireEvent$$Lambda$7.handle(Unknown Source) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at javafx.event.Event.fireEvent(Event.java:198) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at javafx.scene.Scene$DnDGesture.fireEvent(Scene.java:2937) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at javafx.scene.Scene$DnDGesture.processTargetDrop(Scene.java:3163) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at javafx.scene.Scene$DnDGesture.access$6400(Scene.java:2913) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at javafx.scene.Scene$DropTargetListener.drop(Scene.java:2877) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler.lambda$handleDragDrop$291(GlassSceneDnDEventHandler.java:95) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler.access$lambda$2(GlassSceneDnDEventHandler.java) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler$$Lambda$3.run(Unknown Source) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at java.security.AccessController.doPrivileged(AccessController.java:52) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassSceneDnDEventHandler.handleDragDrop(GlassSceneDnDEventHandler.java:92) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleDragDrop$345(GlassViewEventHandler.java:672) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassViewEventHandler.access$lambda$7(GlassViewEventHandler.java) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$10.get(Unknown Source) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:391) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleDragDrop(GlassViewEventHandler.java:671) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.View.handleDragDrop(View.java:712) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.View.notifyDragDrop(View.java:1037) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MonocleView.notifyDragDrop(MonocleView.java:163) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MouseInput.notifyMouse(MouseInput.java:248) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MouseInput.lambda$postMouseEvent$100(MouseInput.java:227) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MouseInput.access$lambda$3(MouseInput.java) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MouseInput$$Lambda$4.run(Unknown Source) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:92) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.RunnableProcessor.enterNestedEventLoop(RunnableProcessor.java:107) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MonocleApplication._enterNestedEventLoop(MonocleApplication.java:144) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MonocleApplication.enterDnDEventLoop(MonocleApplication.java:371) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.monocle.MonocleDnDClipboard.pushToSystem(MonocleDnDClipboard.java:54) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.SystemClipboard.flush(SystemClipboard.java:51) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.glass.ui.ClipboardAssistance.flush(ClipboardAssistance.java:59) 
07-24 13:59:51.333 6441 6474 E AndroidRuntime:  at com.sun.java 
07-24 13:59:51.343 1881 1963 W BstCommandProcessor-Application: in sendHttpRequest, requestType is of CRASH_APP type but one of the requiredInfo is NULL, crashedApp = [email protected] 
07-24 13:59:51.343 1881 1963 D BstCommandProcessor-Application: in sendHttpRequest, request to send to (fqdn): http://10.0.2.2:2861/AppCrashedInfo 
07-24 13:59:51.343 1881 1963 D BstCommandProcessor-Application: data: {"packageName":"com.gluonapplication2","shortPackageName":"com.gluonapplication2","versionCode":1,"versionName":"1.0"} 
07-24 13:59:51.363 1677 1924 I ActivityManager: Process com.gluonapplication2 (pid 6441) has died. 
07-24 13:59:51.363 1677 1880 I WindowState: WIN DEATH: Window{4e8b30d8 u0 com.gluonapplication2/javafxports.android.FXActivity} 
07-24 13:59:51.363 1677 1924 W ActivityManager: Force removing ActivityRecord{4eaf8ee8 u0 com.gluonapplication2/javafxports.android.FXActivity t9}: app died, no saved state 

Voici mon code SolitaireEvent.Java. J'ai commenté où la ligne 142 que le journal des erreurs indique

public class SolitaireEvent { 

    Pane tempPane; 
    double locationY; 
    EventHandler mouseDrag; 
    DataFormat cardDataFormat; 
    AlertDialog alert; 
    static ArrayList<Card> cardList; 
    ArrayList<Pane> topPanes; 

    public SolitaireEvent(Pane tempPane, double locationY, EventHandler mouseDrag, DataFormat cardDataFormat) { 
     this.tempPane = tempPane; 
     this.locationY = locationY; 
     this.mouseDrag = mouseDrag; 
     this.cardDataFormat = cardDataFormat; 
    } 

    public SolitaireEvent(ArrayList<Pane> topPanes, Pane tempPane, double locationY, EventHandler mouseDrag, DataFormat cardDataFormat) { 
     this.topPanes = topPanes; 
     this.tempPane = tempPane; 
     this.locationY = locationY; 
     this.mouseDrag = mouseDrag; 
     this.cardDataFormat = cardDataFormat; 
    } 

    public SolitaireEvent(DataFormat cardDataFormat) { 
     this.cardDataFormat = cardDataFormat; 
    } 

    public void dragDetected(Object object) { 
     final Card card = (Card) object; 

     card.setOnDragDetected((MouseEvent event) -> { 

      // drag was detected, start drag-and-drop gesture 
      System.out.println("onDragDetected"); 
      cardList = new ArrayList<>(); 

      Dragboard db = card.startDragAndDrop(TransferMode.ANY); 
      for (int i = tempPane.getChildren().indexOf(card); i < tempPane.getChildren().size(); i++) { 

       Card cardMove = (Card) tempPane.getChildren().get(i); 
       System.out.println("cardList Source Pane: " + tempPane + " Source Card: " + cardMove.getName()); 
       cardList.add(cardMove); 
      } 
      Image [] image = new Image[cardList.size()]; 


       //db.setDragView(image); 
      // put a string on dragboard 
      ClipboardContent content = new ClipboardContent(); 
      content.put(cardDataFormat, cardList); 

      db.setContent(content); 

      event.consume(); 
     }); 
    } 

    public void dragOver(Object e) { 
     //System.out.println("onDragOver"); 

     Pane targetPane = (Pane) e; 

     targetPane.setOnDragOver((DragEvent event) -> { 

      // data is dragged over the target 
      // accept it only if it is not dragged from the same node 
      // and if it has a string data 
      if (event.getGestureSource() != targetPane 
        && event.getDragboard().hasContent(cardDataFormat)) { 
       // allow for both copying and moving, whatever user chooses 
       event.acceptTransferModes(TransferMode.ANY); 

      } 
      event.consume(); 
     }); 
    } 

    public void dragEntered(Object e) { 
     Pane targetPane = (Pane) e; 
     targetPane.setOnDragEntered((DragEvent event) -> { 
      // the drag-and-drop gesture entered the target 
      System.out.println("onDragEntered"); 
      // show to the user that it is an actual gesture target 
      if (event.getGestureSource() != targetPane && event.getDragboard().hasContent(cardDataFormat)) { 
       //targetPane.setBackground(new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY))); 
      } 
      event.consume(); 
     }); 
    } 

    public void dragExited(Object e) { 
     //System.out.println("onDragExited"); 
     Pane target = (Pane) e; 

     target.setOnDragExited((DragEvent event) -> { 
      // mouse moved away, remove the graphical cues 
      // target.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY))); 
      event.consume(); 
     }); 
    } 

    public void dragDropped(Object e) { 
     Pane targetPane = (Pane) e; 

     targetPane.setOnDragDropped((DragEvent event) -> { 
      // Get the Dragboard data 
      Dragboard db = event.getDragboard(); 
      boolean success = false; 
      // if there is an image data on dragboard, read it and use it 
      if (db.hasContent(cardDataFormat)) { 
       Card targetTopCard = getTargetTopCard(targetPane); 
       ArrayList<Card> cardSourceList = (ArrayList<Card>) db.getContent(cardDataFormat); 

       if (checkCards(cardSourceList, targetPane, targetTopCard)) { 
        // Line 142 is the next line 
        cardList.stream().forEach((sourceCard) -> { 
         dragDone(sourceCard); 
        }); 

        targetTopCard = null; 
        cardList = null; 
       } 

      } 

      // transferred and used 
      event.setDropCompleted(success); 
      event.consume(); 
     }); 
    } 

    private boolean checkCards(ArrayList<Card> cardSourceList, Pane targetPane, Card targetTopCard) { 
     boolean success = false; 
     SolitaireRule solRule = new SolitaireRule(); 

     for (Card sourceCard : cardSourceList) { 
      if (!checkTopPanes(targetPane)) { 
       if (!targetPane.getChildren().isEmpty()) { 
        if (!solRule.sameColor(sourceCard.getName(), targetTopCard.getName())) { 
         if (solRule.compareRank(sourceCard.getName(), targetTopCard.getName())) { 
          locationY = getLocationY(targetPane); 
          Card card = createNewCard(sourceCard.getName()); 
          targetPane.getChildren().add(card); 
          success = true; 
         } else { 
          //alert = new AlertDialog(Alert.AlertType.WARNING, "Warning", "Same Color", "The cards are the same colors."); 
          success = false; 
          break; 
         } 
        } else { 
         //alert = new AlertDialog(Alert.AlertType.WARNING, "Warning", "Same Color", "The cards are the same colors."); 
         success = false; 
         break; 
        } 
       } else { 
        success = acceptKing(targetTopCard, sourceCard, targetPane); 
       } 
       targetTopCard = sourceCard; 
      } else { 
       success = acceptAce(targetTopCard, sourceCard, targetPane); 
       break; 
      } 
     } 
     return success; 
    } 

    private boolean checkTopPanes(Pane targetPane) { 

     boolean found = false; 

     for (Pane pane : topPanes) { 

      if (pane == targetPane) { 
       found = true; 
       System.out.println("Found Pane: " + targetPane); 
       break; 
      } 
     } 
     return found; 
    } 

    public void dragDone(Card sourceCard) { 

     System.out.println("cardList Source Pane: " + tempPane + " cardList Source Card: " + sourceCard); 
     tempPane.getChildren().remove(sourceCard); 

     if (!tempPane.getChildren().isEmpty()) { 
      // Flip the last 
      new SolitaireAnimation().flipCard(tempPane, mouseDrag); 
     } 

    } 

    private Card createNewCard(String cardName) { 
     System.out.println("createNewCard(): Creating card..."); 
     Card card = new Card(); 
     System.out.println("createNewCard(): Setting card images..."); 
     card.setImage(new Image(SolitaireEvent.class.getResourceAsStream("/" + cardName + card.IMGEXT))); 
     System.out.println("createNewCard(): Setting card name..."); 
     card.setName(cardName); 
     System.out.println("createNewCard(): Setting card Event Filter..."); 
     card.addEventFilter(MouseDragEvent.MOUSE_PRESSED, mouseDrag); 
     System.out.println("createNewCard(): Setting card location.."); 
     card.setLayoutY(locationY); 
     System.out.println("createNewCard(): Setting card color..."); 
     if (cardName.endsWith("H") || cardName.endsWith("D")) { 
      card.setIsRed(true); 
     } else if (cardName.endsWith("S") || cardName.endsWith("C")) { 
      card.setIsBlack(true); 
     } 
     System.out.println("createNewCard(): Returning card..."); 
     return card; 
    } 

    private boolean acceptKing(Card topCard, Card sourceCard, Pane targetPane) { 
     boolean success = false; 
     Card card = new Card(); 
     if (sourceCard.getName().substring(0, 1).equals("K")) { 
      System.out.println("acceptKing()[Accepted, this is a " + sourceCard.getName().substring(0, 1) + "]"); 
      card = createNewCard(sourceCard.getName()); 
      targetPane.getChildren().add(card); 
      success = true; 
     } 

     return success; 
    } 

    private boolean acceptAce(Card topCard, Card sourceCard, Pane targetPane) { 
     boolean success = false; 
     Card card = new Card(); 
     if (targetPane.getChildren().isEmpty()) { 
      System.out.println("acceptAce()[Pane is empty]"); 
      if (sourceCard.getName().substring(0, 1).equals("A")) { 
       System.out.println("acceptAce()[This is Ace]"); 
       card = createNewCard(sourceCard.getName()); 
       targetPane.getChildren().add(card); 
       success = true; 
      } 
     } else { 
      System.out.println("acceptAce()[Not Ace]"); 
      SolitaireRule solRule = new SolitaireRule(); 
      if (solRule.foundationRank(sourceCard.getName(), topCard.getName())) { 
       card = createNewCard(sourceCard.getName()); 
       targetPane.getChildren().add(card); 
       success = true; 
      } 
     } 

     return success; 
    } 

    private double getLocationY(Pane targetPane) { 

     double returnLocation = 0.0; 
     double layoutY = 0.0; 

     // Get the y location and the last card of the last index 
     if (!tempPane.getChildren().isEmpty()) { 
      for (Node children : targetPane.getChildren()) { 
       layoutY = children.getLayoutY(); 
      } 
     } 

     // Check if the target pane is empty, if true 
     // set the location of y to 0 else add 30 
     if (targetPane.getChildren().isEmpty()) { 
      returnLocation = 0; 
     } else if (targetPane == tempPane) { 
      returnLocation = layoutY; 
     } else { 
      returnLocation = layoutY + 30; 
     } 

     return returnLocation; 
    } 

    private Card getTargetTopCard(Pane targetPane) { 
     Card topCard = null; 

     // Get the y location and the last card of the last index 
     if (!tempPane.getChildren().isEmpty()) { 
      for (Node children : targetPane.getChildren()) { 
       topCard = (Card) children; 
      } 
     } 

     return topCard; 
    } 
} 
+0

Gluon Mobile ne prend pas en charge Stream API, d'où le 'NoSuchMethodError'. Supprimer l'appel à 'ArrayList.stream()' dans 'dragDropped()' et voir si cela fonctionne – jns

Répondre

2

L'erreur n'a rien à voir avec les événements.

Si vous vérifiez le code que vous avez commenté:

cardList.stream().forEach((sourceCard) -> { 
        dragDone(sourceCard); 
       }); 

contient stream, et depuis JavaFXPorts est en cours d'exécution sur Android/iOS avec Java 7 versions, les flux Java 8 ne sont pas encore pris en charge. Les expressions lambda sont supportées, cependant, grâce à la retrolambda project.

Utilisez plutôt une ancienne boucle for-imested.

Si vous avez vraiment besoin d'un support complet pour les flux, vous pouvez jeter un oeil à la streamsupportproject. Android N prend également en charge les flux et autres fonctionnalités Java 8, mais il est toujours en aperçu.

+0

Wow, vous êtes génial merci de nous aider sur ce forum. J'ai remarqué cette erreur. Mais je l'ai ignoré parce que je me concentrais plus sur le gestionnaire d'événements sur un appareil mobile. Que Dieu vous bénisse ... –

+0

Mon plaisir! Une fois que votre application fonctionne, vous pouvez jeter un oeil à ce [concours] (http://gluonhq.com/enter-gluon-app-contest/) ... –

+0

@YvesGonzaga Je voulais juste noter que si vous pensez à essayer streamsupport, vous devrez utiliser la version 1.4.2 pour le moment. Les deux versions plus récentes 1.4.3 et 1.5 ont un bug qui l'empêche de fonctionner quand JavaFXPorts est présent. Cela sera corrigé dans la version 1.5.1 –