原文: http://zetcode.com/gui/jrubyswing/layout/

在 JRuby Swing 编程教程的这一部分中,我们将介绍布局管理器。

在设计应用的 GUI 时,我们决定要使用哪些组件以及如何在应用中组织这些组件。 为了组织我们的组件,我们使用专门的不可见对象,称为布局管理器。 Swing 工具箱包含两种组件。 容器和子项。 容器将子项分组为合适的布局。 要创建布局,我们使用布局管理器。

绝对定位

在大多数情况下,程序员应使用布局管理器。 在某些情况下,我们可以使用绝对定位。 在绝对定位中,程序员以像素为单位指定每个组件的位置和大小。 如果调整窗口大小,则组件的大小和位置不会更改。 在各种平台上,应用看起来都不同,在 Linux 上看起来不错,在 Mac OS 上看起来不太正常。 在应用中更改字体可能会破坏布局。 如果将应用翻译成另一种语言,则必须重做布局。 对于所有这些问题,仅在有理由时才使用绝对定位。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program, we lay out three images
  5. # using absolute positioning.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.Color
  12. import javax.swing.ImageIcon
  13. import javax.swing.JLabel
  14. import javax.swing.JPanel
  15. import javax.swing.JFrame
  16. class Example < JFrame
  17. def initialize
  18. super "Absolute"
  19. self.initUI
  20. end
  21. def initUI
  22. panel = JPanel.new
  23. panel.setLayout nil
  24. panel.setBackground Color.new 66, 66, 66
  25. self.getContentPane.add panel
  26. rot = ImageIcon.new "rotunda.jpg"
  27. rotLabel = JLabel.new rot
  28. rotLabel.setBounds 20, 20, rot.getIconWidth, rot.getIconHeight
  29. min = ImageIcon.new "mincol.jpg"
  30. minLabel = JLabel.new min
  31. minLabel.setBounds 40, 160, min.getIconWidth, min.getIconHeight
  32. bar = ImageIcon.new "bardejov.jpg"
  33. barLabel = JLabel.new bar
  34. barLabel.setBounds 170, 50, bar.getIconWidth, bar.getIconHeight
  35. panel.add rotLabel
  36. panel.add minLabel
  37. panel.add barLabel
  38. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  39. self.setSize 350, 300
  40. self.setLocationRelativeTo nil
  41. self.setVisible true
  42. end
  43. end
  44. Example.new

在此示例中,我们使用绝对定位显示了三幅图像。

  1. panel.setLayout nil

Swing 中的容器已经具有默认的布局管理器。 JPanel具有FlowLayout管理器作为其默认布局管理器。 我们将setLayout方法与nil参数一起使用,以删除默认的布局管理器,而改用绝对定位。

  1. rot = ImageIcon.new "rotunda.jpg"
  2. rotLabel = JLabel.new rot
  3. rotLabel.setBounds 20, 20, rot.getIconWidth, rot.getIconHeight

我们创建一个ImageIcon对象。 我们将图标放入JLabel组件中以显示它。 然后,我们使用setBounds方法将标签放置在面板上。 前两个参数是标签的 x,y 位置。 第 3 和第 4 个参数是图标的宽度和高度。

  1. panel.add rotLabel

我们将标签添加到面板容器中。

JRuby Swing 中的布局管理 - 图1

图:绝对定位

按钮示例

在下面的示例中,我们将在窗口的右下角放置两个按钮。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program, we use the BoxLayout
  5. # manager to position two buttons in the
  6. # bottom right corner of the window.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: December 2010
  11. include Java
  12. import java.awt.Dimension
  13. import javax.swing.JButton
  14. import javax.swing.JPanel
  15. import javax.swing.JFrame
  16. import javax.swing.BoxLayout
  17. import javax.swing.Box
  18. class Example < JFrame
  19. def initialize
  20. super "Buttons"
  21. self.initUI
  22. end
  23. def initUI
  24. basic = JPanel.new
  25. basic.setLayout BoxLayout.new basic, BoxLayout::Y_AXIS
  26. self.add basic
  27. basic.add Box.createVerticalGlue
  28. bottom = JPanel.new
  29. bottom.setLayout BoxLayout.new bottom, BoxLayout::X_AXIS
  30. bottom.setAlignmentX 1.0
  31. okButton = JButton.new "OK"
  32. closeButton = JButton.new "Close"
  33. bottom.add okButton
  34. bottom.add Box.createRigidArea Dimension.new 5, 0
  35. bottom.add closeButton
  36. bottom.add Box.createRigidArea Dimension.new 15, 0
  37. basic.add bottom
  38. basic.add Box.createRigidArea Dimension.new 0, 15
  39. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  40. self.setSize 300, 200
  41. self.setLocationRelativeTo nil
  42. self.setVisible true
  43. end
  44. end
  45. Example.new

我们将创建两个面板。 基本面板具有垂直框布局。 底部面板有一个水平面板。 我们将在基础面板中放置一个底部面板。 我们将右对齐底部面板。 窗口顶部和底部面板之间的空间是可扩展的。 这是通过垂直胶水完成的。

  1. basic = JPanel.new
  2. basic.setLayout BoxLayout.new basic, BoxLayout::Y_AXIS
  3. ...
  4. bottom = JPanel.new
  5. bottom.setLayout BoxLayout.new bottom, BoxLayout::X_AXIS

基本面板具有垂直框布局。 底部面板具有水平框布局。

  1. bottom.setAlignmentX 1.0

底部面板右对齐。

  1. basic.add Box.createVerticalGlue

我们创建一个垂直胶水。 胶水是垂直可扩展的白色空间,它将带有按钮的水平框推到底部。

  1. okButton = JButton.new "OK"
  2. closeButton = JButton.new "Close"

