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

在 JRuby Swing 编程教程的这一部分中,我们将介绍基本的 Swing 组件。

组件是 GUI 应用的基本构建块。 多年来,一些组件已成为所有 OS 平台上所有工具包中的标准组件。 例如,按钮,复选框或滚动条。 Swing 具有丰富的组件集,可满足大多数编程需求。 可以将更多专用组件创建为自定义组件。

JCheckBox

JCheckBox是具有两种状态的组件:开和关。 开状态通过复选标记显示。 它用来表示一些布尔属性。 JCheckBox组件提供了一个带有文本标签的复选框。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # This program uses JCheckBox
  5. # component to show/hide the title
  6. # 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.JCheckBox
  14. import javax.swing.Box
  15. import javax.swing.BoxLayout
  16. import javax.swing.JFrame
  17. class Example < JFrame
  18. def initialize
  19. super "JCheckBox example"
  20. self.initUI
  21. end
  22. def initUI
  23. self.setLayout BoxLayout.new getContentPane, BoxLayout::Y_AXIS
  24. self.add Box.createRigidArea Dimension.new 15, 20
  25. cb = JCheckBox.new "Show Title", true
  26. cb.setBounds 50, 60, 80, 30
  27. cb.setFocusable(false)
  28. cb.add_action_listener do |e|
  29. if self.getTitle.empty?
  30. self.setTitle "JCheckBox example"
  31. else
  32. self.setTitle ""
  33. end
  34. end
  35. add cb
  36. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  37. self.setSize 300, 200
  38. self.setLocationRelativeTo nil
  39. self.setVisible true
  40. end
  41. end
  42. Example.new

在我们的示例中,我们在窗口上放置了一个复选框。 复选框显示或隐藏窗口的标题。

  1. self.setLayout BoxLayout.new getContentPane, BoxLayout::Y_AXIS
  2. self.add Box.createRigidArea Dimension.new 15, 20

在此示例中,我们使用BoxLayout布局管理器。 我们在此处放置一些空间,以使复选框不太靠近角落。

  1. cb = JCheckBox.new "Show Title", true

JCheckBox组件已创建。 构造器的第一个参数是其文本标签。 第二个参数是一个布尔值,指示初始选择状态。 如果为true,则选中该复选框。

  1. cb.setFocusable false

我们禁用复选框的焦点。 可以使用空格键选择或取消选择具有焦点的JCheckBox

  1. cb.add_action_listener do |e|
  2. if self.getTitle.empty?
  3. self.setTitle "JCheckBox example"
  4. else
  5. self.setTitle ""
  6. end
  7. end

在动作监听器内部,我们检查标题是否已设置。 如果有标题,我们将其删除。 如果没有标题,我们设置一个。 这样,我们可以切换标题的可见性。

JRuby Swing 中的组件 - 图1

图:JCheckBox

JLabel

JLabel组件用于显示文本,图像或两者。 没有用户交互。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program, we show lyrics of a
  5. # song in a window.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.BorderLayout
  12. import java.awt.Color
  13. import java.awt.Font
  14. import javax.swing.JFrame
  15. import javax.swing.BorderFactory
  16. import javax.swing.JPanel
  17. import javax.swing.JLabel
  18. class Example < JFrame
  19. def initialize
  20. super "Lyrics"
  21. self.initUI
  22. end
  23. def initUI
  24. lyrics = "<html>It's way too late to think of<br>
  25. Someone I would call now<br>
  26. And neon signs got tired<br>
  27. Red eye flights help the stars out<br>
  28. I'm safe in a corner<br>
  29. Just hours before me<br>
  30. <br>
  31. I'm waking with the roaches<br>
  32. The world has surrendered<br>
  33. I'm dating ancient ghosts<br>
  34. The ones I made friends with<br>
  35. The comfort of fireflies<br>
  36. Long gone before daylight<br>
  37. <br>
  38. And if I had one wishful field tonight<br>
  39. I'd ask for the sun to never rise<br>
  40. If God leant his voice for me to speak<br>
  41. I'd say go to bed, world<br>
  42. <br>
  43. I've always been too late<br>
  44. To see what's before me<br>
  45. And I know nothing sweeter than<br>
  46. Champaign from last New Years<br>
  47. Sweet music in my ears<br>
  48. And a night full of no fears<br>
  49. <br>
  50. But if I had one wishful field tonight<br>
  51. I'd ask for the sun to never rise<br>
  52. If God passed a mic to me to speak<br>
  53. I'd say stay in bed, world<br>
  54. Sleep in peace</html>"
  55. panel = JPanel.new
  56. panel.setLayout BorderLayout.new 10, 10
  57. label = JLabel.new lyrics
  58. label.setFont Font.new "Georgia", Font::PLAIN, 14
  59. label.setForeground Color.new 50, 50, 25
  60. panel.add label, BorderLayout::CENTER
  61. panel.setBorder BorderFactory.createEmptyBorder 10, 10, 10, 10
  62. self.add panel
  63. self.pack
  64. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  65. self.setLocationRelativeTo nil
  66. self.setVisible true
  67. end
  68. end
  69. Example.new

