XY Layout JAVA - PullRequest
       41

XY Layout JAVA

2 голосов
/ 06 февраля 2009

есть ли какой-нибудь XY-Layout для Java?

Таким образом, я могу установить кнопку на X и Y, и она должна быть такой большой и т.д. :)

Они текут каждый раз, и растягиваются. И чтобы сделать их маленькими, нужно поместить панель в панель в панель в панели ^^,

Ответы [ 4 ]

6 голосов
/ 06 февраля 2009

При установке макета контейнера на ноль (без LayoutManager) вы можете установить границы компонента индивидуально с помощью component.setBounds (x, y, w, h).

Фиксированные макеты в 99% всех случаев плохой дизайн пользовательского интерфейса (если ваши метки, например, не получают желаемого размера, вы сталкиваетесь с проблемами мэра, когда ваше приложение поддерживает несколько языков), поэтому я советую вам написать специальный менеджер макета для ваших конкретных потребностей .

Написание вашего собственного менеджера компоновки довольно просто, все, что вам нужно сделать, это уметь вычислить предпочтительный размер для контейнера с заданными компонентами и вашим макетом, и сделать макет, установив (вычисленные) границы вашего компоненты. Я избавился от GridBagLayout и давно начал кодировать свои собственные макеты, и макет никогда не был таким простым.

Вот пример пользовательского макета, который размещает пары компонентов ключа и значения:

public class KeyValueLayout implements LayoutManager {

    public static enum KeyAlignment {
        LEFT, RIGHT;
    }

    private KeyAlignment keyAlignment = KeyAlignment.LEFT;

    private int hgap;

    private int vgap;

    public KeyValueLayout () {
        this(KeyAlignment.LEFT);
    }

    public KeyValueLayout (KeyAlignment keyAlignment) {
        this(keyAlignment, 5, 5);
    }

    public KeyValueLayout (int hgap, int vgap) {
        this(KeyAlignment.LEFT, hgap, vgap);
    }

    public KeyValueLayout (KeyAlignment keyAlignment, int hgap, int vgap) {

        this.keyAlignment = keyAlignment != null ? keyAlignment : KeyAlignment.LEFT;
        this.hgap = hgap;
        this.vgap = vgap;
    }

    public void addLayoutComponent (String name, Component comp) {
    }

    public void addLayoutComponent (Component comp, Object constraints) {
    }

    public void removeLayoutComponent (Component comp) {
    }

    public void layoutContainer (Container parent) {
        Rectangle canvas = getLayoutCanvas(parent);
        int ypos = canvas.y;
        int preferredKeyWidth = getPreferredKeyWidth(parent);

        for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
            Component key = (Component) iter.next();
            Component value = iter.hasNext() ? (Component) iter.next() : null;
            int xpos = canvas.x;
            int preferredHeight = Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0);

            if (keyAlignment == KeyAlignment.LEFT)
                key.setBounds(xpos, ypos, key.getPreferredSize().width, key.getPreferredSize().height);
            else
                key.setBounds(xpos + preferredKeyWidth - key.getPreferredSize().width, ypos, key.getPreferredSize().width,
                    key.getPreferredSize().height);

