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