简体   繁体   English

如何布置组件以使中间组件获得所有空间,但最右边的组件是否对齐?

[英]How to lay out components so that the middle component gets all the space, but the right-most component is aligned left?

I have a panel that consists of a button (X), a label (Y), and a progress bar (Z). 我有一个面板,包括一个按钮(X),一个标签(Y)和一个进度条(Z)。 Ideally I would like to lay them out like so: 理想情况下,我想这样做:

| X-X Y---------------Y Z---Z ============= |  <-- expanded-size panel
                              ^ extra space

| X-X Y------Y Z---Z |                         <-- reduced-size panel

The diagram above shows: 上图显示:

  • When the panel expands, extra space should go to the label (Y) so that the label can completely show its text. 当面板展开时,额外的空间应该转到标签(Y),以便标签可以完全显示其文本。
  • The progress bar (Z) should always remain next to the label (Y). 进度条(Z)应始终保留在标签(Y)旁边。
  • When the panel is reduced, the label (Y)'s size should be reduced. 面板缩小时,标签(Y)的尺寸应减小。
  • The button (X) and the progress bar (Z)'s sizes should be constant, not the label (Y)'s size. 按钮(X)和进度条(Z)的大小应该是常量, 而不是标签(Y)的大小。

However, when I try using GroupLayout, this is what happens when the panel is expanded: 但是,当我尝试使用GroupLayout时,这是扩展面板时发生的情况:

| X-X Y---------------Y ============= Z---Z |  <-- expanded-size panel (bad)

The problem is that when the panel has extra space, the label (Y) gets expanded beyond what it needs, which pushes the progress bar (Z) to the right. 问题是当面板有额外的空间时,标签(Y)会扩展到超出需要的范围,这会将进度条(Z)推向右侧。 I would prefer that the progress bar's (Z) position is next to the label (Y). 我希望进度条的(Z)位置在标签(Y)旁边。

How can I accomplish this layout? 我怎样才能完成这个布局?

Example code ("Blah.java"): 示例代码(“Blah.java”):

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

