2

最大幅を制限したパネルを作成したいのですが、コンテナが短くなると幅が狭くなります。

使っGridBagLayoutていたのですが、サイズが短くなると挙動がおかしくなりました。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Michael Nesterenko
 *
 */
public class SSCE extends JFrame {

    /**
     * 
     */
    public SSCE() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GridBagLayout gbl = new GridBagLayout();
        gbl.columnWidths = new int[] {200, 1};
        gbl.columnWeights = new double[] {0, 1};
        gbl.rowHeights = new int[] {10};
        gbl.rowWeights = new double[] {0};
        setLayout(gbl);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JPanel sizeRestrictedPanel = new JPanel();
        sizeRestrictedPanel.setBackground(Color.BLUE);
        sizeRestrictedPanel.setMinimumSize(new Dimension(50, 50));
        sizeRestrictedPanel.setMaximumSize(new Dimension(300, 50));
        sizeRestrictedPanel.setPreferredSize(new Dimension(300, 50));
        add(sizeRestrictedPanel, gbc);

        JPanel dummy = new JPanel();
        dummy.setBackground(Color.RED);
        add(dummy, gbc);

        setPreferredSize(new Dimension(600, 200));
        pack();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new SSCE().setVisible(true);
    }

}

フレーム幅が短くなるとすぐに青いパネルのサイズが変更されますが、ウィンドウのサイズ変更でスムーズにサイズ変更したいです。

4

2 に答える 2

2

ユーザーがウィンドウの幅を縮小すると、最初は赤いパネルだけが縮小します。

質問のコード例は、実際には、コンポーネントのパッキングによって指定されたサイズを超えて拡大されたウィンドウで始まります。行を削除するsetPreferredSize(new Dimension(600, 200));と、赤いパネルが拡大されたウィンドウの代わりに、以下に示すウィンドウが表示されます。幅をこのサイズよりも小さくすると、青色のパネルが推奨サイズよりも小さくなり、「動作がおかしくなる」ことになります。これは、GridBagLayout が青色のパネルの優先サイズを優先できなくなったため、各パネルに等しいスペースを与え、最小サイズを優先しようとするためです。

ここに画像の説明を入力

GridBagLayout で setPreferredSize を使用しないことをお勧めします。 ウィンドウが引き続き有効であるために必要な最小サイズを決定し、ユーザーがこの最小値よりもサイズを縮小できないようにすることをお勧めします。一部のコンポーネントは、ユーザーがウィンドウを拡大したときに、最初に割り当てられたよりも多くのスペースを占めるべきではありません。の代わりに GridBagConstraints の weightx と weighty を使用してこれを実現でき setMaximumSizeます。

以下のコードは、2 つのパネルのサイズがスムーズに変更される様子を示しています。サイズが変更されたときに寸法を表示するテキストを追加しました。

import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.*;

/**
 * @author Michael Nesterenko, Leon LaSpina
 *
 */
public class SSCE extends JFrame {
   JLabel blueDimension, redDimension;
   JPanel sizeRestrictedPanel, dummyPanel, bottomPanel;

   public SSCE() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      JPanel testPanel = new JPanel();
      bottomPanel = new JPanel();
      setLayout(new BorderLayout());
      GridBagLayout gbl = new GridBagLayout();
      testPanel.setLayout(gbl);
      add(testPanel, BorderLayout.CENTER);
      add(bottomPanel, BorderLayout.SOUTH);
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.fill = GridBagConstraints.HORIZONTAL;
      gbc.weightx = 0.75;

      sizeRestrictedPanel = new JPanel();
      sizeRestrictedPanel.setBackground(Color.BLUE);
      sizeRestrictedPanel.setMinimumSize(new Dimension(50, 50));
      sizeRestrictedPanel.setMaximumSize(new Dimension(300, 50));
      //sizeRestrictedPanel.setPreferredSize(new Dimension(300, 50));
      testPanel.add(sizeRestrictedPanel, gbc);
      dummyPanel = new JPanel();
      dummyPanel.setBackground(Color.RED);
      dummyPanel.setMinimumSize(new Dimension(50, 50));
      //dummyPanel.setPreferredSize(new Dimension(50, 50));
      gbc.weightx = 0.25;
      testPanel.add(dummyPanel, gbc);

      setSize(new Dimension(600, 200));
      blueDimension = new JLabel("------");
      blueDimension.setForeground(Color.BLUE);
      redDimension = new JLabel("------");
      redDimension.setForeground(Color.RED);
      bottomPanel.add(blueDimension);
      bottomPanel.add(new JLabel("   "));
      bottomPanel.add(blueDimension);
      bottomPanel.add(redDimension);
      this.addComponentListener(new ComponentAdapter() {
         public void componentResized(ComponentEvent e) {
            updateDimensionText();
         }
      });
   }

   private void updateDimensionText() {
      Dimension d1 = sizeRestrictedPanel.getSize();
      String s1 = d1.width + "," + d1.height;
      Dimension d2 = dummyPanel.getSize();
      String s2 = d2.width + "," + d2.height;
      blueDimension.setText(s1);
      redDimension.setText(s2);
   }

   /**
    * @param args
    */
   public static void main(String[] args) {
      SSCE win = new SSCE();
      win.setVisible(true);
      win.updateDimensionText();
   }
}
于 2013-07-25T13:03:04.567 に答える