Динамическое расположение с расширяемыми ячейками - PullRequest
4 голосов
/ 15 августа 2011

Я действительно застрял с макетом, который я должен сделать с помощью Java Swing.

Мне нужно построить динамическую форму, перебирая вектор меток и входных компонентов.

Вот как это должно быть:

enter image description here

На этом изображении вы можете видеть, каким должен быть результат.Между зелеными линиями находится одна пара метка / входной компонент.Я также получаю ограничение, говоря мне, если я должен выложить их в один ряд 50/50 или в два ряда или в один ряд 25/75 или 75/25.Также вся форма должна быть изменяемого размера с соотношением 50/50, 25/75 и 75/25, все еще корректным.

Я попробовал GridBagLayout, который работал довольно хорошо, но, как вы можете видеть в первом ряду на рисункеЯрлык может быть очень длинным.Поэтому я использовал JTextarea, но GridBagLayout отключил его.Я также пробовал JGoodies FormLayout, но также имел проблемы с Textarea для длинных этикеток.

Соотношение 25/75 и 75/25 не так уж важно, но на самом деле это также часть того, что я должен сделать.

Я думаю, что просто создать Textarea очень сложнорасширить его родительский компонент.

Я также прочитал / написал эти статьи:

, но яЯ все еще застрял.

Кто-нибудь из вас знает, как этого добиться?

Спасибо

Ответы [ 2 ]

1 голос
/ 15 августа 2011

Прошло много времени с тех пор, как я сделал много свингов, но две мысли:

  1. Если элемент управления отключается, звучит так, будто вы не устанавливаете минимальный размер.

  2. Я не думаю, что какой-либо из готовых менеджеров компоновки имеет функцию для поддержания соотношения размеров, как ваше 25/75 разделение. Но не отчаивайтесь! Вы можете написать свой собственный менеджер макета. Когда я много занимался свингом, я написал несколько менеджеров по макету. (Я бы сказал, «для специализированных требований», но на самом деле они были для довольно общих требований, и меня всегда удивляло, что в Java не было встроенных менеджеров компоновки для обработки таких вещей. Например: вам часто нужен ряд или столбец кнопок где все кнопки имеют одинаковый размер, поэтому вы должны найти, какая кнопка имеет самый длинный текст, а затем изменить размер всех остальных, чтобы соответствовать ему, или: настроить строки и столбцы, где каждый столбец имеет размер, самый широкий в этом столбце , но ширина одного столбца не влияет на другие столбцы, а затем аналогично для строк.) В любом случае, то, что вы описываете, довольно необычно, так что вы можете просто захотеть написать свой собственный менеджер макета.

Хитрость в написании менеджера компоновки состоит в том, чтобы просто реализовать несколько ключевых функций: (a) Рассчитать координаты X и Y, где вы разместите каждый элемент управления с учетом общего размера; (б) Рассчитать минимальный требуемый размер; (c) Рассчитать предпочтительный размер; (d) Рассчитайте максимальный размер, который вы будете использовать. Хм, может быть, еще один или два, я забыл, но это не так уж важно. Когда я впервые подумал о «написании собственного менеджера компоновки», это звучало для меня как «напиши свой собственный движок базы данных» или «напиши свой собственный компилятор», но на самом деле это не так уж страшно. Обычно это несколько сотен строк кода.

Конечно, если кто-то еще здесь может сказать вам, как сделать то, что вы хотите сделать с одним из стандартных менеджеров компоновки, это, безусловно, намного проще.

0 голосов
/ 16 августа 2011

Вот что я получил до сих пор.В этом примере используется только JTextArea, но он работает и с другими компонентами (как показано на моем рисунке).Единственное, что он не может сделать в данный момент - это расположить компоненты, как показано в строке 3 на рисунке выше (один поверх другого), но это не должно быть проблемой.

Может быть, это поможет кому-тоузнайте, как написать собственный менеджер компоновки.

import java.awt.*;
import javax.swing.*;

public class SwingApp extends JFrame {

