[英]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: 上图显示:
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
andgetPreferredSize
methods return the same value,SpringLayout
interprets this as meaning that the component should not be stretched. 当组件的getMaximumSize
和getPreferredSize
方法返回相同的值时,SpringLayout
将此解释为意味着不应该拉伸组件。
Thus with SpringLayout
and manually setting Y
's and Z
's maximum size, the ideal layout outlined above can be achieved. 因此,使用SpringLayout
并手动设置Y
和Z
的最大尺寸,可以实现上述理想布局。 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.