如何在代号one中使用坐标布局?

How to use coordinates to layout in codename one?

因为要做桌游,想通过X轴和Y轴在屏幕上设置组件。有没有办法使用 X 和 Y 轴设置控制位置? 谢谢

是的,这是可能的,但据我所知,这不是使用代号一进行编码的标准方式。通常组件的位置由布局管理器决定:手动设置 x 和 y 位置对于过渡效果很有意义。

但是,您可以使用允许您手动选择组件的 x 和 y 位置的自定义布局。例如:

import com.codename1.io.Log;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.Layout;

/**
 * This is a special layout that keeps components in invalid positions with
 * their preferred size: that means that a revalidate() will not change the
 * position of components, that can be set using setX() and setY(); note that
 * animateLayout() and animateUnlayout() will not work as expected. Example of
 * usage: https://gist.github.com/jsfan3/4ccb8380e43db35f54bcd9960c6d8376
 *
 * 
 */
public class InvalidLayout extends Layout {

    private boolean fixedWidth = false;
    private int maxWidth = 0;
    private int maxHeight = 0;

    /**
     * The preferred size is calculated automatically, without a minimum width
     * or a minimum height
     */
    public InvalidLayout() {
    }

    /**
     * The preferred size is fixed to the given values
     *
     * @param width
     * @param height
     */
    public InvalidLayout(int width, int height) {
        this.fixedWidth = true;
        this.maxWidth = width;
        this.maxHeight = height;
    }

    @Override
    public void layoutContainer(Container parent) {
        for (Component current : parent) {
            current.setSize(current.getPreferredSize());
        }
    }

    @Override
    public Dimension getPreferredSize(Container parent) {
        if (!fixedWidth) {
            for (Component current : parent) {
                int x = current.getX() + current.getPreferredW();
                if (maxWidth < x) {
                    maxWidth = x;
                }
                int y = current.getY() + current.getPreferredH();
                if (maxHeight < y) {
                    maxHeight = y;
                }
            }
        }
        return new Dimension(maxWidth, maxHeight);
    }

}

用法示例。正如您通过尝试以下代码所看到的,星号被添加到任意 x、y 位置(在本例中是随机的),FontImage 图标从上到下沿对角线移动,并且带有 InvalidLayout 的容器的大小自动适应的位置它包含的元素:

    /**
     * This code demonstrates that InvalidLayout allows to set its Components
     * in the wanted position, that is kept after a revalidate()
     */
    public void start() {
        if (current != null) {
            current.show();
            return;
        }
        Form hi = new Form("Hi World", BoxLayout.y());
        hi.add(FlowLayout.encloseCenter(new Label("Test")));
        Container invalidCnt = new Container(new InvalidLayout());
        Label test = new Label(FontImage.createMaterial(FontImage.MATERIAL_3D_ROTATION, "Button", 5));
        invalidCnt.add(test);
        hi.add(invalidCnt);
        hi.add(FlowLayout.encloseCenter(new Label("Test")));
        test.setX(0);
        test.setY(0);
        hi.show();
        hi.revalidate();
        UITimer.timer(500, true, () -> {
            int max = 60;
            int min = 0;
            Random rand = new Random();
            Label label = new Label("*");
            invalidCnt.add(label);
            label.setX(Display.getInstance().convertToPixels(rand.nextInt((max - min) + 1) + min));
            label.setY(Display.getInstance().convertToPixels(rand.nextInt((max - min) + 1) + min));
            test.setX(test.getX() + Display.getInstance().convertToPixels(2));
            test.setY(test.getY() + Display.getInstance().convertToPixels(2));
            hi.revalidate();
        });
    }

希望对您有所帮助。然而,像本例中那样使用自定义布局是不常见的。使用代号一制作的棋盘游戏示例是:https://github.com/codenameone/codenameone-demos/blob/master/Solitaire/src/com/codename1/apps/solitaire/Solitaire.java and https://github.com/codenameone/codenameone-demos/blob/master/CN1Poker/src/com/codename1/demo/poker/Poker.java