2

カスタムを作成しようとしていますJDialog。コンポーネントを好みの高さで積み重ねたいのですが、幅はコンテナを埋める必要があります。LinearLayoutAndroid に似ています。ウィンドウのサイズが変更されたときに、コンポーネントが適切な高さを維持するようにします。

レイアウトマネージャーの使用から:

シナリオ:いくつかのコンポーネントを自然なサイズでコンパクトに並べて表示する必要があります。

JPanel を使用してコンポーネントをグループ化し、JPanel のデフォルトの FlowLayout マネージャーまたは BoxLayout マネージャーのいずれかを使用することを検討してください。これには SpringLayout も適しています。

たとえば、 a のJTextField上に aが必要JTabbedPaneです。提案されたすべてのレイアウト マネージャー FlowLayout、BoxLayout、SpringLayout を試してみましたが、JDialogウィンドウの高さが大きくなったときにコンポーネントの自然なサイズが保持されません。

私の状況で使用できる Java Swing のレイアウト マネージャーはありますか?

Swing レイアウトに関する私の問題を示す小さな例を次に示します。 ダイアログ

import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class TestDialog extends JDialog {

    public TestDialog() {
        setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
        //setLayout(new SpringLayout());

        JTextField field1 = new JTextField();
        JTextField field2 = new JTextField();
        JTextField field3 = new JTextField();
        JTextField field4 = new JTextField();

        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        
        panel1.setLayout(new BoxLayout(panel1, BoxLayout.PAGE_AXIS));
        panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
        
        panel1.add(field2);
        panel2.add(field3);
        panel2.add(field4);
        
        JTabbedPane tabs = new JTabbedPane();
        tabs.addTab("Tab 1", panel1);
        tabs.addTab("Tab 2", panel2);
        
        add(field1);
        add(tabs);
        
    //field1.setMaximumSize(field1.getPreferredSize());
    //SpringUtilities.makeCompactGrid(this.getContentPane(), 2, 1, 2, 2, 2, 2);
        
        this.pack();
        this.setVisible(true);
    }
    
    public static void main(String[] args) {
        new TestDialog();
    }
}
4

6 に答える 6

2

JTabbedPaneの上にJTextFieldが必要です。提案されたすべてのレイアウトマネージャーで試してみました

垂直BoxLayoutは正常に機能するはずです。フレームサイズを大きくしたときにコンポーネントが大きくなる場合は、以下を追加する必要があります。

textField.setMaximumSize( textField.getPreferredSize() );
tabbedPane.setMaximumSize( tabbedPane.getPreferredSize() );

さらにヘルプが必要な場合は、問題を示すSSCCEを投稿してください。

編集:

テキストフィールドの希望するサイズを指定する必要があります。これは、以下を使用して行われます。

JTextField textField = new JTextField(10);
于 2011-01-17T16:31:37.513 に答える
1

ヌル レイアウト (基本的に x/y) は、探しているものか、グループ レイアウトかもしれません。

MigLayout は、おそらくすぐに使用できる機能も備えています (ウィンドウに合わせて拡張するには、特定のディレクティブを指定する必要があります。それ以外の場合は指定しません)。

概念的には、レイアウトがコンポーネントのサイズを最終的に決定するという事実に混乱していると思うので、「自然な」サイズは少し誤解を招きます。あなたが求めているのは、コンポーネントに設定されているサイズだと思いますか? それとも、コンポーネントで setSize メソッドがまったく呼び出されていない場合のデフォルトのことですか?

いずれにせよ、Swing で良い結果を得るには、サイジングの期待値をより明確にする必要があります。

于 2011-01-17T16:18:03.297 に答える
1

私は独自のStackLayoutを実装することになりました。コードは以下のとおりです。これは、私の質問の同じアプリケーションがどのように見えるかです。LinearLayoutコンポーネントは上から下に積み重ねられ、Android の場合と同様に全幅を占めます。

StackLayout を使用したマイ ダイアログ

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;

public class StackLayout implements LayoutManager {

    @Override
    public void layoutContainer(Container parent) {
        Insets insets = parent.getInsets();
        int maxWidth = parent.getWidth() - (insets.left + insets.right);

        int y = insets.top;

        for(int n = 0; n < parent.getComponentCount(); n++) {
            Component c = parent.getComponent(n);
            int height = c.getPreferredSize().height;
            c.setBounds(0, y, maxWidth, height);

            y += height;
        }
    }

    @Override
    public Dimension minimumLayoutSize(Container c) {
        int sumHeight = 0;
        int maxWidth = 0;

        for(int n = 0; n < c.getComponentCount(); n++) {
            Dimension preferredSize = c.getComponent(n).getPreferredSize();
            if(n == 0) {
                maxWidth = preferredSize.width;
            } else {
                maxWidth += preferredSize.width;
            }
            sumHeight += preferredSize.height;
        }

        // add the containers insets
        Insets insets = c.getInsets();
        sumHeight += insets.top + insets.bottom;
        maxWidth += insets.left + insets.right;

        return new Dimension(maxWidth, sumHeight);
    }

    @Override
    public Dimension preferredLayoutSize(Container c) {
        return minimumLayoutSize(c);
    }

    @Override
    public void addLayoutComponent(String arg0, Component c) {}

    @Override
    public void removeLayoutComponent(Component c) {}

}
于 2011-01-18T12:28:00.320 に答える
1

コンポーネントの自然なサイズの意味がよくわかりませんでした。ただし、レイアウトマネージャーがコンポーネントのサイズを台無しにしたくない場合は、を使用するかsetMaximumSize(int width,int height)、レイアウトをnullに設定し、setBounds(int x,int y,int width,int height)メソッドを使用してコンポーネントのサイズを変更することをお勧めします。

コンポーネントのサイズが互いにどのように変化するかを調整したい場合は、GridBagLayout を見て、weightx および weighty プロパティを使用することをお勧めします。

于 2011-01-17T17:37:43.220 に答える
0

あなたが説明していることから、はるかに単純なレイアウトマネージャー - BorderLayout() - をお勧めします。コードは次のとおりです。JDialog の幅を設定するには、少なくとも 1 つの JTextField の幅を指定する必要があります。間隔が必要な場合は、EmptyBorder を使用できます。これが役に立てば幸いです - MS

import java.awt.*;

import javax.swing.*;

public class TestDialog extends JDialog {

private JTextField  field1 = new JTextField(20),
            field2 = new JTextField(),
            field3 = new JTextField(),
            field4 = new JTextField();

public TestDialog(Frame f) {
    super (f, "Test Dialog");
    Container cp = getContentPane();
    cp.setLayout (new BorderLayout());
    cp.add (northPanel(), "North");
    cp.add (tabbedPane(), "Center");
    pack();
}

private JPanel northPanel () {
    JPanel nPanel = new JPanel(new BorderLayout());
    nPanel.add (field1, "Center");
              // nPanel.setBorder (...);
    return nPanel;
}

private JTabbedPane tabbedPane () {
    JTabbedPane tp = new JTabbedPane();
    tp.add ("Tab 1", panel1());
    tp.add ("Tab 2", panel2());
    return tp;
}


private JPanel panel1 () {
    JPanel tfPanel = new JPanel(new BorderLayout());
    tfPanel.add (field2, "North");
    return tfPanel;
}


private JPanel panel2 () {
    JPanel tfPanel = new JPanel(new BorderLayout()),
           t2Panel = new JPanel(new BorderLayout());
    t2Panel.add (field3, "North");
    t2Panel.add (field4, "Center");
    tfPanel.add (t2Panel, "North");
    return tfPanel;
}

public static void main (String[] args) {
    new TestDialog (null).setVisible (true);

}}

于 2011-01-20T05:44:40.227 に答える
0

GridBagLayout塗りつぶしや重みを指定せずに使用すると、必要なものが得られるはずです。基本的に、1 列 2 行のグリッド バッグ レイアウトになります。コンポーネントを追加するときは、作成しGridBagConstraintsて x および y オプションのみを設定するだけです。他のオプションは設定しないでください。

于 2011-01-17T17:38:10.380 に答える