1

コンポーネントで setPreferredSize() を使用すると、幅と高さの両方が修正されます。したがって、固定幅のみが必要で、コンテンツをその制限された幅に収めるために必要に応じて高さを調整する場合、これは良くありません。

HTML テキストを考えてみましょう。ブラウザー ウィンドウでは、文字列が自動的に折り返され、必要な高さが適応されるため、使用可能な幅に収まります。したがって、ブラウザの幅を固定しても、テキストの高さは流動的なままです。

コンポーネントで同じことを達成できますか? 具体的には、JPanel.

setMaximumSize() が私が望むことを行うと信じていたことに注意してください-最大幅を設定し、高さを何か大きなものに設定して、指定したよりも広くなることはありませんが、成長するのに十分な高さがあるようにします。ただし、システムはその機能を完全に無視しているようです。例えば:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JViewport;

public class TMSApp
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("TestMaximumSize"); 
        Container container = frame.getContentPane(); 
        container.setBackground(Color.RED); 

        container.setLayout(new BorderLayout() ); 

        JViewport viewport = new JViewport(); 
        viewport.setBackground(Color.BLACK); 
        viewport.setPreferredSize(new Dimension(640, 480) ); 
        container.add(viewport, BorderLayout.CENTER); 

        JPanel testPanel = new JPanel(); 
        testPanel.setBackground(Color.WHITE); 
        testPanel.setMaximumSize(new Dimension(100, 9999) ); 
        //testPanel.setPreferredSize(new Dimension(100, 9999) ); 

        viewport.setView(testPanel); 

        testPanel.setLayout(new BoxLayout(testPanel, BoxLayout.Y_AXIS) ); 

        testPanel.add(new JLabel("<html>This is a very long HTML label " 
                                    + "that should adapt to the width of " 
                                    + "the parent container by wrapping text, " 
                                    + "just as it would in a web page " 
                                    + "constrained to the window width.</html>") ); 

        frame.setVisible(true); 
        frame.pack(); 

    }

}

このアプリを実行すると、「幅は 100 以内」と私が言っているにもかかわらず、testPanel はラベルを 1 行に残す必要があるだけ幅が広がります。私にとって、これは setMaximumSize() の契約を破ります。

(setPreferredSize() を使用すると、正しく制約されることに注意してください。ただし、上記のようにコンポーネントで setPreferredSize() を使用することはできません。これは、流動性を与える代わりに高さも修正するためです。そうです、setMaximumSize()最終的に高さを制限しましたが、許容範囲でした)。

幅を制御し、必要に応じて高さを調整する方法はありますか?

(記録として、JScrollPane にラップされた大きなパネルに一連のパネルを追加して、ラベルの代わりにパネルを含むリストとして機能させたいと考えています。すべてのアイテムを表示するには、大きなパネルを横にスクロールする必要があると考えています。 UIが悪いので、スクロールバーを除いたスクロールペインの実際の表示可能領域よりも幅が広くならないようにしたいので、小さなパネルの高さを調整して、コンテンツ(HTML文字列を含むJLabels)を利用可能な幅に合わせます。したがって、ユーザーは縦方向にスクロールするだけで各アイテムをすべて見ることができますが、上で示したように、ビューポートとスクロール バーを手動で使用しても同じ問題が発生します。

大きなパネルの幅だけを修正できた場合、小さな子パネルは自動的に幅によって制限されます。または、子パネルの幅のみを修正できれば、大きなパネルが必要以上に広くなることはありません。)

4

1 に答える 1

1

Swing コンポーネントがイベント ディスパッチ スレッド上にあることを確認するために、SwingUtilities への呼び出しを追加しました。

GUI が動作するようになりましたが、testPanel の高さに注意する必要があります。好みの幅または好みの高さだけを設定できれば、両方を設定する必要はありません。

これがあなたのコードの私のバージョンです。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;

public class TMSApp implements Runnable {

    @Override
    public void run() {
        JFrame frame = new JFrame("TestMaximumSize");
        Container container = frame.getContentPane();
        container.setBackground(Color.RED);
        container.setLayout(new BorderLayout());

        JPanel testPanel = new JPanel();
        testPanel.setBackground(Color.WHITE);
        testPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        testPanel.setPreferredSize(new Dimension(250, 9999));
        testPanel.setLayout(new BoxLayout(testPanel, BoxLayout.Y_AXIS));
        testPanel.add(new JLabel("<html>This is a very long HTML label "
                + "that should adapt to the width of "
                + "the parent container by wrapping text, "
                + "just as it would in a web page "
                + "constrained to the window width.</html>"));

        JScrollPane scrollPane = new JScrollPane(testPanel);
        scrollPane.setHorizontalScrollBarPolicy(
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPane.getViewport().setPreferredSize(new Dimension(250, 400));

        container.add(scrollPane, BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TMSApp());
    }

}
于 2012-12-28T16:33:26.260 に答える