Java Swing两个组件的布局

6
    +--------------------------------------------+
    |                 +-------+      +----------+|
    |                 | +---+ |      |  +-----+ ||
    |                 | | A | |      |  |  B  | ||
    |                 | +---+ |      |  +-----+ ||
    |                 +-------+      +----------+|
    +--------------------------------------------+
                          ^
                          |
                          |
                        Center

背景:我有

  • 一个大小为50x25的JButton(“A”),在JPanel(FlowLayout.CENTER)中
  • 一个大小为100x25的JLabel(“B”),在JPanel(FlowLayout.RIGHT)中
  • 这两个JPanel都在一个JPanel中

期望结果:我希望

  • JButton “A”始终水平居中,
  • JLabel “B”始终右对齐。

我尝试过的方法:但它们对我没有用

  • BorderLayout is not working for me because JButton "A" is shifted LEFT:
  • I'd prefer not to put an invisible component WEST to undo the shift

    +--------------------------------------------+
    |            +-------+           +----------+|
    |            | +---+ |           |  +-----+ ||
    |            | | A | |           |  |  B  | ||
    |            | +---+ |           |  +-----+ ||
    |            +-------+           +----------+|
    +--------------------------------------------+
                     ^    ^
                     |    |
                     |    |
                     |  Center
                     |
                   Shifted Left
    
  • GridLayout won't work because I don't want the "A" and "B" to be expanded

感谢任何建议!
附言:
JButton/JLabel各自位于自己的JPanel中,因为如果没有JPanel,BorderLayout.CENTER会将JButton扩展到整个主面板的宽度(直到JLabel的左边缘)。JPanels对问题陈述不是必需/关键。
结论:
我选择了下面发布的“满载鳗鱼的气垫船”的答案。谢谢!

4
不要明确设置任何组件的大小,这在这里已经被重复了无数次! - jfpoilpret
@jfpoilpret:有没有好的方法可以确保控件的大小恰好为100x25,而不需要显式设置它? - Vlad
1
除非按钮没有文本,否则你怎么知道它需要100x25的尺寸(不少于,也不是更重要的,大于)。同样的情况也适用于标签。 - Andrew Thompson
1
“你看到了吗?”不,我在Mac或*nix上没有看到那个..因为那些只针对一个操作系统。Java布局的重点是它们足够强大,可以处理不同的平台、PLAF、屏幕尺寸、分辨率..哦,还有忘记平台布局'holiwar' - Java是不可知的。;) - Andrew Thompson
1
@Vlad:我不知道你的陈述是否“证明”了WPF的布局更好,而只是对于这个例子来说它们更简单。即使它们对于所有用途都更简单,简单性只是一个因素;我们不知道它们的强大和可扩展性。 - Hovercraft Full Of Eels
显示剩余9条评论
1个回答

5
你应该嵌套JPanels并使用多种布局。将包含JButtons的面板放置到另一个使用GridLayout(1,0)(1行,可变数量的列)的JPanel中可能有效,然后将该JPanel放置到使用BorderLayout的JPanel的BorderLayout.NORTH位置可能有效。
例如:
import java.awt.*;
import javax.swing.*;

public class Foo003 {

   private static void createAndShowGui() {
      JButton btnA = new JButton("A");
      JButton btnB = new JButton("B");

      btnA.setPreferredSize(new Dimension(50, 25));
      btnB.setPreferredSize(new Dimension(100, 25));

      JPanel btnAPanel = new JPanel(); // uses default FlowLayout.CENTER
      JPanel btnBPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
      btnAPanel.add(btnA);
      btnBPanel.add(btnB);

      JPanel topPanel = new JPanel(new GridLayout(1, 0));
      topPanel.add(new JLabel("")); // empty placeholder label
      topPanel.add(btnAPanel);
      topPanel.add(btnBPanel);

      JPanel mainPanel = new JPanel(new BorderLayout());
      mainPanel.add(topPanel, BorderLayout.NORTH);

      mainPanel.setPreferredSize(new Dimension(400, 300));

      JFrame frame = new JFrame("Foo003");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

2
  1. 这不是琐碎的事情。
  2. 这很容易。
- Hovercraft Full Of Eels
@Hovercraft:在WPF中这既是微不足道又容易的。我认为Swing也不会更落后。 - Vlad
@Hovercraft:作为一个来自WPF的人,我发现Swing布局管理无法以一种简单的方式解决微不足道的布局任务令人沮丧。将WPF中OP问题的微不足道解决方案与您相当复杂的代码进行比较:<Grid><Panel Width="50" Height="25" HorizontalAlignment="Center"/><Panel Width="100" Height="25" HorizontalAlignment="Right"/></Grid>您还认为您的方法很容易吗?您还认为这个问题不是微不足道的吗? - Vlad
1
@Vlad:我不是在反驳你。每个工具都有其相对的优点和缺点。我个人喜欢Swing布局管理器,但我相对了解它们并且能够快速地设计出一个布局,但是我并不是说它们是最优的,因为它们并不是。但是它们确实有效,并且非常可扩展。 - Hovercraft Full Of Eels
谢谢,这非常有启发。我以前用过GridLayout,但不是你所描述的方式。感谢所有的回复! - casio car
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接