简体   繁体   English

如何使用对齐方式输出文本

[英]How to output text with a justify alignment

I am trying to create a component for libgdx which can output text in a manner equal to what html would do with a <p align=”justify”> ... </p> . 我正在尝试为libgdx创建一个组件,它可以以与html对<p align=”justify”> ... </p>相同的方式输出文本。

My idea was to add some custom component which can achieve this by adjusting the relative x and y coordinations of the components. 我的想法是添加一些自定义组件,可以通过调整组件的相对x和y协调来实现这一点。

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

import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup;
import com.badlogic.gdx.utils.Align;

public class Paragraph extends WidgetGroup {

    private Label space;

    public Paragraph(String text, float width, LabelStyle style) {

        super();
        setWidth(width);

        this.space = new Label(" ", style);
        this.space.pack();

        String[] words = text.split(" ");
        for (String word : words) {

            Label label = new Label(word, style);
            label.pack();

            addActor(label);
        }    
    }

    public void layout () {

        float size = 0;
        List<Actor> elements = new ArrayList<Actor>();

        float x = getX(Align.topLeft);
        float y = getY(Align.topLeft);

        for (Actor actor : this.getChildren().items) {

            if (actor != null) {
                if (elements.isEmpty()) {
                    elements.add(actor);
                    size = actor.getWidth();

                } else {

                    if (size + space.getWidth() + actor.getWidth() <= this.getWidth()) {

                        elements.add(actor);
                        size += (space.getWidth() + actor.getWidth());

                    } else {

                        float spacing = space.getWidth() + ((getWidth() - size) / elements.size());

                        Actor element = elements.get(0);
                        element.setPosition(x, y, Align.topLeft);

                        x += element.getWidth();

                        for (int i = 1; i < elements.size(); i++) {
                            element = elements.get(i);
                            element.setPosition(x + spacing, y, Align.topLeft);

                            x += (spacing + element.getWidth());
                        }

                        // new line
                        elements.clear();
                        x = getX(Align.topLeft);
                        y += (this.space.getHeight() * 1.5);

                        elements.add(actor);
                        size = actor.getWidth();
                    }
                }
            }
        }

        if (elements.isEmpty() == false) {

            float spacing = space.getWidth();

            Actor element = elements.get(0);
            element.setPosition(x, y, Align.topLeft);

            x += element.getWidth();

            for (int i = 1; i < elements.size(); i++) {
                element = elements.get(i);
                element.setPosition(x + spacing, y, Align.topLeft);

                x += (spacing + element.getWidth());
            }
        }
    }
}

My problem is that the x and y coordinate I retrieve with getX(Align.topLeft) & getY(Align.topLeft) always returns (0,0) instead of the real coordinates on the stage. 我的问题是我用getX(Align.topLeft)和getY(Align.topLeft)检索的x和y坐标总是返回(0,0)而不是舞台上的真实坐标。

Component structure looks like this: 组件结构如下所示:

Stage
+ Container
  + Table
    + ScrollPane
      + Table
        + Table
          + Paragraph
          + Paragraph
          + Paragraph
          + Paragraph
        + Image

So the end result is that all the text contained in the different paragraphs is drawn on top of each other. 因此,最终结果是不同段落中包含的所有文本都是相互叠加的。 Not on position (0,0), but on the same position inside of the surrounding table. 不在位置(0,0)上,而是在周围桌子内的相同位置。

I figured it out myself. 我自己想通了。

Seems it was a bad idea to override the layout method for that. 似乎覆盖布局方法是个坏主意。 I now call a different method from the constructor. 我现在从构造函数调用一个不同的方法。

Also I messed up with the x and y coordinates, so I had to rewrite that method. 我也搞砸了x和y坐标,所以我不得不重写那个方法。

Ps.: I adjusted the question as well, as I figured out the solution, it was not really about the x and y coodinates of the widget group. Ps。:我也调整了问题,因为我发现了解决方案,它并不是关于小组组的x和y坐标。

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

import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.WidgetGroup;
import com.badlogic.gdx.utils.Align;

public class Paragraph extends WidgetGroup {

    private static final class RowData {

        final List<Actor> elements;
        final float size;
        final boolean lastRow;

        RowData(List<Actor> elements, float size, boolean lastRow) {
            this.elements = elements;
            this.size = size;
            this.lastRow = lastRow;
        }

        static RowData createNewRow(List<Actor> elements, float size) {
            return new RowData(elements, size, false);
        }

        static RowData createLastRow(List<Actor> elements, float size) {
            return new RowData(elements, size, true);
        }
    }

    private Label space;

    public Paragraph(String text, float width, LabelStyle style) {

        super();
        setWidth(width);

        this.space = new Label(" ", style);
        this.space.pack();

        String[] words = text.split(" ");
        for (String word : words) {

            Label label = new Label(word, style);
            label.pack();

            addActor(label);
        }

        arrangeActors();
    }

    private void arrangeActors() {

        float size = 0;
        float height = space.getHeight();

        List<RowData> rows = new ArrayList<RowData>(); 
        List<Actor> elements = new ArrayList<Actor>();

        Actor[] actors = this.getChildren().begin();

        for (Actor actor : actors) {

            if (actor != null) {
                if (elements.isEmpty()) {

                    elements.add(actor);
                    size = actor.getWidth();

                } else if (size + space.getWidth() + actor.getWidth() <= this.getWidth()) {

                    elements.add(actor);
                    size += (space.getWidth() + actor.getWidth());

                } else {

                    rows.add(RowData.createNewRow(elements, size));

                    elements = new ArrayList<Actor>();
                    height += space.getHeight();

                    elements.add(actor);
                    size = actor.getWidth();
                }
            }
        }

        this.getChildren().end();

        rows.add(RowData.createLastRow(elements, size));

        height += space.getHeight();
        setHeight(height);

        float y = height;

        for (RowData data : rows) {

            float spacing = space.getWidth();
            if (data.lastRow == false) {
                spacing += ((getWidth() - data.size) / data.elements.size()); 
            }

            Actor element = data.elements.get(0);
            element.setPosition(0, y, Align.topLeft);

            float x = element.getWidth();

            for (int i = 1; i < data.elements.size(); i++) {

                element = data.elements.get(i);                
                element.setPosition(x + spacing, y, Align.topLeft);
                x += (spacing + element.getWidth());
            }

            y -= this.space.getHeight();
        }
    }

    @Override
    public float getPrefWidth () {
        return getWidth();
    }

    @Override
    public float getPrefHeight () {
        return getHeight();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM