2011-12-13 15 views
9

私はGroupLayoutを使用して、動的に生成されたデータ入力フォームのコンポーネントを管理しています。レイアウトは多かれ少なかれそうです:Swing GroupLayout:コンポーネントサイズのサイズ変更と制限

私は水平レイアウトに2つの並列グループを使い、垂直レイアウトには1つの連続グループを使用しています。ほとんどの場合、すべてがうまくいきます。

ラベルの幅の最大値(JLabelのインスタンスのみ)を親の幅の1/3に制限したいJFrameJFrameが固定サイズの場合、これは簡単なことですが、サイズを変更する必要があります。

私は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の使用は個人的です他のレイアウトでどのようにネストされているかを示す2番目のパネルを追加しました。

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)[example](http://stackoverflow.com/a/14858272/230513)。 – trashgod

関連する問題