    private static final long serialVersionUID = 1L;

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                final SwingApp app = new SwingApp();
            }
        });
    }

    private SwingApp() {
        setTitle(":)");
        setSize(800, 450);
        setResizable(true);
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        /*JTextArea textArea = new JTextArea("111111alks jdfksajfjsaölk jfölksajfölkjsa 
        lkfj salkjflkdsjf ölsajfölksaj fölkjs flkjdsa flkjsaölkfjsölk");*/
        //textArea.setLineWrap(true);
        //this.getContentPane().add(textArea);
        this.getContentPane().setLayout(new MyListLayoutManager());
        add(20, "left ajdskfj lksajdf dsafj lkdsjflksjalkfjsalk jlksjaf salkjfjdsflkjdslkfjlks "
                + "flk salkfjdslkfjlkds flkjds lkfjdslkfjlkds flkjds fljlfd left", "right dksjf "
                + "asjfjsa jfsjföldsajföljsa ölkfjdsaölk jf0932875 0983 09584093859438 095843 "
                + "5lkjf lksa jf lkdsajf 923879 825094lkjtwj lkdsf27509425 right");
        add(50, "left ajdskfj lksajdf dsafj lkdsjflksjalkfjsalk jlksjaf salkjfjdsflkjdslkfjlks "
                + "flk salkfjdslkfjlkds flkjds lkfjdslkfjlkds flkjds fljlfd left", "right dksjf "
                + "asjfjsa jfsjföldsajföljsa ölkfjdsaölk jf0932875 0983 09584093859438 095843 "
                + "5lkjf lksa jf lkdsajf 923879 825094lkjtwj lkdsf27509425 right");
        add(70, "left ajdskfj lksajdf dsafj lkdsjflksjalkfjsalk jlksjaf salkjfjdsflkjdslkfjlks "
                + "flk salkfjdslkfjlkds flkjds lkfjdslkfjlkds flkjds fljlfd left", "right dksjf "
                + "asjfjsa jfsjföldsajföljsa ölkfjdsaölk jf0932875 0983 09584093859438 095843 "
                + "5lkjf lksa jf lkdsajf 923879 825094lkjtwj lkdsf27509425 right");
        add(70, "left ajdskfj lksajdf dsafj lkdsjflksjalkfjsalk jlksjaf salkjfjdsflkjdslkfjlks "
                + "flk salkfjdslkfjlkds flkjds lkfjdslkfjlkds flkjds fljlfd left", "right dksjf "
                + "asjfjsa jfsjföldsajföljsa ölkfjdsaölk jf0932875 0983 09584093859438 095843 "
                + "5lkjf lksa jf lkdsajf 923879 825094lkjtwj lkdsf27509425 right");
        add(70, "left ajdskfj lksajdf dsafj lkdsjflksjalkfjsalk jlksjaf salkjfjdsflkjdslkfjlks "
                + "flk salkfjdslkfjlkds flkjds lkfjdslkfjlkds flkjds fljlfd left", "right dksjf "
                + "asjfjsa jfsjföldsajföljsa ölkfjdsaölk jf0932875 0983 09584093859438 095843 "
                + "5lkjf lksa jf lkdsajf 923879 825094lkjtwj lkdsf27509425 right");
    }

    private void add(final int leftPercent, final String leftText, final String rightText) {
        final JPanel panel = new JPanel(new MyRowLayoutManager(leftPercent));
        final JTextArea left = new JTextArea(leftText);
        left.setLineWrap(true);
        final JTextArea right = new JTextArea(rightText);
        right.setLineWrap(true);
        panel.add(left);
        panel.add(right);
        this.getContentPane().add(panel);
    }

    private class MyListLayoutManager implements LayoutManager {

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

        @Override
        public void removeLayoutComponent(final Component comp) {
        }

        @Override
        public Dimension preferredLayoutSize(final Container parent) {
            return new Dimension(600, 300);
        }

        @Override
        public Dimension minimumLayoutSize(final Container parent) {
            return new Dimension(0, 0);
        }

        @Override
        public void layoutContainer(final Container parent) {
            final Dimension size = parent.getSize();
            final int left = 0;
            int top = 0;
            for (int i = 0; i < parent.getComponentCount(); ++i) {
                final Component component = parent.getComponent(i);
                component.setSize(size.width, 1);
                final Dimension preferredSize = component.getPreferredSize();
                component.setBounds(left, top, preferredSize.width, preferredSize.height);
                top += preferredSize.height;
            }
        }
    }

    private class MyRowLayoutManager implements LayoutManager {

        private final int _leftPercent;

        private MyRowLayoutManager(final int leftPercent) {
            _leftPercent = leftPercent;
        }

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

        @Override
        public void removeLayoutComponent(final Component comp) {
        }

        @Override
        public Dimension preferredLayoutSize(final Container parent) {
            return new Dimension(600, 300);
        }

        @Override
        public Dimension minimumLayoutSize(final Container parent) {
            return new Dimension(0, 0);
        }

        @Override
        public void layoutContainer(final Container parent) {
            if (parent.getComponentCount() != 2) {
                throw new RuntimeException("Supports for exact 2 components");
            }
            final Dimension size = getSize();
            final int widthForLeft = size.width * _leftPercent / 100;
            final int widthForRight = size.width - widthForLeft;
            final Component left = parent.getComponent(0); //left Component
            left.setSize(widthForLeft, 1);
            final Dimension leftDimension = left.getPreferredSize();
            left.setBounds(0, 0, widthForLeft, leftDimension.height);
            final Component right = parent.getComponent(1); //right Component
            right.setSize(widthForRight, 1);
            final Dimension rightDimension = right.getPreferredSize();
            right.setBounds(widthForLeft, 0, widthForRight, rightDimension.height);
            parent.setSize(size.width, Math.max(leftDimension.height, rightDimension.height));
            parent.setPreferredSize(new Dimension(size.width, Math.max(leftDimension.height, rightDimension.height)));
        }
    }
}

, включив основной метод в invokeLater(), можно увидеть:

enter image description here

SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            final SwingApp app = new SwingApp();
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...