2
votes

I need to implement a complex feature with Codename One that involves the moving of a tapped component (like a Button) on the screen: the users will have some buttons on the layered pane and they should be able to move them using the finger. Abstracting my problem to make it as more general as possible, these are the requirements:

  • there are several buttons in the layered pane;
  • each button has an initial position calculated by an algorithm that needs to know the screen size;
  • the position of each button can be inside the visible part of the screen or out of it (for example the x/y position can be negative or bigger than the screen size);
  • if the user only taps a button, its action listener should be invoked...
  • ... instead, if the user taps a button and moves the finger while continuing to press the screen, my algorithm should receive the x/y axis movement of the finger in real time and it should be able to update the position of all buttons while the finger moves.

It's not a game. Here I abstracted the problem to adapt my requirements to several situation. How can I implement these things in Codename One?

A "simple" use case, to better understand what I mean, is for example the moving of buttons disposed in a circle: in this example, the user can tap a single button or he/she can rotate all the circle of buttons moving the finger while tapping a button.

1

1 Answers

1
votes

You can use setDraggable(true) and make the drop containers into a droppable target using setDropTarget(true). Once you do that the default behavior of Container will allow you to visually rearrange/move components around between droppable Container instances. You can simply override the default drop method in Container with something smarter that implements the functionality you want:

public void drop(Component dragged, int x, int y) {
    int i = getComponentIndex(dragged);
    if(i > -1) {
        Component dest = getComponentAt(x, y);
        if(dest != dragged) {
            int destIndex = getComponentIndex(dest);
            if(destIndex > -1 && destIndex != i) {
                setComponentIndex(dragged,destIndex);
            }
        }
        animateLayout(400);
    } else {
        Container oldParent = dragged.getParent();
        if(oldParent != null) {
            oldParent.removeComponent(dragged);
        }
        Component pos = getComponentAt(x, y);
        i = getComponentIndex(pos);
        if(i > -1) {
            addComponent(i, dragged);
        } else {
            addComponent(dragged);
        }
        getComponentForm().animateHierarchy(400);
    }
}