public class Blah extends JPanel {
    public Blah() {
        final JButton X = new JButton("X");
        final JLabel Y = new JLabel("yyyyyyyyyyy");
        Y.setOpaque(true);
        Y.setBackground(Color.YELLOW);
        final JProgressBar Z = new JProgressBar();
        Z.setIndeterminate(true);

        final GroupLayout l = new GroupLayout(this);
        super.setLayout(l);

        l.setHorizontalGroup(
                l.createSequentialGroup()
                .addComponent(X, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addComponent(Y, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(Z, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE));

        l.setVerticalGroup(
                l.createParallelGroup()
                .addComponent(X)
                .addComponent(Y)
                .addComponent(Z));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame frame = new JFrame("Blah");
                frame.add(new Blah());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

It is very rare that one individual layout manager will meet all your needs. 一个单独的布局管理器很少能满足您的所有需求。 Instead you could use a compound layout approach. 相反,您可以使用复合布局方法。

That is, separate each individual layout requirement into a separate component, with it's own layout manager. 也就是说,将每个单独的布局要求分成一个单独的组件,并使用它自己的布局管理器。 Then added all these to your master component, managing the overall requirements. 然后将所有这些添加到主组件中,管理总体要求。

As an example 举个例子

在此输入图像描述在此输入图像描述

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class SimpleGridBagLayout {

    public static void main(String[] args) {
        new SimpleGridBagLayout();
    }

    public SimpleGridBagLayout() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {

            setLayout(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            add(createLabel("XXX-XXX", Color.BLUE), gbc);

            JPanel panel = new JPanel();
            panel.add(createLabel("Y-Y", Color.RED));
            panel.add(createLabel("ZZZZZ---ZZZZZ", Color.GREEN), gbc);

            gbc.gridx++;
            gbc.weightx = 1;
            add(panel, gbc);

        }

        protected JLabel createLabel(String text, Color border) {

            JLabel label = new JLabel(text);
            label.setBorder(new LineBorder(border));
            return label;

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 100);
        }
    }

}

There are a number of factors at play here. 这里有很多因素在起作用。 The preferred and minimum sizes of the child components will make a significant difference to how some layout managers layout there components when the available size is to small. 子组件的首选大小和最小大小将对可用大小较小时布局管理器布局组件的方式产生重大影响。

Updated 更新

public TestPane() {

    setLayout(new GridBagLayout());

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridx = 0;
    add(createLabel("XXX-XXX", Color.BLUE), gbc);

    JPanel panel = new JPanel(new GridBagLayout());
    gbc = new GridBagConstraints();
    gbc.gridx = 0;
    panel.add(createLabel("Y-Y", Color.RED), gbc);
    gbc.gridx = 1;
    panel.add(createLabel("ZZZZZ---ZZZZZ", Color.GREEN), gbc);

    gbc = new GridBagConstraints();
    gbc.gridx = 1;
    gbc.weightx = 1;
    add(panel, gbc);

}

Updated 更新

Now with "non-shrinking" progress bar 现在有了“不缩水”的进度条

public class TestPane extends JPanel {

    public TestPane() {

        setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        add(createLabel("XXX-XXX", Color.BLUE), gbc);

        JPanel panel = new JPanel(new GridBagLayout());
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        panel.add(createLabel("Y-Y", Color.RED), gbc);
        gbc.gridx = 1;
        MyProgressBar pb = new MyProgressBar();
        panel.add(pb, gbc);

        gbc = new GridBagConstraints();
        gbc.gridx = 1;
        gbc.weightx = 1;
        add(panel, gbc);

    }

    protected JLabel createLabel(String text, Color border) {

        JLabel label = new JLabel(text);
        label.setBorder(new LineBorder(border));
        return label;

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 100);
    }
}

public class MyProgressBar extends JProgressBar {

    @Override
    public Dimension getPreferredSize() {
        Dimension ps = super.getPreferredSize();
        ps.width = 75;
        return ps;
    }

    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }

}

After banging my head against the wall for far too long, I discovered this little gem of documentation in SpringLayout 's tutorial ( http://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html ): 在将我的头撞到墙上太久之后,我在SpringLayout的教程( http://docs.oracle.com/javase/tutorial/uiswing/layout/spring.html )中发现了这个小文档。

When a component's getMaximumSize and getPreferredSize methods return the same value, SpringLayout interprets this as meaning that the component should not be stretched. 当组件的getMaximumSizegetPreferredSize方法返回相同的值时, SpringLayout将此解释为意味着不应该拉伸组件。

Thus with SpringLayout and manually setting Y 's and Z 's maximum size, the ideal layout outlined above can be achieved. 因此,使用SpringLayout并手动设置YZ的最大尺寸,可以实现上述理想布局。 Here's the code: 这是代码:

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

public class Blah extends JPanel {
    public Blah() {
        final JButton X = new JButton("X");
        final JLabel Y = new JLabel("yyyyyyyyyyy");
        Y.setOpaque(true);
        Y.setBackground(Color.YELLOW);
        final JProgressBar Z = new JProgressBar();
        Z.setIndeterminate(true);

        final SpringLayout l = new SpringLayout();
        super.setLayout(l);

        super.add(X);
        super.add(Y);
        super.add(Z);

        Z.setMaximumSize(Z.getPreferredSize());

        l.putConstraint(SpringLayout.WEST, X, 10, SpringLayout.WEST, this);
        l.putConstraint(SpringLayout.WEST, Y, 10, SpringLayout.EAST, X);
        l.putConstraint(SpringLayout.WEST, Z, 10, SpringLayout.EAST, Y);
        l.putConstraint(SpringLayout.EAST, this, 10, SpringLayout.EAST, Z);

        l.putConstraint(SpringLayout.NORTH, X, 10, SpringLayout.NORTH, this);
        l.putConstraint(SpringLayout.NORTH, Y, 10, SpringLayout.NORTH, this);
        l.putConstraint(SpringLayout.NORTH, Z, 10, SpringLayout.NORTH, this);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final JFrame frame = new JFrame("Blah");
                frame.add(new Blah());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何布置我的按钮,以便它们从左上方到右下方(先填充第一行,然后填充第二行) - How do i lay out my buttons so they will go from top left to bottom right (filling first row then second) 在Java中查找左/右最多未设置位的索引的最有效方法是什么? - What is the most efficient way of finding the index of the left/right-most unset bit in Java? 如何在JPanel上放置/布局组件? - How to position/lay out components on JPanel? Java SWT GridLayout可以从右到左布置小部件吗? - Can Java SWT GridLayout lay out widgets from right to left? java Swing:如何使一个组件与另一个组件左对齐,相对于父组件居中 - java Swing: how to keep one component left aligned with another component centered with respect to parent 如何在Swing中最好地布置这些组件? - How can I best lay out these components in Swing? Java,GridBagLayout。 如何将组件添加到其他组件 - Java, GridBagLayout. How add components right to other component 如何通过FlowLayout在左侧拥有一个组件而在右侧拥有一个组件 - How to have one component on the left and one on the right by FlowLayout 如何在j2me中从右到左设置组件方向? - How to set component orientation from right to left in j2me? 如何在中间设置ActionBar标题而不是默认的左对齐位置? - How to set the ActionBar title in middle instead of the default left aligned position?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM