2

私は非常に単純な UI を実装しようとしていますSpringLayout(ネット上で見つけたほとんどのチュートリアル ライターとは対照的に、他のレイアウト マネージャーと比較してコーディング インターフェイスが非常に好きであり、その使用方法を学びたいため) . UI は基本的に次のようになります。

UI テンプレート

これで問題ありません。ウィンドウのサイズを大きくすると、UI のサイズが思いどおりに変更されます (ウェルカム テキストを中央に配置し、テキスト領域を拡大して新しい使用可能なスペースをすべて埋めます) 。ただし、特定のポイントを下回る (より具体的には、ウェルカム テキストに対してウィンドウが狭すぎる場合):

縮小時のUI

ユーザーがコンポーネントを収容するのに十分なサイズよりも小さいサイズにウィンドウを縮小しようとすると、単に停止するように、ウィンドウをそれ以上縮小できないようにしたいと思います。SpringLayoutレイアウトマネージャーを使用してこれを達成するにはどうすればよいですか?

サイズ変更イベントを処理し、最小サイズに達しているかどうかを確認し、サイズを最小サイズに設定することで、おそらくこれを実行できることを知っています。ただし、これには、a) ウィンドウの最小サイズを、レンダリング前であっても知る、または計算する方法を知る必要があります。b) UI レンダリングを正しく行うためだけに、一連のイベント処理コードを記述します。c)優れたレイアウトマネージャーが処理することを期待するコードの束 ;)

4

2 に答える 2

3

「実際の」(それ以上縮小できない)最小サイズを達成するには、いくつかの問題があります。

  • 子コンポーネントは(コンテンツに基づいて)妥当な最小サイズを返す必要がありますが、多くのコア コンポーネントはそうではありません。
  • layoutManager は、利用可能なスペースがどれほど少なくても、すべての子の複合最小値を尊重する必要があります
  • 最上位のコンテナー (ここでは JFrame) は、最小値を超えて縮小することを許可してはなりません

1つ目はJLabelに当てはまり、2つ目はSpringLayoutに当てはまります(ラベルが切り捨てられているのはそのためです)-これにより、3つ目が根本的な問題として残り、解決策は明らかではありません。実際、私はそれが可能であることさえ知りませんでした@mKorbel の例を実行する前に。関連する行は確かに

frame.setMinimumSize(someSize);

その線があると、下のフレームを縮小することはできません。なしで、そうです。その観察から始めて、いくつかの掘り下げにより、ウィンドウでのオーバーライドのドキュメントが判明しました

このウィンドウの最小サイズを定数値に設定します。[..] 現在のウィンドウのサイズが minimumSize より小さい場合、ウィンドウのサイズは最小サイズを尊重するために自動的に拡大されます。setSize または setBounds メソッドが後で幅または高さより小さい値で呼び出されると、[...] が自動的に拡大され、minimumSize 値が優先されます。ユーザーが最小サイズ値未満でウィンドウのサイズを変更しようとすると、サイズ変更操作が制限される場合があります。この動作はプラットフォームに依存します。

コードを見ると、最小サイズに関連する2つの詳細があります(実装、それらに依存しないでください:-)

 Dimension minSize;
 boolean minSizeSet;

アクセスするパブリックAPI

 public Dimension getMinimumSize()
 public boolean isMininumSizeSet()

最初のかなり古い (jdk1.1)、後者はかなり新しい (jdk1.5) - 最初は後者に依存することはできませんが、内部的に null の minSize をチェックする必要があることを意味します。Window でオーバーライドされたサイジング メソッド (手動で設定された minSize を尊重するために最善を尽くすことが保証されている) は最新 (jdk6) であり、後者に依存しています言い換えれば、 isMinimumSizeSet をオーバーライドするとうまくいきます。

いくつかのコード スニペット (注意: これはテストされていないハックであり、望ましくない副作用を伴う OS 依存である可能性があります!):

    // JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("some frame title") {

        /**
         * Overridden to tricks sizing to respect the min.
         */
        @Override
        public boolean isMinimumSizeSet() {
            return true; //super.isMinimumSizeSet();
        }

        /**
         * Overridden to adjust for insets if tricksing and not using 
         * LAF decorations.
         */
        @Override
        public Dimension getMinimumSize() {
            Dimension dim = super.getMinimumSize();
            // adjust for insets if we are faking the isMinSet
            if (!super.isMinimumSizeSet() && !isDefaultLookAndFeelDecorated()) {
               Insets insets = getInsets();
               dim.width += insets.left + insets.right;
               dim.height += insets.bottom + insets.top;
            }
            return dim;
        }



    };
    // add a component which reports a content-related min
    JLabel label = new JLabel("Welcome to my application!");
    // make it a big min
    label.setFont(label.getFont().deriveFont(40f));
    frame.add(label); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
于 2012-01-05T14:28:31.480 に答える
3
  1. MinimumSizeオーバーライドできますTopLevelContainer

  2. あなたが入れJTextAreaJScrollPane

  3. 最も簡単な方法は、全体に最も洗練された(または) を実装するのではなく、GUI をパーツに分割することによって混合LayoutManagers( と呼ばれる) することです (同じまたは異なる で区切られます)。NestedLayoutJPanelsLayoutManagerLayoutManagerGridBagLayoutSpringLayoutContainer

  4. LayoutManagersかなり無視する人もいますsetXxxSize

  5. SpringLayoutJavaの私のカップではありません

import java.awt.*;
import javax.swing.*;

public class MinSizeForContainer {

    private JFrame frame = new JFrame("some frame title");

    public MinSizeForContainer() {
        JTextArea textArea = new JTextArea(15, 30);
        JScrollPane scrollPane = new JScrollPane(textArea);

        CustomJPanel fatherPanel = new CustomJPanel();
        fatherPanel.setLayout(new SpringLayout());

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(fatherPanel, BorderLayout.CENTER);
        frame.setLocation(20, 20);
        frame.setMinimumSize(fatherPanel.getMinimumSize());
        frame.pack();
        frame.setVisible(true);
    }

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

            @Override
            public void run() {
                MinSizeForContainer Mpgp = new MinSizeForContainer();
            }
        });
    }
}

class CustomJPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(400, 400);
    }
}
于 2012-01-03T22:36:41.760 に答える