2

私が作業しているUIには、ユーザーが映画を選択して再生できるパネルが表示されます。再生、一時停止などのコントロールがあります。

レイアウトは私が望むように見えます。パネルはGridBagLayoutを使用します。行2にはステータスメッセージのテキスト領域が表示され、行3にはボタンと進行状況バーのあるパネルが表示されます。

私が遭遇している問題は、テキスト領域にテキストの行が多すぎると、3行目のボタンが折り返されることです。これは、外枠の高さに関係ありません。

行2の高さが行3の幅に影響しています。この動作がわかりません。誰かが私が間違っているのは何ですか、そしてどうすればそれを修正できるのか教えてもらえますか?コードを添付しました。

少し異なるトピックで、コードを見ている場合、一番下のコンポーネントと一番外側のパネルの間にマージンを残す方法を提案できますか?

よろしくお願いします。

よろしく、
ピーター



    private static JButton CreateImageButton(String fileName) {
        JButton retVal = new JButton("xxx");
        return retVal;
    }

    public MoviePanel() {
        this.setLayout(new GridBagLayout());
        this.setBackground(Color.WHITE);

        JButton btnRefresh = CreateImageButton("refresh.png");
        GridBagConstraints c = new GridBagConstraints(); 
        c.gridx=0;
        c.gridy=0;
        c.fill = GridBagConstraints.NORTH;
        c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
        this.add(btnRefresh, c);

        JComboBox cbMovieList = new JComboBox();
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets.right = 10; c.insets.top = 10;
        c.weightx = 1.0;
        this.add(cbMovieList, c);

        JButton btnAuthorize = new JButton("Get Info");
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.anchor = GridBagConstraints.WEST;
        c.insets.top = 10;
        this.add(btnAuthorize, c);

        JTextArea txtInfo = new JTextArea();
        txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
        txtInfo.setBackground(Color.cyan);
        // txtInfo.setText("abc\ndef");
        txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 2;
        c.anchor = GridBagConstraints.NORTHWEST;
        c.weighty = 1.0;
        c.insets.top = 10;

        this.add(txtInfo, c);

        JPanel controllerOuter = new JPanel();
        controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
        controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());

        FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
        controllerLayout.setHgap(0);
        JPanel controller = new JPanel(controllerLayout);

        controller.setBorder(new EmptyBorder(10, 10, 10, 10));

        Dimension dim = new Dimension(60, 40);
        JButton btnPlay = CreateImageButton("play.png");
        btnPlay.setPreferredSize(dim);

        controller.add(btnPlay);
        JButton btnPause = CreateImageButton("pause.png");
        btnPause.setPreferredSize(dim);
        controller.add(btnPause);
        JButton btnStop = CreateImageButton("stop.png");
        btnStop.setPreferredSize(dim);
        controller.add(btnStop);
        JButton btnForward = CreateImageButton("forward.png");
        btnForward.setPreferredSize(dim);
        controller.add(btnForward);
        JComboBox cbAspectRatio = new JComboBox();
        cbAspectRatio.setPreferredSize(new Dimension(100, 40));
        cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
        controller.add(cbAspectRatio);

        controllerOuter.add(controller);

        JProgressBar pbProgress = new JProgressBar(0, 100);
        pbProgress.setPreferredSize(new Dimension(350, 40));
        pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
        pbProgress.setValue(50);
        pbProgress.setString("50/100");
        pbProgress.setStringPainted(true);
        pbProgress.setForeground(Color.BLUE);
        pbProgress.setBorderPainted(true);
        controllerOuter.add(pbProgress);


        c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 2;
        c.weightx = 1.0;
        this.add(controllerOuter, c);
    }

これが画像です

4

2 に答える 2

4

私はあなたのコードにいくつかのことを見ます:

  1. JButtonのpreferredSizeを強制します。可能であれば、それを削除します。これは、解決策よりも多くの問題が発生することが多いためです。PreferredSizeを強制する場合は、最小サイズと最大サイズも設定するように注意する必要があります。そうしないと、観察しているような奇妙な動作が発生します。
  2. BoxLayoutを使用してコントロールを表示します。これは完全に許容できますが、BoxLayoutは、設定しなかったレイアウトを実行するために最小/最大サイズにも依存します。
  3. 覆い隠されたレイアウトを使用します。これも問題ありませんが、MoviePanelのGridBagLayoutだけを使用してみませんか?
  4. 通常、テキストが大きすぎる場合に備えて、TextAreasはJScrollPaneでラップされます。TextAreaでsetLineWrap(true)を設定して、右側に行き過ぎないようにすることもできます。TextAreaに行/列を設定することにより、preferreSizeを定義します(含まれているテキストに依存しないようにするため)。
  5. GridBagConstraints場合、fillプロパティは、、、、または(そのうちの1つにVERTICALを使用しました)のみにすることができNONEます。また、新しいインスタンスを再作成する必要はありません。同じGridBagConstraintを何度も再利用できます。コンポーネントの制約を設定すると、LayoutManagerによって自動的に複製されます。VERTICALHORIZONTALBOTH