            xpos += preferredKeyWidth + hgap;
            if (value != null)
                value.setBounds(xpos, ypos, canvas.x + canvas.width - xpos, preferredHeight);
            ypos += preferredHeight + vgap;
        }
    }

    public Dimension minimumLayoutSize (Container parent) {
        int preferredKeyWidth = getPreferredKeyWidth(parent);
        int minimumValueWidth = 0;
        int minimumHeight = 0;
        int lines = 0;
        for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
            lines++;
            Component key = (Component) iter.next();
            Component value = iter.hasNext() ? (Component) iter.next() : null;
            minimumHeight += Math.max(key.getPreferredSize().height, value != null ? value.getMinimumSize().height : 0);
            minimumValueWidth = Math.max(minimumValueWidth, value != null ? value.getMinimumSize().width : 0);
        }

        Insets insets = parent.getInsets();
        int minimumWidth = insets.left + preferredKeyWidth + hgap + minimumValueWidth + insets.right;
        minimumHeight += insets.top + insets.bottom;
        if (lines > 0)
            minimumHeight += (lines - 1) * vgap;

        return new Dimension(minimumWidth, minimumHeight);
    }

    public Dimension preferredLayoutSize (Container parent) {
        int preferredKeyWidth = getPreferredKeyWidth(parent);
        int preferredValueWidth = 0;
        int preferredHeight = 0;
        int lines = 0;
        for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
            lines++;
            Component key = (Component) iter.next();
            Component value = iter.hasNext() ? (Component) iter.next() : null;

            preferredHeight += Math.max(key.getPreferredSize().height, value != null ? value.getPreferredSize().height : 0);
            preferredValueWidth = Math.max(preferredValueWidth, value != null ? value.getPreferredSize().width : 0);
        }

        Insets insets = parent.getInsets();
        int preferredWidth = insets.left + preferredKeyWidth + hgap + preferredValueWidth + insets.right;
        preferredHeight += insets.top + insets.bottom;
        if (lines > 0)
            preferredHeight += (lines - 1) * vgap;

        return new Dimension(preferredWidth, preferredHeight);
    }

    public Dimension maximumLayoutSize (Container target) {
        return preferredLayoutSize(target);
    }

    private int getPreferredKeyWidth (Container parent) {
        int preferredWidth = 0;
        for (Iterator<Component> iter = new ComponentIterator(parent); iter.hasNext();) {
            Component key = (Component) iter.next();
            if (iter.hasNext())
                iter.next();

            preferredWidth = Math.max(preferredWidth, key.getPreferredSize().width);
        }

        return preferredWidth;
    }

    private Rectangle getLayoutCanvas (Container parent) {
        Insets insets = parent.getInsets();
        int x = insets.left;
        int y = insets.top;

        int width = parent.getSize().width - insets.left - insets.right;
        int height = parent.getSize().height - insets.top - insets.bottom;

        return new Rectangle(x, y, width, height);
    }

    private class ComponentIterator implements Iterator<Component> {

        private Container container;

        private int index = 0;

        public ComponentIterator (Container container) {
            this.container = container;
        }

        public boolean hasNext () {
            return index < container.getComponentCount();
        }

        public Component next () {
            return container.getComponent(index++);
        }

        public void remove () {
        }
    }
}

Просто установите макет и добавьте попеременно метки и значения компонентов. Он прост в использовании, особенно по сравнению с GridBagLayout или вложенными панелями с пользовательскими макетами.

3 голосов
/ 06 февраля 2009

Причина, по которой размеры компонентов изменяются, заключается в том, что все выглядит хорошо, независимо от размера окна, поэтому Swing препятствует прямому положению X-Y. Возможно, вы захотите взглянуть на GroupLayout http://java.sun.com/docs/books/tutorial/uiswing/layout/group.html, который предназначен для сборщиков графического интерфейса, и на упомянутой выше странице описано использование невидимых компонентов для поглощения растяжений. например: layout.setAutoCreateGaps(true);

SpringLayout также может быть полезен - см. визуальное руководство

Если вы действительно хотите X и Y, тогда установите менеджер макета на null и используйте setLocation () или setBounds (). Я ДЕЙСТВИТЕЛЬНО ДЕЙСТВИТЕЛЬНО не рекомендовал бы это, но это работает. Прочитайте этот урок

2 голосов
/ 06 февраля 2009

Если вы действительно хотите это сделать, используйте

setLayout(null);

на компоненте, в который вы помещаете вещи, затем используйте

setBounds(x, y, width, height);

для установки абсолютных координат элементов. Пример:

setLayout(null);
JButton myButton = new JButton("Do Stuff");
add(myButton);
myButton.setBounds(30, 30, 100, 30);

Тем не менее, полученный графический интерфейс будет выглядеть нестандартно, не будет изменять размер, и, если он имеет какую-либо сложность, будет трудно поддерживать.

Я знаю, что макет расстраивает, но в итоге вам будет лучше использовать комбинацию BorderLayouts и FlowLayouts или GridBagLayout - или конструктор интерфейса IDE, такой как Eclipse или Netbeans.

1 голос
/ 06 февраля 2009

Это не отвечает на ваш конкретный вопрос, но, как и согласие с другими комментариями, взгляните на MiG Layout . Как новичок в Swing, я был одинаково разочарован макетами, но это очень помогло.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...