0
\$\begingroup\$

So I’m playing around with drag and drop with Nifty and I have the drag working. I don’t have a drop set up yet as I’m just trying to get the dragging working at the moment.

For the purposes of my game the default drag and drop behavior of moving the draggable to another spot wont work. I’m working on a tower defense kind of game and when the player goes to drag a turret from the inventory into the game, I still need a copy of it to stay in the starting point. So I am trying to use the DraggableDragStartedEvent to determine when the drag starts and make a copy of the dropable to place in the UI so the player can still add more of that turret if they want to. Or is there another way of changing the default behavior so when the player drags they see the item under the mouse/finger but still leaves a copy at the starting point so it can be repeated from the same location?

Here is what I have and it doesn’t seem to be working:

The Nifty book for 1.3.2 (I just now realize JME uses 1.4.2 so this may no longer work and the docs on the github are not as in depth as this book) says to add a methid to your screen controller with the annotation @NiftyEventSubscriber(id=“elementId”) and it must have a String for the first parameter to pass in the id and the second must have an event of the type you want to listen to and its just supposed to work. But its not. I see “bind” in the log and I see “start screen” in the log but when I drag the draggable nothing gets logged. The dragging is working so I know it should be calling this event.

controller(new ScreenController() {
    @Override
    public void bind(Nifty nifty, Screen screen) {
        System.out.println("bind");
    }

    @Override
    public void onStartScreen() {
        System.out.println("start screen");
    }

    @Override
    public void onEndScreen() {
        System.out.println("end screen");
    }

    @NiftyEventSubscriber(id="layout")
    public void onClick(String id, DraggableDragStartedEvent event) {
        System.out.println("drag started");
    }
});

And my draggable:

control(new DraggableBuilder("chest") {{
    id("layout");
    childLayoutCenter();
    width("101px");
    height("171px");
    panel(new PanelBuilder() {{
        childLayoutCenter();
        text(new TextBuilder(){{
            text("My Cool Game");
            font("Interface/Fonts/Default.fnt");
            alignCenter();
            valignCenter();
            color(Color.WHITE);
            height("5%");
            width("15%");
        }});
    }});
}});
\$\endgroup\$
  • \$\begingroup\$ I was going through the drag and drop example on Nifty github and they use control(new DroppableBuilder("chest") and @NiftyEventSubscriber(id="chest") so I also tried changing control(new DraggableBuilder("chest") to control(new DraggableBuilder("layout") and it still doesn't work. \$\endgroup\$ – Jason Crosby May 19 '18 at 13:30
  • \$\begingroup\$ I found out from a response on jmonkey forums that DraggableDragStartedEvent might be broken. So I switched to use NiftyMousePrimaryClickedEvent and I now get an exception IllegalAccessException: Class de.lessvoid.nifty.NiftyEventAnnotationProcessor$Subscriber can not access a member of class mygame.Main$1 with modifiers "public". Any ideas on why? \$\endgroup\$ – Jason Crosby May 20 '18 at 14:26
1
\$\begingroup\$

I played around with one of Niftys standard examples for Drag'n'Drop (DragDropDemoMain) and noticed that you don't get the event when the Draggable is not associated with a Droppable. If I move a Draggable to a Droppable and then start to drag it from this Droppable I'll get the DraggableDragStartedEvent as expected.

I investigated this a little further and found this code in DraggableControl:

  private void notifyObserversDragStarted() {
    if (nifty == null || droppable == null) { // <-- THIS MIGHT BE THE REASON FOR YOUR ISSUE
      return;
    }
    String id = getId();
    if (id != null) {
      nifty.publishEvent(id, new DraggableDragStartedEvent(droppable, this));
    }
  }

This confirms the behaviour. If a Draggable is not on a Droppable already and you drag it then you don't get the event. I guess this is because the parameter Droppable in the DraggableDragStartedEvent is supposed to be not null.

setDroppable() at the DraggableControl class could be used to set the Draggable from code. Since most of the drag'n'drop was contributed by someone else I'm not sure if there are other things to consider tho :)

But maybe this is pointing you into the right direction to solve it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.