2016-07-24 4 views
1

내 Java fx solitaire 응용 프로그램에서 마우스 이벤트 처리기를 사용하고 있습니다. 데스크톱 전용 디자인이었습니다. 그런 다음 JavaFx 포트를 찾습니다. 그래서 내 응용 프로그램이 모바일 장치에서 작동하는지 테스트하려고했습니다. 아래 그림과 같이 좋아 보인다. 내가 끌어 카드를 드롭 할 때Android 용 JavaFX 포트에서 이벤트 처리

enter image description here

내 문제입니다. 앱이 충돌합니다. 어쩌면 내 사건 처리 때문일까?

실제 장치 (Kindle Fire) 및 VM (Blue Stacks)에서 시도했습니다. 다음은 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 

다음은 내 SolitaireEvent.Java 코드입니다. 나는 오류 로그가 말하고있는 행 142를 주석 처리했다.

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은 스트림 API를 지원하지 않으므로 'NoSuchMethodError'입니다. 'dragList()'에서'ArrayList.stream()'에 대한 호출을 제거하고 작동하는지 확인하십시오. – jns

답변

2

오류는 이벤트와 아무런 관련이 없다. 코드를 선택하면

당신은 주석있다 : 그것은 stream를 포함하고 JavaFXPorts부터 자바 7 개 버전으로 안드로이드/iOS에서 실행되는

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

, 자바 8 스트림은 아직 지원되지 않습니다. 하지만 람다 표현식은 retrolambda project 덕분에 지원됩니다.

대신 중첩 된 중첩 루프를 사용하십시오.

Streams를 완전히 지원해야하는 경우 streamsupportproject을 살펴보십시오. 또한 Android N은 스트림 및 기타 Java 8 기능을 지원하지만 미리보기 상태입니다.

+0

와우 당신은이 포럼에서 우리를 도와 주셔서 대단히 감사합니다. 나는 그 오류를 알아 차렸다. 하지만 모바일 장치의 이벤트 처리기에 더 집중하고 있기 때문에 무시했습니다. 신의 축복이 있기를 ... –

+0

내 기쁨! 앱을 작동 시키면이 [컨테스트] (http://gluonhq.com/enter-gluon-app-contest/)를 볼 수 있습니다. –

+0

@YvesGonzaga streamsupport를 시도해 볼 것을 고려한다면 지금 릴리스 1.4.2를 사용해야합니다. 두 가지 최신 버전 1.4.3과 1.5에는 JavaFXPorts가있을 때 실행되지 못하게하는 버그가 있습니다. 이 문제는 릴리스 1.5.1에서 수정 될 예정입니다. –