2

コンポーネントを垂直に配置するのに役立つレイアウトマネージャー(またはレイアウトマネージャーのセット)を探しています。すべてのコンポーネント(ボタン)は同じ幅で、下にあるダイアログクライアント領域の幅で縁取られている必要があります。これらの各ボタンは、接続されているJLabelに応じて高さを拡張できます(ユーザーが関連するボタンをクリックするとラベルが表示されます)-要するに、すべてのコンポーネントは同じ固定幅に引き伸ばされる必要がありますが、可変ですコンテンツに応じた高さ。必要に応じて、垂直スクロールバーをサポートするために、ダイアログコンテンツ全体をJScrollPane内に配置する必要があります。

私は、目的の動作を実装するために、さまざまなレイアウトマネージャー(主に水平方向のストレッチ用のborderlayoutと垂直方向の配置用のboxlayout)を積み重ねたところです。しかし、それは満足のいくコードではなく、私が望むように完全に機能するわけでもありません。

私はこの問題のためにインターネットをサーフィンすることに多くの時間を費やし、垂直レイアウトがJavaで一般的な問題であることを発見しました。多くの人がGridBagLayoutがこの仕事をするのに最適なレイアウトだと答えましたが、私はそれを私が望むように動作させることができませんでした。

それが私にその問題の助けを与えるのに十分な情報であることを願っています。

よろしくマイケル

編集:-もう必要ありません-

編集2:

これが私の現在の試みの画像です: http ://www.pic-upload.de/view-16978954/example-image.png.html

これはほとんど私が望む結果ですが、サイズ変更には奇妙な振る舞いがあります。

編集3:

私の主な問題は、JLabelを含むhtmlと組み合わせたJScrollPaneだと思います。setMaximumSize(...)のようなものが必要ですが、正常に機能しません: http ://www.pic-upload.de/view- 16988005 / example-image3.png.html

固定幅が必要ですが、設定方法がわかりません。

setPreferredSize(...)は機能しますが、HTMLテキストが含まれているため、JLabelの高さがわかりません。

編集4:

私のボタン:

public class Expander extends JPanel implements ActionListener {

    private static class HtmlViewer extends JLabel {

        private static final long serialVersionUID = 8787130155299083869L;


        public HtmlViewer(String doc) {
            super(doc);
            this.setBackground(Color.WHITE);
            this.setOpaque(true);
        }
    }


    private static final long serialVersionUID = 4480221797736558685L;


    JToggleButton button;
    JComponent component;


    public Expander(String text, String doc) {
        this(text, new HtmlViewer(doc));
    }

    public Expander(String text, JComponent expandableComponent) {
        this.setLayout(new BorderLayout());

        button = new JToggleButton(text) {
            private static final long serialVersionUID = -3330376265192275758L;

            @Override
            public void paint(Graphics g) {
                super.paint(g);

                if (this.isSelected()) {
                    g.drawString("▼", this.getWidth() - 20, 15);
                } else {
                    g.drawString("■", this.getWidth() - 20, 15);
                }
            }
        };

        button.setFocusPainted(false);
        button.addActionListener(this);

        component = expandableComponent;
        component.setBorder(new EmptyBorder(5, 5, 5, 5));

        this.add(button, BorderLayout.PAGE_START);
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if (button.isSelected()) {
            this.add(component);
        } else {
            this.remove(component);
        }
        this.getTopLevelAncestor().validate();
        this.getTopLevelAncestor().repaint();
        this.setMaximumSize(this.getPreferredSize());
    }
}

フレーム:

public class grid2 {