今、解決策について、私はいくつかを見つけました:

  1. を追加するときはcontollerOuter、も指定しますc.fill = GridBagConstraints.HORIZONTAL;(これが問題を解決する最も簡単な方法です)
  2. JButtonのpreferredSizeを設定するときは、それらのminimumSizeも同じ値に強制します。
  3. すべてのコンポーネントをレイアウトするには、GridBagLayoutのみを使用してください。(これは私のお気に入りです)
  4. FlowLayoutをX_AXISのBoxLayoutに置き換えます。

GridBagConstraintsプロパティを覚えておいてください:

  • gridx、gridy:場所を指定します
  • gridwidth、gridheight:colspan/rowspanを指定します
  • weightx、weighty:誰がどの比率で追加の水平/垂直スペースを取得するかを指定します
  • アンカー:「セル」がコンポーネントよりも大きい場合、コンポーネントとその「セル」の位置合わせを指定します
  • fill:コンポーネントをセルの幅/高さまで伸ばすかどうかを指定します
于 2012-05-09T10:34:22.337 に答える
3

JPanelに1つずつ追加するだけCenter and Bottomでうまくいくので、JTextAreaあなたのGridBagLayout意志が目的を果たすまで、その後BorderLayoutはMAINのJPanelがそれを行います。さらに、JScrollPane全体に追加することで、他の領域で必要な労力を削減できます。コードと出力を見てください:

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

public class JTextPaneExample extends JPanel
{
    private Icon info = UIManager.getIcon("OptionPane.informationIcon");
    private Icon error = UIManager.getIcon("OptionPane.errorIcon");

    private static JButton CreateImageButton(String fileName) {
        JButton retVal = new JButton("xxx");
        return retVal;
    }

    private void createAndDisplayGUI()
    {
        JFrame frame = new JFrame("JTextPane Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setLayout(new BorderLayout());
        this.setBackground(Color.WHITE);

        JPanel centerPanel = new JPanel();
        centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        centerPanel.setLayout(new GridBagLayout());
        centerPanel.setBackground(Color.WHITE);
        JButton btnRefresh = CreateImageButton("refresh.png");
        GridBagConstraints c = new GridBagConstraints(); 
        c.gridx=0;
        c.gridy=0;
        c.fill = GridBagConstraints.NORTH;
        c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
        centerPanel.add(btnRefresh, c);

        JComboBox cbMovieList = new JComboBox();
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 0;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets.right = 10; c.insets.top = 10;
        c.weightx = 1.0;
        centerPanel.add(cbMovieList, c);

        JButton btnAuthorize = new JButton("Get Info");
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 1;
        c.anchor = GridBagConstraints.WEST;
        c.insets.top = 10;
        centerPanel.add(btnAuthorize, c);

        JTextArea txtInfo = new JTextArea();
        txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
        txtInfo.setBackground(Color.cyan);
        // txtInfo.setText("abc\ndef");
        txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
        JScrollPane scroller = new JScrollPane();
        scroller.setViewportView(txtInfo);
        c = new GridBagConstraints();
        c.gridx = 1;
        c.gridy = 2;
        c.anchor = GridBagConstraints.NORTHWEST;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weighty = 1.0;
        c.insets.top = 10;

        centerPanel.add(scroller, c);

        JPanel controllerOuter = new JPanel();
        controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
        controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());

        FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
        controllerLayout.setHgap(0);
        JPanel controller = new JPanel(controllerLayout);

        controller.setBorder(new EmptyBorder(10, 10, 10, 10));

        Dimension dim = new Dimension(60, 40);
        JButton btnPlay = CreateImageButton("play.png");
        btnPlay.setPreferredSize(dim);

        controller.add(btnPlay);
        JButton btnPause = CreateImageButton("pause.png");
        btnPause.setPreferredSize(dim);
        controller.add(btnPause);
        JButton btnStop = CreateImageButton("stop.png");
        btnStop.setPreferredSize(dim);
        controller.add(btnStop);
        JButton btnForward = CreateImageButton("forward.png");
        btnForward.setPreferredSize(dim);
        controller.add(btnForward);
        JComboBox cbAspectRatio = new JComboBox();
        cbAspectRatio.setPreferredSize(new Dimension(100, 40));
        cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
        controller.add(cbAspectRatio);

        controllerOuter.add(controller);

        JProgressBar pbProgress = new JProgressBar(0, 100);
        pbProgress.setPreferredSize(new Dimension(350, 40));
        pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
        pbProgress.setValue(50);
        pbProgress.setString("50/100");
        pbProgress.setStringPainted(true);
        pbProgress.setForeground(Color.BLUE);
        pbProgress.setBorderPainted(true);
        controllerOuter.add(pbProgress);

        add(centerPanel, BorderLayout.CENTER);
        add(controllerOuter, BorderLayout.PAGE_END);

        frame.getContentPane().add(this);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new JTextPaneExample().createAndDisplayGUI();
            }           
        });
    }
}

行を追加したときの出力は次のとおりです。

レイアウト

于 2012-05-09T10:31:39.007 に答える