2011-12-13 63 views
9

我使用GroupLayout来管理某些动态生成的数据输入表单中的组件。布局或多或少像这样:Swing GroupLayout:调整大小并限制组件大小

*-----------------------------------------------* 
| label A  | field A      | 
| label B  | field B      | 
| label C  | field C      | 
*-----------------------------------------------* 

我使用用于水平布局2个平行组,以及用于垂直布局的单个顺序组。大多数情况下,一切都很好。

我想将标签的最大宽度(仅为JLabel的实例)限制为父项的宽度的三分之一JFrame。如果JFrame是固定大小,这将是微不足道的,但我必须处理它被调整大小。

我从JFrame中挑选ComponentListener.componentResized()事件,但是我一旦遇到这样的事件,我有点被困在做什么。

我试过这个方法没有任何的运气:

public void componentResized(ComponentEvent e) { 
    int maxW = parentFrame.getWidth()/3; 
    for (JLabel l : labels) { 
     l.setMaximumSize(// have also tried setSize() and setPreferredSize() 
      new Dimension(
       Math.min(l.getSize().width, maxW), 
       l.getMaximumSize().height)); 
    } 
    groupLayout.invalidateLayout(getContentSpace()); 
} 

任何人都可以提出一个方法来限制将工作标签的宽度是多少?

我可能每次都可以从头重新构建布局,但我觉得应该有一个更简单的方法。

+0

永远不要setXXSize:http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi – kleopatra

+0

标签的尺寸是否大于最大标签的首选尺寸? – trashgod

+0

@trashgod不,没有。我想设置标签宽度的上限,而不是最小限制。编辑了这个问题,使其更清晰。 – vaughandroid

回答

27

在此示例中,GroupLayout可以简单地依赖于标签的首选大小,而不必诉诸于任何setXXXSize()方法。在这种方法中,

  • 标签的空间总是容纳最大的标签。
  • 可以用有用的方式调整文本字段的大小。
  • 跨平台和字体的结果是正确的。
  • “你并不需要指定大部分组件的任何东西......因为组件本身具有所需的调整行为的默认。” - How to Use GroupLayout: Component Size and Resizability

采用GroupLayout.Alignment.TRAILING右对齐的标签是个人首选项,我添加了第二个面板来显示它如何嵌套在另一个布局中。

enter image description here

import java.awt.EventQueue; 
import javax.swing.BorderFactory; 
import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.GroupLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

/** @see http://stackoverflow.com/questions/8492065 */ 
public class GroupPanel extends JPanel { 

    private JLabel label1 = new JLabel("Primary:"); 
    private JTextField field1 = new JTextField(16); 
    private JLabel label2 = new JLabel("Secondary:"); 
    private JTextField field2 = new JTextField(16); 
    private JLabel label3 = new JLabel("Tertiary:"); 
    private JTextField field3 = new JTextField(16); 

    public GroupPanel(int n) { 
     this.setBorder(BorderFactory.createTitledBorder("Panel " + n)); 
     GroupLayout layout = new GroupLayout(this);   
     this.setLayout(layout); 
     layout.setAutoCreateGaps(true); 
     layout.setAutoCreateContainerGaps(true); 
     layout.setHorizontalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) 
       .addComponent(label1) 
       .addComponent(label2) 
       .addComponent(label3)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 
       .addComponent(field1) 
       .addComponent(field2) 
       .addComponent(field3)) 
     ); 
     layout.setVerticalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label1) 
       .addComponent(field1)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label2) 
       .addComponent(field2)) 
      .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 
       .addComponent(label3) 
       .addComponent(field3)) 
     ); 
    } 

    private static void display() { 
     JFrame f = new JFrame("GroupPanel"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS)); 
     f.add(new GroupPanel(1)); 
     f.add(new GroupPanel(2)); 
     f.add(Box.createVerticalGlue()); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       display(); 
      } 
     }); 
    } 
} 
+0

这是一个非常明确的例子,所以非常感谢。您提供的代码与我自己已经实现的代码几乎完全相同,但关键点是“您不需要为大多数组件指定任何内容......因为组件本身具有默认的所需调整大小行为。 ”。我想我的标签需要是覆盖getPreferredSize()的自定义实现。 – vaughandroid

+0

优秀;另请参阅此(不太灵活)[示例](http://stackoverflow.com/a/3175280/230513)。 – trashgod

+1

另请参阅此(_more_ flexible)[示例](http://stackoverflow.com/a/14858272/230513)。 – trashgod

相关问题