1

Obligatory apologies for being new to Java etc. With that out of the way, I'm trying to develop a simple game. At the moment, all I want to do is be able to move the counter around the board, however I get error messages whenever i do this. It seems to be something to do with the onMouseClicked property of the GridPane I'm using for the game board because even if the handleMovement method is empty, I still get all of these errors whenever I click the mouse:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: argument type mismatch
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[java]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[java]  at java.lang.reflect.Method.invoke(Method.java:498)
[java]  at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
[java]  at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
[java]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[java]  at java.lang.reflect.Method.invoke(Method.java:498)
[java]  at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
[java]  at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
[java]  at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
[java]  at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
[java]  at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
[java]  at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
[java]  at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
[java]  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
[java]  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
[java]  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
[java]  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
[java]  at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
[java]  at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
[java]  at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
[java]  at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
[java]  at javafx.event.Event.fireEvent(Event.java:198)
[java]  at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3470)
[java]  at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
[java]  at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
[java]  at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
[java]  at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
[java]  at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
[java]  at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
[java]  at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
[java]  at java.security.AccessController.doPrivileged(Native Method)
[java]  at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
[java]  at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
[java]  at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
[java]  at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
[java]  at com.sun.glass.ui.View.notifyMouse(View.java:937)
[java]  at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
[java]  at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:186)
[java]  at java.lang.Thread.run(Thread.java:748)

My Controller class:

package Particle;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.shape.Circle;
import Elements.Player;
import javafx.scene.Node;

public class GameInterfaceController implements Initializable {    

//prepare new game grid
@FXML
GridPane gameBoard = new GridPane();

//prepare player marker
@FXML    
Circle playerCirc = new Circle();

/*
* Initialise controller class
* Requires to call teleport method, otherwise player will always begin at (0,0)
*/
@Override
public void initialize(URL url, ResourceBundle rb)
{
    teleport();
}    

/*
* Handles action when user clicks "Teleport" button
*/
@FXML
private void handleTeleport(ActionEvent event) throws Exception
{
    teleport();
}

@FXML
private void handleMovement(ActionEvent event) throws Exception
{
    Node source = (Node)event.getSource();
    System.out.println(source.toString());
    Integer colIndex = GridPane.getColumnIndex(source);
    Integer rowIndex = GridPane.getRowIndex(source);
    System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
}


/*
* move player marker to a random location on the board
*/
private void teleport()
{
    GridPane.setColumnIndex(playerCirc, (int)(12.0 * Math.random()));
    GridPane.setRowIndex(playerCirc, (int)(20.0 * Math.random()));
}

}

My FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.shape.Circle?>
<?import javafx.scene.shape.MeshView?>

<AnchorPane id="AnchorPane" fx:id="gameWindow" prefHeight="709.0" prefWidth="380.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Particle.GameInterfaceController">
   <children>
      <GridPane fx:id="gameBoard" gridLinesVisible="true" layoutX="14.0" layoutY="14.0" maxHeight="400.00" maxWidth="240.00" minHeight="600.0" minWidth="360.0" onMouseClicked="#handleMovement" prefHeight="400.0" prefWidth="240.0" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0">
        <columnConstraints>
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
            <ColumnConstraints hgrow="NEVER" minWidth="10.0" prefWidth="100.0" />
        </columnConstraints>
        <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="NEVER" />
        </rowConstraints>
         <children>
            <Circle fx:id="playerCirc" fill="#ff4326" radius="10.0" stroke="BLACK" strokeType="INSIDE">
               <GridPane.margin>
                  <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
               </GridPane.margin>
            </Circle>
         </children>
      </GridPane>
      <Button fx:id="teleportButton" layoutX="14.0" layoutY="625.0" mnemonicParsing="false" onAction="#handleTeleport" text="Teleport" />
      <Button fx:id="pulseButton" layoutX="90.0" layoutY="625.0" mnemonicParsing="false" onAction="#handlePulse" prefHeight="25.0" prefWidth="61.0" text="EMP" />
      <MeshView layoutX="233.0" layoutY="657.0" onMouseClicked="#handleMovement" />
   </children>
</AnchorPane>

My main class:

package Particle;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {

        //prepare game interface
        Parent root = FXMLLoader.load(getClass().getResource("GameInterface.fxml"));
        Scene gameWindow = new Scene(root);
        stage.setTitle("Particle game");        
        stage.setScene(gameWindow);

        //display game window
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

I used code from the answer to this question to try to solve it but I'm still getting these errors. I've also used a try-catch block around the code in the handleMovement method, but it doesnt catch anything which leads me to think the error is with the FXML or somewhere else? Can anyone explain why this is happening, or tell me if there's another way to listen for mouse clicks and determine where on the board the user has clicked?

vpaladino778
  • 157
  • 14
Haggishunt56
  • 39
  • 1
  • 9
  • When you say 'all I want to do is be able to move the counter around the board' what exactly do you mean. Can you be a little more specific in what you're trying to make happen in the gridpane? Are you trying to make it so a counter can be dragged around the screen? – vpaladino778 Dec 31 '19 at 15:19
  • Sure. The teleport method allows the user to move the counter to a random square on the board. I want them to be able to click on a square on the gridpane to move to that square. The first step is registering which square on the grid the user has selected. Only after I can do that will I deal with moving the counter but right now I can’t get it to even do that without encountering the above mentioned errors – Haggishunt56 Dec 31 '19 at 16:29

2 Answers2

2

I think i may have found your issue

@FXML
private void handleMovement(ActionEvent event) throws Exception
{
    Node source = (Node)event.getSource();
    System.out.println(source.toString());
    Integer colIndex = GridPane.getColumnIndex(source);
    Integer rowIndex = GridPane.getRowIndex(source);
    System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
}

I noticed that you are using handleMovement() as the value for the GridPane's onMouseClicked attribute. As seen here:

<GridPane fx:id="gameBoard" gridLinesVisible="true" layoutX="14.0" 
layoutY="14.0" maxHeight="400.00" maxWidth="240.00" minHeight="600.0" minWidth="360.0"
onMouseClicked="#handleMovement" prefHeight="400.0" prefWidth="240.0"
AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0">

I believe the issue may be that the handleMovement function needs a parameter that is of type MouseEvent instead of ActionEvent.

So your handleMovement() function should look like this now:

@FXML
private void handleMovement(MouseEvent event) throws Exception
{
    Node source = (Node)event.getSource();
    System.out.println(source.toString());
    Integer colIndex = GridPane.getColumnIndex(source);
    Integer rowIndex = GridPane.getRowIndex(source);
    System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue());
}

This would explain the java.lang.IllegalArgumentException: argument type mismatch error. JavaFX is expecting a function with a MouseEvent as the only parameter, but instead its getting a function that has an ActionEvent type.

vpaladino778
  • 157
  • 14
  • Hopefully this fixes your issue, let me know if it works! You might have to alter the `event.getSource()` call, depending if MouseEvent has different member functions or not, i'm not sure off hand. – vpaladino778 Dec 31 '19 at 18:14
  • I tried using MouseEvent earlier and got a compiler error instead. I’ll have a look at changing event.getSource() later in the week and let you know how I get on. Thanks! – Haggishunt56 Dec 31 '19 at 23:12
0

I wasn't able to get this working, so have decided to re-write the program using Swing rather than JavaFX.

Haggishunt56
  • 39
  • 1
  • 9