具有可扩展单元格的动态布局

时间:2011-08-15 13:45:38

标签: java forms swing textarea

我真的陷入了我必须用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 个答案:

答案 0 :(得分:1)

自从我做了很多Swing之后已经有一段时间了,但有两点想法:

  1. 如果控件被切断,听起来好像你没有设置最小尺寸。

  2. 我不认为任何现成的布局管理器都有一个功能来保持像25/75分割那样的大小比例。但不要绝望!您可以编写自己的布局管理器。回到我做了很多Swinging时,我写了几个布局管理器。 (我会说,"对于特殊要求",但实际上它们是出于相当普遍的要求,我总是惊讶于Java并没有包含罐头布局管理器来处理这些事情。就像:你经常想要一行或一列按钮,其中所有按钮的大小相同,因此您必须找到哪个按钮具有最长的文本,然后调整所有其他按钮以匹配它。或者:设置行和列,其中每个列的大小对于该列中最宽的东西,但是一列的宽度对其他列没有影响;然后类似于行。)无论如何,你所描述的内容相当不寻常,所以你可能只想编写自己的布局管理器。

  3. 编写布局管理器的技巧只是实现一些关键功能:(a)计算X和Y坐标,在给定总体大小的情况下,您将放置每个控件; (b)计算所需的最小尺寸; (c)计算首选大小; (d)计算您将使用的最大尺寸。嗯,可能还有一两个我忘了,但这并不是什么大不了的事。当我第一次想到"写我自己的布局经理"听起来像是#34;编写自己的数据库引擎"或者"编写自己的编译器"起初,但实际上并不是那么可怕。它通常是几百行代码。

    当然,如果此处的其他人可以告诉您如何使用其中一个罐装布局经理做您想做的事情,那肯定会容易得多。

答案 1 :(得分:0)

这是我到目前为止所得到的。此示例仅使用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)));
        }
    }
}

将main方法包装到invokeLater()中可以看到:

enter image description here

SwingUtilities.invokeLater(new Runnable() {

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