    public static void main(String[] args) {

        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel p = new JPanel();
        JScrollPane scroll = new JScrollPane(p, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        addStuff(p);

        frame.add(scroll);

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

    public static void addStuff(Container container) {
        container.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weightx = 1;
        c.weighty = 0;

        Expander e = new Expander("test", "<html>fgb fdh fgfhg ifghiufdshfidsghfiufdsghiudsfhdsfiu dshiufhds if dhf idsufhdsiufhiufhiuds hfdshfiudshfuidsifudshfiudshf  ufdhfiushdfiudshiufhdsiufhdsiuf udshfiudshfiudshfudshf iuhfiudshfiudshfiudshf</html>"); // long html text example
        e.setMaximumSize(new Dimension(500, 10000));
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = GridBagConstraints.REMAINDER;
        container.add(e, c);

        JButton button2 = new JButton("Button 2");
        c.gridy = 1;
        c.gridwidth = GridBagConstraints.REMAINDER;
        container.add(button2, c);

        c.gridy = 2;
        c.weighty = 1;
        c.gridwidth = GridBagConstraints.REMAINDER;
        container.add(new JLabel(), c);
    }
}
4

4 に答える 4

3

http://docs.oracle.com/javase/tutorial/uiswing/layout/box.htmlを参照してください

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

例

于 2012-11-20T15:24:27.170 に答える
2

私が使用するのはGridBagLayoutです。これはHTMLテーブルに似ており、GridBagConstraintsを使用して、オブジェクトを水平方向と垂直方向の両方に展開するように設定できます(例constraints.fill = GridBagConstraints.BOTH) 。

これで下の写真の問題が解決すると思います(下部に空白のラベルを追加してボタンを上部に留めるための小さなハックがありますが、いじくり回すとこれを削除できると確信しています)

public static void main(String[] args) {
    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    addStuff(frame.getContentPane());

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

public static void addStuff(Container container) {
    container.setLayout(new GridBagLayout());

    GridBagConstraints c = new GridBagConstraints();
    c.fill = GridBagConstraints.HORIZONTAL;
    c.weightx = 1;
    c.weighty = 0;

    JButton button = new JButton("Button 1");
    c.gridx = 0;
    c.gridy = 0;
    container.add(button, c);

    JButton button2 = new JButton("Button 2");
    c.gridy = 1;
    container.add(button2, c);

    c.gridy = 2;
    c.weighty = 1;
    container.add(new JLabel(), c);
}
于 2012-11-20T15:24:33.707 に答える
1

ここでいくつかの問題:

  1. BorderLayoutJFrameあなたを伸ばすでしょうJPanel p
  2. 設定しないweightxので、fill属性は役に立ちません

ソリューション:

  1. 上部に配置される別のパネルでラップするJPanel pか、最後に非表示のJPanelを追加して、コンポーネントをプッシュします。
  2. weightxプロパティをに設定します1.0

これが機能するデモコード(あなたのものに基づく)です:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Gridbag {

    public void initUI() {
        JFrame frame = new JFrame();

        frame.setSize(500, 500);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel p = new JPanel(new GridBagLayout());

        GridBagConstraints constraints = new GridBagConstraints();
        JButton button = new JButton("button 1");
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.anchor = GridBagConstraints.PAGE_START;
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.weightx = 1.0;
        p.add(button, constraints);

        button = new JButton("button 2");
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.anchor = GridBagConstraints.PAGE_START;
        p.add(button, constraints);
        JPanel root = new JPanel(new GridBagLayout());
        constraints.weighty = 1.0;
        root.add(p, constraints);
        frame.add(root);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Gridbag().initUI();
            }
        });
    }

}
于 2012-11-20T16:46:40.007 に答える
1

OK、動作しました。私は完全に間違っていました。JScrollPaneがこの問題のトラブルメーカーだと思いましたが、それはJLabelでした。JLabelにHTMLテキストが含まれている場合、テキストは自動的に折り返されません。そのため、ダイアログの幅が小さすぎると、すべてが水平方向に引き伸ばされます。私はここでこの問題の良い解決策を見つけました:最大幅を設定することによってJLabelがテキストをラップするようにします

回答6:

JLabel labelBeingUsed = myLabel;
View view = (View) labelBeingUsed.getClientProperty(BasicHTML.propertyKey);
view.setSize(scrollPane1.getWidth(), 0.0f);
float w = view.getPreferredSpan(View.X_AXIS);
float h = view.getPreferredSpan(View.Y_AXIS);
labelBeingUsed.setSize((int) w, (int) h);

ダイアログのサイズを変更するたびに、上記のコードを使用して、JLabelを含む各HTMLの幅を目的の幅に更新する必要があります。

役立つヒントをありがとうございました。

于 2012-11-22T09:12:12.217 に答える