2011-08-15 34 views
4

我真的坚持与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扩展其父组件非常困难。

我也读/写这些aricles:

,但我仍然坚持。

你们中的任何一个人对如何做到这一点有什么想法吗?

感谢

+2

+1了该图片贴到您的文章,如果你想获得答案雷尔那么你必须确定哪些区域是不可复制的,那么对我来说,您的问题是有意义的 – mKorbel

+0

也是带有固定文本的JTextArea,或者文本可以随用户输入而改变吗? – toto2

+0

不知道这对你是否有用,但也许你可以使用JSplitPane来处理必须在25%/ 75%部分中分割的行。 –

回答

1

这已经有一段时间,因为我做了很多摇摆,但有两个想法:

  1. 如果控制被切断,这听起来像是你不设置最低尺寸。

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

诀窍写一个布局管理器只是实现了几个关键功能:(a)计算X和Y坐标在那里你会放置给出的总体规模控制每一个; (b)计算所需的最小尺寸; (c)计算首选大小; (d)计算您将使用的最大尺寸。恩,可能还有一两个我忘了,但这不是什么大不了的事。当我第一次想到“编写我自己的布局管理器”时,听起来像“编写自己的数据库引擎”或“编写自己的编译器”,但它并不是真的靠近这个可怕的地方。它通常是几百行代码。

当然,如果在这里的其他人可以告诉你如何做一个你想要做的事情与罐头布局经理之一,这当然更容易。

+1

另请参阅[创建自定义布局管理器](http://download.oracle.com/javase/tutorial/uiswing/layout/custom.html)。 – trashgod

+1

@trashgod:谢谢。如果OP追求这一点,我相信他会比我的两句话更需要帮助。您可能还想看看现有布局管理器的源代码 - 这就是我如何解决问题的方法。 (如果您没有Java源代码,请从Oracle下载它,这通常很有帮助。“使用源码,Duke。”) – Jay

+0

我终于编写了自己的布局管理器,它的工作原理几乎完美。我现在只有滚动问题,但我会在几分钟内为此打开一个新线程;-) 顺便说一句:你太棒了! – haferblues

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))); 
     } 
    } 
} 

通过包装主要方法为invokeLater()可以看到:

enter image description here

SwingUtilities.invokeLater(new Runnable() { 

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