2016-07-24 10 views
1

Ich verwende einen Maus-Event-Handler auf meiner Java-Solitaire-Anwendung. Es war Design nur für den Desktop. Dann entdecke ich JavaFx Port. Also habe ich versucht zu testen, ob meine Anwendung auf dem mobilen Gerät funktioniert. Es zeigt gut wie das Bild unten.Ereignisbehandlung in JavaFX Port für Android

enter image description here

Mein Problem ist, wenn ich versuche, um die Karte zu ziehen. Es stürzt die App ab. Liegt es vielleicht an meinem Event-Handling?

Ich probierte es auf realen Gerät (Kindle Fire) und VM (Blue Stacks) Unten ist das Fehlerprotokoll von 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 

Hier ist mein Code SolitaireEvent.Java. Ich habe kommentiert, wo die Zeile 142, die das Fehlerprotokoll sagt

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 unterstützt Stream API nicht, daher der 'NoSuchMethodError'. Entfernen Sie den Aufruf von 'ArrayList.stream()' in 'dragDropped()' und sehen Sie, ob es funktioniert – jns

Antwort

2

Der Fehler hat nichts mit Ereignissen zu tun.

Wenn Sie den Code überprüfen, haben Sie auf Kommentar:

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

es stream enthält, und da JavaFXPorts läuft auf Android/iOS mit Java 7-Versionen, Java 8 Ströme werden noch nicht unterstützt. Lambda-Ausdrücke werden jedoch dank der Retrolambda project unterstützt.

Verwenden Sie stattdessen eine alte For-Nested-Schleife.

Wenn Sie wirklich volle Unterstützung für Streams benötigen, können Sie sich die streamsupportproject ansehen. Auch Android N unterstützt Streams und andere Java 8-Funktionen, aber es ist immer noch in der Vorschau.

+0

Wow, Sie sind super danke, dass Sie uns in diesem Forum geholfen haben. Ich habe diesen Fehler bemerkt. Aber ich ignorierte es, weil ich mich mehr auf den Event-Handler auf dem mobilen Gerät konzentrierte. Möge Gott Sie segnen ... –

+0

Mein Vergnügen! Sobald Sie Ihre App arbeiten, möchten Sie vielleicht einen Blick darauf werfen [Wettbewerb] (http://gluonhq.com/enter-gluon-app-contest/) ... –

+0

@ YvesGonzaga wollte nur, dass, wenn Sie Wenn Sie versuchen, Streamsupport auszuprobieren, müssen Sie vorläufig Version 1.4.2 verwenden. Die zwei aktuelleren Versionen 1.4.3 und 1.5 haben einen Fehler, der verhindert, dass JavaFXPorts ausgeführt werden. Dies wird in Release 1.5.1 behoben –