这是两个将进入窗口右下角的按钮。

  1. bottom.add okButton
  2. bottom.add Box.createRigidArea Dimension.new 5, 0

我们将“确定”按钮放入水平框中。 我们在按钮旁边放置了一些刚性空间。 这样两个按钮之间会有一些空间。

  1. basic.add Box.createRigidArea Dimension.new 0, 15

我们在按钮和窗口的边框之间留出一些空间。

JRuby Swing 中的布局管理 - 图2

图:按钮示例

Windows 示例

以下示例使用GroupLayout管理器创建 Windows 对话框。 该对话框来自 JDeveloper 应用。

GroupLayout管理器将布局的创建分为两个步骤。 第一步,我们沿着水平轴布置组件。 在第二步中,我们沿垂直轴布置组件。 这在布局管理器中是一个不寻常的想法,但效果很好。

有两种类型的安排:顺序安排和并行安排。 在两种布局中,我们都可以顺序或并行排列组件。 在水平布局中,一行组件称为顺序组。 一列组件称为并行组。 在垂直布局中,一列组件称为顺序组。 一排组件称为并行组。 您必须正确理解这些定义才能与GroupLayout管理器一起使用。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program, GroupLayout
  5. # manager to create a Windows
  6. # example.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: December 2010
  11. include Java
  12. import java.awt.Dimension
  13. import java.awt.Color
  14. import javax.swing.JButton
  15. import javax.swing.SwingConstants
  16. import javax.swing.JFrame
  17. import javax.swing.JLabel
  18. import javax.swing.JTextArea
  19. import javax.swing.BorderFactory
  20. import javax.swing.GroupLayout
  21. class Example < JFrame
  22. def initialize
  23. super "Windows"
  24. self.initUI
  25. end
  26. def initUI
  27. layout = GroupLayout.new self.getContentPane
  28. self.getContentPane.setLayout layout
  29. layout.setAutoCreateGaps true
  30. layout.setAutoCreateContainerGaps true
  31. self.setPreferredSize Dimension.new 350, 300
  32. windows = JLabel.new "Windows"
  33. area = JTextArea.new
  34. area.setEditable false
  35. area.setBorder BorderFactory.createLineBorder Color.gray
  36. activateButton = JButton.new "Activate"
  37. closeButton = JButton.new "Close"
  38. helpButton = JButton.new "Help"
  39. okButton = JButton.new "OK"
  40. sg = layout.createSequentialGroup
  41. pg1 = layout.createParallelGroup
  42. pg2 = layout.createParallelGroup
  43. pg1.addComponent windows
  44. pg1.addComponent area
  45. pg1.addComponent helpButton
  46. sg.addGroup pg1
  47. pg2.addComponent activateButton
  48. pg2.addComponent closeButton
  49. pg2.addComponent okButton
  50. sg.addGroup pg2
  51. layout.setHorizontalGroup sg
  52. sg1 = layout.createSequentialGroup
  53. sg2 = layout.createSequentialGroup
  54. pg1 = layout.createParallelGroup
  55. pg2 = layout.createParallelGroup
  56. sg1.addComponent windows
  57. pg1.addComponent area
  58. sg2.addComponent activateButton
  59. sg2.addComponent closeButton
  60. pg1.addGroup sg2
  61. sg1.addGroup pg1
  62. pg2.addComponent helpButton
  63. pg2.addComponent okButton
  64. sg1.addGroup pg2
  65. layout.setVerticalGroup sg1
  66. layout.linkSize SwingConstants::HORIZONTAL,
  67. okButton, helpButton, closeButton, activateButton
  68. self.pack
  69. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  70. self.setLocationRelativeTo nil
  71. self.setVisible true
  72. end
  73. end
  74. Example.new

我们使用GroupLayout管理器创建由六个组件组成的布局。 组件组沿两个轴形成。

  1. sg = layout.createSequentialGroup
  2. pg1 = layout.createParallelGroup
  3. pg2 = layout.createParallelGroup
  4. pg1.addComponent windows
  5. pg1.addComponent area
  6. pg1.addComponent helpButton
  7. sg.addGroup pg1
  8. pg2.addComponent activateButton
  9. pg2.addComponent closeButton
  10. pg2.addComponent okButton
  11. sg.addGroup pg2
  12. layout.setHorizontalGroup sg

第一步,我们有一个水平布局。 它由两组平行的三个部分组成。

  1. sg1 = layout.createSequentialGroup
  2. sg2 = layout.createSequentialGroup
  3. pg1 = layout.createParallelGroup
  4. pg2 = layout.createParallelGroup
  5. sg1.addComponent windows
  6. pg1.addComponent area
  7. sg2.addComponent activateButton
  8. sg2.addComponent closeButton
  9. pg1.addGroup sg2
  10. sg1.addGroup pg1
  11. pg2.addComponent helpButton
  12. pg2.addComponent okButton
  13. sg1.addGroup pg2
  14. layout.setVerticalGroup sg1

垂直布局有点复杂。 首先,我们添加一个组件。 然后,我们添加一个包含单个组件的并行组和一个包含两个组件的顺序组。 最后,我们添加两个组件的并行组。

  1. layout.linkSize SwingConstants::HORIZONTAL,
  2. okButton, helpButton, closeButton, activateButton

此代码使所有按钮的大小相同。 我们只需要设置它们的宽度,因为默认情况下它们的高度已经相同。

JRuby Swing 中的布局管理 - 图3

图:窗口示例

查看示例的屏幕截图。 注意,可以将组件分为垂直和水平组件集。 例如,标签,区域和“帮助”按钮组件可以形成垂直的组件组。 这正是GroupLayout管理器所做的。 它通过形成组件的垂直和水平组来布局组件。

在 JRuby Swing 教程的这一部分中,我们提到了组件的布局管理。