我们的示例在窗口中显示了歌曲的歌词。 我们可以在JLabel组件中使用 HTML 标签。 我们使用<br>标签来分隔行。

  1. lyrics = "<html>It's way too late to think of<br>
  2. Someone I would call now<br>
  3. And neon signs got tired<br>
  4. ...

我们定义了多行文字。

  1. label = JLabel.new lyrics
  2. label.setFont Font.new "Georgia", Font::PLAIN, 14

在这里,我们创建标签组件。 我们将其字体设置为 14 像素高的纯乔治亚州。

  1. panel.add label, BorderLayout::CENTER
  2. panel.setBorder BorderFactory.createEmptyBorder 10, 10, 10, 10

我们将标签放在面板的中央。 我们在标签周围放置了 10px。

JRuby Swing 中的组件 - 图2

图:JLabel组件

JSlider

JSlider是一个组件,使用户可以通过在有限的间隔内滑动旋钮来以图形方式选择一个值。 我们的示例将显示音量控制。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program we use a JSlider
  5. # component to control volume images.
  6. #
  7. # author: Jan Bodnar
  8. # website: www.zetcode.com
  9. # last modified: December 2010
  10. include Java
  11. import java.awt.Dimension
  12. import java.awt.BorderLayout
  13. import javax.swing.event.ChangeListener
  14. import javax.swing.JFrame
  15. import javax.swing.JSlider
  16. import javax.swing.JLabel
  17. import javax.swing.JPanel
  18. import javax.swing.BorderFactory
  19. import javax.swing.Box
  20. import javax.swing.BoxLayout
  21. import javax.swing.ImageIcon
  22. class ChangeEvent
  23. include ChangeListener
  24. def setLabel label
  25. @label = label
  26. end
  27. def setIcons mute, min, med, max
  28. @mute = mute
  29. @min = min
  30. @med = med
  31. @max = max
  32. end
  33. def stateChanged e
  34. sender = e.getSource
  35. value = sender.getValue
  36. if value == 0
  37. @label.setIcon(@mute)
  38. elsif value > 0 and value <= 30
  39. @label.setIcon(@min)
  40. elsif value > 30 and value < 80
  41. @label.setIcon(@med)
  42. else
  43. @label.setIcon(@max)
  44. end
  45. end
  46. end
  47. class Example < JFrame
  48. def initialize
  49. super "JSlider"
  50. self.initUI
  51. end
  52. def initUI
  53. mute = ImageIcon.new "mute.png"
  54. min = ImageIcon.new "min.png"
  55. med = ImageIcon.new "med.png"
  56. max = ImageIcon.new "max.png"
  57. panel = JPanel.new
  58. panel.setLayout BoxLayout.new panel, BoxLayout::X_AXIS
  59. panel.setBorder BorderFactory.createEmptyBorder 40, 40, 40, 40
  60. self.setLayout BorderLayout.new
  61. panel.add Box.createHorizontalGlue
  62. label = JLabel.new mute, JLabel::CENTER
  63. slider = JSlider.new 0, 150, 0
  64. ce = ChangeEvent.new
  65. ce.setLabel label
  66. ce.setIcons mute, min, med, max
  67. slider.add_change_listener ce
  68. slider.setPreferredSize Dimension.new 150, 30
  69. panel.add slider
  70. panel.add label
  71. panel.add Box.createRigidArea Dimension.new 5, 0
  72. panel.add Box.createHorizontalGlue
  73. self.add panel, BorderLayout::CENTER
  74. self.pack
  75. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  76. self.setSize 300, 200
  77. self.setLocationRelativeTo nil
  78. self.setVisible true
  79. end
  80. end
  81. Example.new

在代码示例中,我们显示了JSliderJLabel。 通过拖动滑块,我们可以更改标签组件上的图标。 我们有四个代表声音各种状态的图像。

  1. mute = ImageIcon.new "mute.png"

在这里,我们创建一个图像图标。

  1. panel.setLayout BoxLayout.new panel, BoxLayout::X_AXIS

面板组件具有水平BoxLayout

  1. panel.setBorder BorderFactory.createEmptyBorder 40, 40, 40, 40

我们在面板周围创建 40px 的边框。

  1. panel.add Box.createHorizontalGlue

我们在左右两侧都放置了可调整大小的空间。 这是为了防止JSlider增长到不自然的大小。

  1. label = JLabel.new mute, JLabel::CENTER

该行创建一个具有指定图像和水平对齐方式的JLabel实例。 默认情况下,标签在其显示区域中垂直居中。

  1. slider = JSlider.new 0, 150, 0

这是一个JSlider构造器。 参数为最小值,最大值和当前值。

  1. ce = ChangeEvent.new
  2. ce.setLabel label
  3. ce.setIcons mute, min, med, max

创建一个ChangeEvent对象。 我们为此对象设置了标签和图标。

  1. slider.add_change_listener ce

每次我们移动滑块时,都会调用ChangeEvent对象的stateChanged方法。

  1. panel.add Box.createRigidArea Dimension.new 5, 0

我们在两个组件之间放置一个 5px 的刚性空间。 当滑块位于末端位置时,它们彼此之间过于靠近。

  1. class ChangeEvent
  2. include ChangeListener

这是一个ChangeEvent类,它实现了ChangeListener。 因此,此类必须实现changeEvent方法。

  1. sender = e.getSource
  2. value = sender.getValue

changeEvent方法内部,我们获取事件源。 它是产生事件的滑块。 从发送者,我们获得当前值。

  1. if value == 0
  2. @label.setIcon(@mute)

如果该值等于零,我们将更新标签以具有mute.png图像。

JRuby Swing 中的组件 - 图3

图:JSlider

JToggleButton

JToggleButton是具有两种状态的按钮。 已按下但未按下。 通过单击可以在这两种状态之间切换。 在某些情况下此功能非常合适。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # This program uses toggle buttons to
  5. # change the background color of
  6. # a panel.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: December 2010
  11. include Java
  12. import java.awt.Color
  13. import java.awt.Dimension
  14. import java.awt.event.ActionListener
  15. import javax.swing.JToggleButton
  16. import javax.swing.Box
  17. import javax.swing.BoxLayout
  18. import javax.swing.BorderFactory
  19. import javax.swing.JFrame
  20. import javax.swing.JPanel
  21. import javax.swing.border.LineBorder
  22. class Example < JFrame
  23. include ActionListener
  24. def initialize
  25. super "JToggleButton"
  26. self.initUI
  27. end
  28. def initUI
  29. self.setPreferredSize Dimension.new 280, 200
  30. bottom = JPanel.new
  31. bottom.setLayout BoxLayout.new bottom, BoxLayout::X_AXIS
  32. bottom.setBorder BorderFactory.createEmptyBorder 20, 20, 20, 20
  33. leftPanel = JPanel.new
  34. leftPanel.setLayout BoxLayout.new leftPanel, BoxLayout::Y_AXIS
  35. @display = JPanel.new
  36. @display.setPreferredSize Dimension.new 110, 110
  37. @display.setBorder LineBorder.createGrayLineBorder
  38. @display.setBackground Color.black
  39. bottom.add @display
  40. redButton = JToggleButton.new "red"
  41. redButton.addActionListener self
  42. greenButton = JToggleButton.new "green"
  43. greenButton.addActionListener self
  44. blueButton = JToggleButton.new "blue"
  45. blueButton.addActionListener self
  46. blueButton.setMaximumSize greenButton.getMaximumSize
  47. redButton.setMaximumSize greenButton.getMaximumSize
  48. leftPanel.add redButton
  49. leftPanel.add Box.createRigidArea Dimension.new 25, 7
  50. leftPanel.add greenButton
  51. leftPanel.add Box.createRigidArea Dimension.new 25, 7
  52. leftPanel.add blueButton
  53. bottom.add leftPanel
  54. bottom.add Box.createRigidArea Dimension.new 20, 0
  55. self.add bottom
  56. self.pack
  57. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  58. self.setSize 300, 200
  59. self.setLocationRelativeTo nil
  60. self.setVisible true
  61. end
  62. def actionPerformed e
  63. color = @display.getBackground
  64. red = color.getRed
  65. green = color.getGreen
  66. blue = color.getBlue
  67. if e.getActionCommand == "red"
  68. if red == 0
  69. red = 255
  70. else
  71. red = 0
  72. end
  73. end
  74. if e.getActionCommand == "green"
  75. if green == 0
  76. green = 255
  77. else
  78. green = 0
  79. end
  80. end
  81. if e.getActionCommand == "blue"
  82. if blue == 0
  83. blue = 255
  84. else
  85. blue = 0
  86. end
  87. end
  88. setCol = Color.new red, green, blue
  89. @display.setBackground setCol
  90. end
  91. end
  92. Example.new

在代码示例中,我们使用三个切换按钮来更改矩形组件的颜色。

  1. class Example < JFrame
  2. include ActionListener

该类实现ActionListener。 我们将在Example类的actionPerformed方法中执行一些操作。

  1. redButton = JToggleButton.new "red"
  2. redButton.addActionListener self

我们创建一个JToggleButton组件。 我们向按钮添加一个动作监听器。 动作监听器是Example类。 当我们单击redButton时,将调用Example类的actionPerformed方法。

  1. blueButton.setMaximumSize greenButton.getMaximumSize
  2. redButton.setMaximumSize greenButton.getMaximumSize

我们使三个按钮的大小相等。

  1. color = @display.getBackground
  2. red = color.getRed
  3. green = color.getGreen
  4. blue = color.getBlue

我们确定显示背景颜色的当前红色,绿色,蓝色部分。

  1. if e.getActionCommand == "red"
  2. if red == 0
  3. red = 255
  4. else
  5. red = 0
  6. end
  7. end

我们确定切换了哪个按钮,并相应地更新 RGB 值的颜色部分。

  1. setCol = Color.new red, green, blue
  2. @display.setBackground setCol

在此创建新的颜色,并将显示面板更新为新的颜色。

JRuby Swing 中的组件 - 图4

图:JToggleButton

JList

JList是显示对象列表的组件。 它允许用户选择一项或多项。

  1. #!/usr/local/bin/jruby
  2. # ZetCode JRuby Swing tutorial
  3. #
  4. # In this program, we show all
  5. # available fonts of a system in
  6. # a JList component.
  7. #
  8. # author: Jan Bodnar
  9. # website: www.zetcode.com
  10. # last modified: December 2010
  11. include Java
  12. import java.awt.BorderLayout
  13. import java.awt.Dimension
  14. import java.awt.Font
  15. import java.awt.GraphicsEnvironment
  16. import javax.swing.JFrame
  17. import javax.swing.BorderFactory
  18. import javax.swing.JScrollPane
  19. import javax.swing.JPanel
  20. import javax.swing.JLabel
  21. import javax.swing.JList
  22. class Example < JFrame
  23. def initialize
  24. super "JList"
  25. initUI
  26. end
  27. def initUI
  28. panel = JPanel.new
  29. panel.setLayout BorderLayout.new
  30. panel.setBorder BorderFactory.createEmptyBorder 20, 20, 20, 20
  31. ge = GraphicsEnvironment.getLocalGraphicsEnvironment
  32. fonts = ge.getAvailableFontFamilyNames
  33. list = JList.new fonts
  34. list.add_list_selection_listener do |e|
  35. sender = e.source
  36. if not e.getValueIsAdjusting
  37. name = sender.getSelectedValue
  38. font = Font.new name, Font::PLAIN, 13
  39. @label.setFont font
  40. end
  41. end
  42. pane = JScrollPane.new
  43. pane.getViewport.add list
  44. pane.setPreferredSize Dimension.new 250, 200
  45. panel.add pane
  46. @label = JLabel.new "Aguirre, der Zorn Gottes"
  47. @label.setFont Font.new "Serif", Font::PLAIN, 12
  48. self.add @label, BorderLayout::SOUTH
  49. self.add panel
  50. self.pack
  51. self.setDefaultCloseOperation JFrame::EXIT_ON_CLOSE
  52. self.setLocationRelativeTo nil
  53. self.setVisible true
  54. end
  55. end
  56. Example.new

在我们的示例中,我们将显示JListJLabel组件。 列表组件包含我们系统上所有可用字体系列名称的列表。 如果我们从列表中选择一项,则标签将以我们选择的字体显示。

  1. ge = GraphicsEnvironment.getLocalGraphicsEnvironment
  2. fonts = ge.getAvailableFontFamilyNames

在这里,我们获得系统上所有可能的字体系列名称。

  1. list = JList.new fonts

我们创建JList组件的实例。 它将显示所有字体系列名称。

  1. if not e.getValueIsAdjusting

列表选择中的事件被分组。 我们收到选择和取消选择事件。 为了仅过滤选择事件,我们使用getValueIsAdjusting方法。

  1. name = sender.getSelectedValue
  2. font = Font.new name, Font::PLAIN, 13
  3. @label.setFont font

我们得到所选项目并为标签设置新字体。

  1. pane = JScrollPane.new
  2. pane.getViewport.add list

默认情况下,JList组件不可滚动。 我们将列表放入JScrollPane以使其可滚动。

JRuby Swing 中的组件 - 图5

图:JList组件

在 JRuby Swing 教程的这一部分中,我们介绍了几个 Swing 组件。