-3

I have a vbox which contains a list of cards(Anchor panes). I am trying to make each card draggable so that I can change the order of the list whenever I want. I am using a scene builder.

However, I keep getting the following message after I drag and attempt to drop.

Java Messsge:class javafx.scene.layout.VBox cannot be cast to class javafx.scene.layout.AnchorPane(javafx.scene.layout.VBox and javafx.scene.layout.AnchorPane are in module javafx.graphics of loader 'app') 

My code:

minimal code provided only contains two cards, one of which is being used only in my code.

Edit: I no longer get the error message however, I am not getting my desired result as the cards are not changing positions

mport javafx.beans.property.ObjectProperty;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TitledPane;
import javafx.scene.image.WritableImage;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Controller
{
    @FXML public AnchorPane card1, card2;
    @FXML public AnchorPane current;
    @FXML public GridPane gridPane;
    @FXML public GridPane column1;
    @FXML public AnchorPane col1;
    @FXML public Button button1, button2;
    @FXML public Button currentButton;
    @FXML public VBox v1;
 @FXML
    public void detect() {  //detect card
            card1.setOnDragDetected((MouseEvent event) -> {  //card1 is the card
                Dragboard db = card1.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent content = new ClipboardContent();
                content.putString(card1.getId());
                WritableImage snapshot = card1.snapshot(new SnapshotParameters(), null);
                db.setDragView(snapshot);
                db.setContent(content);
                event.consume();
            });
    }

    @FXML
    public void accept() {  //add to vbox
        v1.addEventHandler(DragEvent.DRAG_OVER, (DragEvent event) -> { //v1 is the vbox
            if (event.getGestureSource() != v1
                    && event.getDragboard().hasString()) {
                event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
            }
            event.consume();
        });
    }

    @FXML
    public void drop() {
       v1.addEventHandler(DragEvent.DRAG_DROPPED, (DragEvent event) -> {
                    Dragboard db = event.getDragboard();
                    boolean success = false;
                    if (db.hasString()) {
                        VBox parent = (VBox) card1.getParent();
                        //int targetIndex = parent.getChildren().indexOf(card1);
                        List<Node> nodes = new ArrayList<Node>(parent.getChildren());
                        parent.getChildren().clear();
                        parent.getChildren().addAll(nodes);
                        success = true;
                    }
                    event.setDropCompleted(success);
                    event.consume();
                });
    }

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="772.0" prefWidth="1295.0" style="-fx-background-color: #C5F5D4;" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="KanbanBoard.Controller">
   <children>
      <AnchorPane layoutY="47.0" prefHeight="687.0" prefWidth="1295.0">
         <children>
            <AnchorPane fx:id="col1" layoutX="-1.0" prefHeight="724.0" prefWidth="216.0">
               <children>
                  <GridPane fx:id="column1" layoutX="33.0" layoutY="15.0" onMouseDragOver="#accept" prefHeight="724.0" prefWidth="209.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="7.0" AnchorPane.topAnchor="0.0">
                    <columnConstraints>
                      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    </columnConstraints>
                    <rowConstraints>
                      <RowConstraints maxHeight="353.8666748046875" minHeight="10.0" prefHeight="103.20001831054685" vgrow="SOMETIMES" />
                      <RowConstraints maxHeight="621.5999816894531" minHeight="10.0" prefHeight="621.5999816894531" vgrow="SOMETIMES" />
                    </rowConstraints>
                     <children>
                        <VBox fx:id="v1" onDragDropped="#drop" onDragOver="#accept" prefHeight="200.0" prefWidth="210.0" GridPane.rowIndex="1">
                           <children>
                              <AnchorPane fx:id="card1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onDragDetected="#detect" onMouseDragged="#handleLabel" prefHeight="125.0" prefWidth="198.0" style="-fx-background-color: #E5EAE6;">
                                 <children>
                                    <TextField layoutX="5.0" layoutY="3.0" prefHeight="26.0" prefWidth="65.0" promptText="ID" />
                                    <TextField layoutX="72.0" layoutY="3.0" prefHeight="26.0" prefWidth="124.0" promptText="Title" />
                                    <TextArea layoutX="5.0" layoutY="32.0" prefHeight="50.0" prefWidth="190.0" promptText="Description" />
                                    <TextField layoutX="5.0" layoutY="85.0" prefHeight="26.0" prefWidth="124.0" promptText="Story point" />
                                    <Button fx:id="button1" layoutX="164.0" layoutY="85.0" mnemonicParsing="false" onMouseClicked="#removeCard" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="-" />
                                    <Button layoutX="129.0" layoutY="85.0" mnemonicParsing="false" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="+" />
                                 </children>
                              </AnchorPane>
                              <AnchorPane fx:id="card2" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onDragDetected="#detect" onMouseClicked="#handleLabel" prefHeight="125.0" prefWidth="198.0" style="-fx-background-color: #E5EAE6;">
                                 <children>
                                    <TextField layoutX="5.0" layoutY="3.0" prefHeight="26.0" prefWidth="65.0" promptText="ID" />
                                    <TextField layoutX="72.0" layoutY="3.0" prefHeight="26.0" prefWidth="124.0" promptText="Title" />
                                    <TextArea layoutX="5.0" layoutY="32.0" prefHeight="50.0" prefWidth="190.0" promptText="Description" />
                                    <TextField layoutX="5.0" layoutY="85.0" prefHeight="26.0" prefWidth="124.0" promptText="Story point" />
                                    <Button fx:id="button2" layoutX="164.0" layoutY="85.0" mnemonicParsing="false" onMouseClicked="#removeCard" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="-" />
                                    <Button layoutX="129.0" layoutY="85.0" mnemonicParsing="false" prefHeight="24.0" prefWidth="31.0" style="-fx-background-color: #ECF4EE;" text="+" />
                                 </children>
                              </AnchorPane>
                           </children>
                        </VBox>
                        <Pane prefHeight="98.0" prefWidth="226.0" style="-fx-background-color: #D1D3D1;">
                           <children>
                              <Button layoutX="124.0" layoutY="64.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="26.0" text="-" />
                              <TextArea layoutY="39.0" prefHeight="50.0" prefWidth="124.0" promptText="Role" />
                              <TextField layoutX="1.0" layoutY="5.0" prefHeight="26.0" prefWidth="124.0" promptText="Name" />
                              <Button fx:id="addColumnButton" layoutX="124.0" layoutY="36.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="26.0" text="+" />
                           </children>
                        </Pane>
                     </children>
                  </GridPane>
               </children>
            </AnchorPane>
            <AnchorPane layoutX="1082.0" prefHeight="726.0" prefWidth="213.0">
               <children>
                  <Pane prefHeight="50.0" prefWidth="214.0" style="-fx-background-color: #8F9691;">
                     <children>
                        <Label layoutX="49.0" layoutY="7.0" prefHeight="36.0" prefWidth="46.0" text="Log" textAlignment="CENTER" textOverrun="WORD_ELLIPSIS">
                           <font>
                              <Font size="22.0" />
                           </font>
                        </Label>
                     </children>
                  </Pane>
                  <Pane layoutY="49.0" prefHeight="676.0" prefWidth="214.0" style="-fx-background-color: #C6C8C6;" />
               </children>
            </AnchorPane>
            <GridPane fx:id="gridPane" layoutX="228.0" onDragDropped="#drop" onDragOver="#accept" prefHeight="726.0" prefWidth="856.0">
              <columnConstraints>
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                  <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
              </columnConstraints>
              <rowConstraints>
                <RowConstraints maxHeight="627.1999938964843" minHeight="10.0" prefHeight="622.4000061035156" vgrow="SOMETIMES" />
              </rowConstraints>
            </GridPane>
         </children>
      </AnchorPane>
      <Label layoutX="381.0" layoutY="-4.0" prefHeight="50.0" prefWidth="180.0" text="Kanban Board">
         <font>
            <Font size="28.0" />
         </font>
      </Label>
   </children>
</AnchorPane>

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.*;
import javafx.stage.Stage;
import java.io.IOException;

public class Kanban extends Application {
    //private Button b;
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Parent root = null;
        try {
            root = FXMLLoader.load(getClass().getResource("Kanban.fxml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        Controller controller = new Controller();
        FXMLLoader loader = new FXMLLoader();
        loader.setController(controller);
        //Controller c = loader.getController();

        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Can someone help me out please.

  • Please add pointers to these lines causing the error. (Thank god I have CTRL + F) – FailingCoder Dec 01 '19 at 20:45
  • It doesn't say what line is causing the error, it's just when I drag the card and attempt to drop it, i get the message shown above. –  Dec 01 '19 at 20:47
  • Where are you seeing this message? Your IDE should have some place where console output is displayed, and in that output there should be a stack trace accompanying the `ClassCastException`. That stack trace will tell you what line is throwing the error—see [What is a stack trace, and how can I use it to debug my application errors?](https://stackoverflow.com/questions/3988788/). – Slaw Dec 01 '19 at 22:45
  • [mcve] please .. as has been suggested repeatedly. why don't you simply provide it? it's powerful a debugging strategy, more often than not it will help you to find the reason yourself and if not it's the only way others can see what's wrong .. – kleopatra Dec 01 '19 at 23:05
  • @kleopatra really sorry, it has been provided. –  Dec 01 '19 at 23:13
  • good direction - though far from _M_ :) Anyway, your setup looks fishy: you seem to be setting the eventhandlers twice, once from fxml, and then again in code .. do the one or other, but not both. – kleopatra Dec 02 '19 at 10:52
  • @kleopatra are you referring to my drop method? if so i have now changed it to only include one event handler, however, it doesn't seem to have changed anything. My cards are still not moving within the vbox. –  Dec 02 '19 at 11:21
  • everywhere ... the method should only have the code that _does_ something, _not adding/setting_ a handler that does. Also you need to change the signature: it needs a parameter – kleopatra Dec 02 '19 at 11:42
  • I'm sorry, I do not know where else I can put my event handlers? I am using these methods to link to my scene builder and they do seem to work as I can drag my cards around etc. Only problem is that I can't place it to a new position. And can you elaborate what you mean by signature please? –  Dec 02 '19 at 11:47
  • repeating: you _set_ the handler in fxml with f.i. `fx:id="v1" onDragDropped="#drop"` now your controller must have a method `void drop(xxEvent e) { // process e ... }` that does what you want, and NOT `void drop() { v1.setOnDragDropped(...)` .. (aside: wondering why your's doesn't blow on loading, not having a parameter?) – kleopatra Dec 02 '19 at 13:51
  • @kleopatra Regarding your aside, FXML-event-handler methods [are allowed to have zero parameters](https://openjfx.io/javadoc/13/javafx.fxml/javafx/fxml/doc-files/introduction_to_fxml.html#controller_method_event_handlers). – Slaw Dec 05 '19 at 11:27

1 Answers1

1

AnchorPane parent = (AnchorPane) card1.getParent(); (In the drop() method, at the bottom of your code)

card1.getParent() with a type of VBox cannot be cast to AnchorPane

FailingCoder
  • 757
  • 1
  • 8
  • 20
  • I'm sorry could you elaborate a little more? –  Dec 01 '19 at 20:49
  • https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html Think of it like trying to cast `java.lang.String` to `javax.swing.JFrame` – FailingCoder Dec 01 '19 at 20:52
  • A better example: `Integer` and `Byte` both extend java.lang.Number. They can be casted to each other. `String` does not. So `String s = 5` would cause an error. – FailingCoder Dec 01 '19 at 20:55
  • I'm sorry I still do not really understand what the exact issue is or how i can solve it. Should I change the vbox to something else? –  Dec 01 '19 at 20:56
  • [Casting variables in java](https://stackoverflow.com/questions/5289393/casting-variables-in-java) @rex – FailingCoder Dec 01 '19 at 21:01
  • So they are both different types, what can I change my vbox to so that it would allow my cards to be accepted? –  Dec 01 '19 at 21:03
  • Do you need to use `AnchorPane parent`? Also, you could instead do `AnchorPane parent = new AnchorPane(some_data_from_the_vbox)` – FailingCoder Dec 01 '19 at 21:05
  • I changed that to `AnchorPane parent = new AnchorPane(card1.getParent)` but that is making all my cards dissapear when I try to move a single one. –  Dec 01 '19 at 21:10
  • 2
    @rex If you're trying to remove the card from its parent, and you know its parent is a `VBox`, why not just do `VBox parent = (VBox) card1.getParent();`? Or is there more to your code that makes that solution invalid (if so, add a [mre] to your question)? – Slaw Dec 01 '19 at 22:41
  • @Slaw So I followed your suggestion and it did solve the issue of my cards being removed and I also no longer get the error message. But when I try to move the card to another position nothing happens(it does drag but doesn't move to a new position). Guess my code is just wrong. –  Dec 01 '19 at 22:50
  • We can help you fix that too. @rex (not me though, I don't code in javafx) – FailingCoder Dec 02 '19 at 01:49