2016-12-20 24 views
0

スイングアプリケーションのコンポーネントのサイズを変更するためにsetXXXSize()メソッドを使用しないように厳重に推奨されているこのフォーラムでは、いくつかの質問をお読みください()。JScrollPaneのサイズを変更するベストプラクティス

私の問題になってきたので、JScrollPaneのサイズを変更せずに親パネルのサイズを大きくすることを避けるために、JScrollPaneのサイズを最適に調整する方法を知りたいと思います。

コードを書く前に、私は「おもちゃの例」を投稿するので、実際の状況を説明したいと思います。

私のJFrameでは、私は現在コンテンツペインにボーダーレイアウトを使用しています。 BorderLayout.CENTERにはJPanelがあり、ここでカスタムペイントを行います。 BorderLayout.EASTには、別のパネル(このパネルはBorderLayout.NORTHのeastPanelに追加される)とJTable(BorderLayout.CENTERのeastPanelに追加された)を含むJScrollPaneの中にいくつかのコンポーネントを含むJPanel(例えばeastPanel)があります。この表には多くの行があります。 eastPanelの高さをcenterPanelの高さと同じにしたいので、できるだけ多くの行を表示しようとすると、JScrollPaneのサイズを大きくする必要があります。

今のところ私はscrollPaneを含むeastPanelでsetPreferredSizeを呼び出す以外に別の解決策を見つけることができませんでしたが、私はこの種の解決策が嫌いであることを認めなければなりません。このサンプルコードで

サンプルコード

私の目的は、コードの短いサンプルを投稿することだったので、私は、eastPanelの北側にとJScrollPaneの内部でいくつかのランダムなラベルを追加しました。 しかし、状況は上記のものと非常に似ています。 私はこのコードの「ひどい」ラインを使用せずに私の問題を解決することができていなかった。

eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height)); 

私はこのような単純な状況のため、より複雑なレイアウトを避けたいです。何か不足していますか?また、私はいくつかのカスタムペインティングを行うパネルのサイズを設定するには、空の境界を許容可能な方法に設定していますか?

コード:あなたの助けを

import java.awt.*; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 
public class Test 
{ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       try {      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
        new TestFrame().setVisible(true); 
       } 
       catch(Exception exception) { 
        JOptionPane.showMessageDialog(null, "Fatal error while initialiing application", "Error", JOptionPane.ERROR_MESSAGE); 
       } 
      } 
     }); 
    } 
} 
class TestFrame extends JFrame 
{ 
    public TestFrame() { 
     super("Test"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     JPanel pane = new JPanel(new BorderLayout(20, 0)); 
     pane.setBorder(new EmptyBorder(20, 20, 20, 20)); 
     JPanel centerPanel = new JPanel(); 
     centerPanel.setBackground(Color.WHITE); 
     centerPanel.setBorder(new EmptyBorder(400, 400, 0, 0)); 
     // centerPanel.setPreferredSize(new Dimension(400, 400)); 
     JPanel eastPanel = new JPanel(new BorderLayout(0, 20)); 
     JPanel labelsContainer = new JPanel(new GridLayout(0, 1)); 
     for(int i=0;i<7;i++) labelsContainer.add(new JLabel(String.valueOf(i))); 
     eastPanel.add(labelsContainer, BorderLayout.NORTH); 
     JPanel moreLabelsContainer = new JPanel(new GridLayout(0, 1)); 
     for(int i=7;i<70;i++) moreLabelsContainer.add(new JLabel(String.valueOf(i))); 
     JScrollPane scroll = new JScrollPane(moreLabelsContainer, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     eastPanel.add(scroll, BorderLayout.CENTER); 
     eastPanel.setPreferredSize(new Dimension(eastPanel.getPreferredSize().width, centerPanel.getPreferredSize().height)); 
     pane.add(centerPanel, BorderLayout.CENTER); 
     pane.add(eastPanel, BorderLayout.EAST); 
     setContentPane(pane); 
     pack(); 
     setLocationRelativeTo(null); 
    } 
} 

ありがとう!

答えて

3

私は、パネル内の特定のコンポーネントの高さに基づいてパネルの高さを制限するレイアウトマネージャーについて認識していません。

1つの方法は、2つの子コンポーネントを含む親パネルの動作をカスタマイズすることです。このアプローチは、中心部の成分に基づいて、高さの動的な計算を可能にする

@Override 
public Dimension getPreferredSize() 
{ 
    Dimension d = super.getPreferredSize(); 

    BorderLayout layout = (BorderLayout)getLayout(); 
    Component center = layout.getLayoutComponent(BorderLayout.CENTER); 

    int centerHeight = center.getPreferreidSize().height; 

    if (d.height > centerHeight) 
     d.height = centerHeight; 

    return d; 
} 

コードのようなものであるかもしれません。

別の方法として、独自のレイアウトマネージャーを作成することができます。次に、このタイプのロジックをレイアウトマネージャから制御できます。

また、この空の枠線は、カスタム塗装を行うパネルのサイズを設定するのに適した方法ですか?

適切な寸法を返すようにgetPreferredSize()を上書きします。

EmptyBorderを使用すると、真のボーダーをパネルに追加することができなくなるので、私はそれをお勧めしません。

+0

あなたの答えをありがとう。いくつかの投稿を読んで私は誤って、setPreferredSizeが "悪"とみなされた場合、getPreferredSizeメソッドをオーバーライドするほうがはるかに優れているとは思わなかった。私はあなたのようなエキスパートのユーザーからこのヒントを受け取ってうれしく思います!ありがとう、私の悪い英語のために申し訳ありません:D – Ansharja

関連する問題