在 JRuby Swing 编程教程的这一部分中,我们将介绍基本的 Swing 组件。
组件是 GUI 应用的基本构建块。 多年来,一些组件已成为所有 OS 平台上所有工具包中的标准组件。 例如,按钮,复选框或滚动条。 Swing 具有丰富的组件集,可满足大多数编程需求。 可以将更多专用组件创建为自定义组件。
JCheckBox
JCheckBox是具有两种状态的组件:开和关。 开状态通过复选标记显示。 它用来表示一些布尔属性。 JCheckBox组件提供了一个带有文本标签的复选框。
#!/usr/local/bin/jruby# ZetCode JRuby Swing tutorial## This program uses JCheckBox# component to show/hide the title# of the window## author: Jan Bodnar# website: www.zetcode.com# last modified: December 2010include Javaimport java.awt.Dimensionimport javax.swing.JCheckBoximport javax.swing.Boximport javax.swing.BoxLayoutimport javax.swing.JFrameclass Example < JFramedef initializesuper "JCheckBox example"self.initUIenddef initUIself.setLayout BoxLayout.new getContentPane, BoxLayout::Y_AXISself.add Box.createRigidArea Dimension.new 15, 20cb = JCheckBox.new "Show Title", truecb.setBounds 50, 60, 80, 30cb.setFocusable(false)cb.add_action_listener do |e|if self.getTitle.empty?self.setTitle "JCheckBox example"elseself.setTitle ""endendadd cbself.setDefaultCloseOperation JFrame::EXIT_ON_CLOSEself.setSize 300, 200self.setLocationRelativeTo nilself.setVisible trueendendExample.new
在我们的示例中,我们在窗口上放置了一个复选框。 复选框显示或隐藏窗口的标题。
self.setLayout BoxLayout.new getContentPane, BoxLayout::Y_AXISself.add Box.createRigidArea Dimension.new 15, 20
在此示例中,我们使用BoxLayout布局管理器。 我们在此处放置一些空间,以使复选框不太靠近角落。
cb = JCheckBox.new "Show Title", true
JCheckBox组件已创建。 构造器的第一个参数是其文本标签。 第二个参数是一个布尔值,指示初始选择状态。 如果为true,则选中该复选框。
cb.setFocusable false
我们禁用复选框的焦点。 可以使用空格键选择或取消选择具有焦点的JCheckBox。
cb.add_action_listener do |e|if self.getTitle.empty?self.setTitle "JCheckBox example"elseself.setTitle ""endend
在动作监听器内部,我们检查标题是否已设置。 如果有标题,我们将其删除。 如果没有标题,我们设置一个。 这样,我们可以切换标题的可见性。

图:JCheckBox
JLabel
JLabel组件用于显示文本,图像或两者。 没有用户交互。
#!/usr/local/bin/jruby# ZetCode JRuby Swing tutorial## In this program, we show lyrics of a# song in a window.## author: Jan Bodnar# website: www.zetcode.com# last modified: December 2010include Javaimport java.awt.BorderLayoutimport java.awt.Colorimport java.awt.Fontimport javax.swing.JFrameimport javax.swing.BorderFactoryimport javax.swing.JPanelimport javax.swing.JLabelclass Example < JFramedef initializesuper "Lyrics"self.initUIenddef initUIlyrics = "<html>It's way too late to think of<br>Someone I would call now<br>And neon signs got tired<br>Red eye flights help the stars out<br>I'm safe in a corner<br>Just hours before me<br><br>I'm waking with the roaches<br>The world has surrendered<br>I'm dating ancient ghosts<br>The ones I made friends with<br>The comfort of fireflies<br>Long gone before daylight<br><br>And if I had one wishful field tonight<br>I'd ask for the sun to never rise<br>If God leant his voice for me to speak<br>I'd say go to bed, world<br><br>I've always been too late<br>To see what's before me<br>And I know nothing sweeter than<br>Champaign from last New Years<br>Sweet music in my ears<br>And a night full of no fears<br><br>But if I had one wishful field tonight<br>I'd ask for the sun to never rise<br>If God passed a mic to me to speak<br>I'd say stay in bed, world<br>Sleep in peace</html>"panel = JPanel.newpanel.setLayout BorderLayout.new 10, 10label = JLabel.new lyricslabel.setFont Font.new "Georgia", Font::PLAIN, 14label.setForeground Color.new 50, 50, 25panel.add label, BorderLayout::CENTERpanel.setBorder BorderFactory.createEmptyBorder 10, 10, 10, 10self.add panelself.packself.setDefaultCloseOperation JFrame::EXIT_ON_CLOSEself.setLocationRelativeTo nilself.setVisible trueendendExample.new
我们的示例在窗口中显示了歌曲的歌词。 我们可以在JLabel组件中使用 HTML 标签。 我们使用<br>标签来分隔行。
lyrics = "<html>It's way too late to think of<br>Someone I would call now<br>And neon signs got tired<br>...
我们定义了多行文字。
label = JLabel.new lyricslabel.setFont Font.new "Georgia", Font::PLAIN, 14
在这里,我们创建标签组件。 我们将其字体设置为 14 像素高的纯乔治亚州。
panel.add label, BorderLayout::CENTERpanel.setBorder BorderFactory.createEmptyBorder 10, 10, 10, 10
我们将标签放在面板的中央。 我们在标签周围放置了 10px。

图:JLabel组件
JSlider
JSlider是一个组件,使用户可以通过在有限的间隔内滑动旋钮来以图形方式选择一个值。 我们的示例将显示音量控制。
#!/usr/local/bin/jruby# ZetCode JRuby Swing tutorial## In this program we use a JSlider# component to control volume images.## author: Jan Bodnar# website: www.zetcode.com# last modified: December 2010include Javaimport java.awt.Dimensionimport java.awt.BorderLayoutimport javax.swing.event.ChangeListenerimport javax.swing.JFrameimport javax.swing.JSliderimport javax.swing.JLabelimport javax.swing.JPanelimport javax.swing.BorderFactoryimport javax.swing.Boximport javax.swing.BoxLayoutimport javax.swing.ImageIconclass ChangeEventinclude ChangeListenerdef setLabel label@label = labelenddef setIcons mute, min, med, max@mute = mute@min = min@med = med@max = maxenddef stateChanged esender = e.getSourcevalue = sender.getValueif value == 0@label.setIcon(@mute)elsif value > 0 and value <= 30@label.setIcon(@min)elsif value > 30 and value < 80@label.setIcon(@med)else@label.setIcon(@max)endendendclass Example < JFramedef initializesuper "JSlider"self.initUIenddef initUImute = ImageIcon.new "mute.png"min = ImageIcon.new "min.png"med = ImageIcon.new "med.png"max = ImageIcon.new "max.png"panel = JPanel.newpanel.setLayout BoxLayout.new panel, BoxLayout::X_AXISpanel.setBorder BorderFactory.createEmptyBorder 40, 40, 40, 40self.setLayout BorderLayout.newpanel.add Box.createHorizontalGluelabel = JLabel.new mute, JLabel::CENTERslider = JSlider.new 0, 150, 0ce = ChangeEvent.newce.setLabel labelce.setIcons mute, min, med, maxslider.add_change_listener ceslider.setPreferredSize Dimension.new 150, 30panel.add sliderpanel.add labelpanel.add Box.createRigidArea Dimension.new 5, 0panel.add Box.createHorizontalGlueself.add panel, BorderLayout::CENTERself.packself.setDefaultCloseOperation JFrame::EXIT_ON_CLOSEself.setSize 300, 200self.setLocationRelativeTo nilself.setVisible trueendendExample.new
在代码示例中,我们显示了JSlider和JLabel。 通过拖动滑块,我们可以更改标签组件上的图标。 我们有四个代表声音各种状态的图像。
mute = ImageIcon.new "mute.png"
在这里,我们创建一个图像图标。
panel.setLayout BoxLayout.new panel, BoxLayout::X_AXIS
面板组件具有水平BoxLayout。
panel.setBorder BorderFactory.createEmptyBorder 40, 40, 40, 40
我们在面板周围创建 40px 的边框。
panel.add Box.createHorizontalGlue
我们在左右两侧都放置了可调整大小的空间。 这是为了防止JSlider增长到不自然的大小。
label = JLabel.new mute, JLabel::CENTER
该行创建一个具有指定图像和水平对齐方式的JLabel实例。 默认情况下,标签在其显示区域中垂直居中。
slider = JSlider.new 0, 150, 0
这是一个JSlider构造器。 参数为最小值,最大值和当前值。
ce = ChangeEvent.newce.setLabel labelce.setIcons mute, min, med, max
创建一个ChangeEvent对象。 我们为此对象设置了标签和图标。
slider.add_change_listener ce
每次我们移动滑块时,都会调用ChangeEvent对象的stateChanged方法。
panel.add Box.createRigidArea Dimension.new 5, 0
我们在两个组件之间放置一个 5px 的刚性空间。 当滑块位于末端位置时,它们彼此之间过于靠近。
class ChangeEventinclude ChangeListener
这是一个ChangeEvent类,它实现了ChangeListener。 因此,此类必须实现changeEvent方法。
sender = e.getSourcevalue = sender.getValue
在changeEvent方法内部,我们获取事件源。 它是产生事件的滑块。 从发送者,我们获得当前值。
if value == 0@label.setIcon(@mute)
如果该值等于零,我们将更新标签以具有mute.png图像。

图:JSlider
JToggleButton
JToggleButton是具有两种状态的按钮。 已按下但未按下。 通过单击可以在这两种状态之间切换。 在某些情况下此功能非常合适。
#!/usr/local/bin/jruby# ZetCode JRuby Swing tutorial## This program uses toggle buttons to# change the background color of# a panel.## author: Jan Bodnar# website: www.zetcode.com# last modified: December 2010include Javaimport java.awt.Colorimport java.awt.Dimensionimport java.awt.event.ActionListenerimport javax.swing.JToggleButtonimport javax.swing.Boximport javax.swing.BoxLayoutimport javax.swing.BorderFactoryimport javax.swing.JFrameimport javax.swing.JPanelimport javax.swing.border.LineBorderclass Example < JFrameinclude ActionListenerdef initializesuper "JToggleButton"self.initUIenddef initUIself.setPreferredSize Dimension.new 280, 200bottom = JPanel.newbottom.setLayout BoxLayout.new bottom, BoxLayout::X_AXISbottom.setBorder BorderFactory.createEmptyBorder 20, 20, 20, 20leftPanel = JPanel.newleftPanel.setLayout BoxLayout.new leftPanel, BoxLayout::Y_AXIS@display = JPanel.new@display.setPreferredSize Dimension.new 110, 110@display.setBorder LineBorder.createGrayLineBorder@display.setBackground Color.blackbottom.add @displayredButton = JToggleButton.new "red"redButton.addActionListener selfgreenButton = JToggleButton.new "green"greenButton.addActionListener selfblueButton = JToggleButton.new "blue"blueButton.addActionListener selfblueButton.setMaximumSize greenButton.getMaximumSizeredButton.setMaximumSize greenButton.getMaximumSizeleftPanel.add redButtonleftPanel.add Box.createRigidArea Dimension.new 25, 7leftPanel.add greenButtonleftPanel.add Box.createRigidArea Dimension.new 25, 7leftPanel.add blueButtonbottom.add leftPanelbottom.add Box.createRigidArea Dimension.new 20, 0self.add bottomself.packself.setDefaultCloseOperation JFrame::EXIT_ON_CLOSEself.setSize 300, 200self.setLocationRelativeTo nilself.setVisible trueenddef actionPerformed ecolor = @display.getBackgroundred = color.getRedgreen = color.getGreenblue = color.getBlueif e.getActionCommand == "red"if red == 0red = 255elsered = 0endendif e.getActionCommand == "green"if green == 0green = 255elsegreen = 0endendif e.getActionCommand == "blue"if blue == 0blue = 255elseblue = 0endendsetCol = Color.new red, green, blue@display.setBackground setColendendExample.new
在代码示例中,我们使用三个切换按钮来更改矩形组件的颜色。
class Example < JFrameinclude ActionListener
该类实现ActionListener。 我们将在Example类的actionPerformed方法中执行一些操作。
redButton = JToggleButton.new "red"redButton.addActionListener self
我们创建一个JToggleButton组件。 我们向按钮添加一个动作监听器。 动作监听器是Example类。 当我们单击redButton时,将调用Example类的actionPerformed方法。
blueButton.setMaximumSize greenButton.getMaximumSizeredButton.setMaximumSize greenButton.getMaximumSize
我们使三个按钮的大小相等。
color = @display.getBackgroundred = color.getRedgreen = color.getGreenblue = color.getBlue
我们确定显示背景颜色的当前红色,绿色,蓝色部分。
if e.getActionCommand == "red"if red == 0red = 255elsered = 0endend
我们确定切换了哪个按钮,并相应地更新 RGB 值的颜色部分。
setCol = Color.new red, green, blue@display.setBackground setCol
在此创建新的颜色,并将显示面板更新为新的颜色。

图:JToggleButton
JList
JList是显示对象列表的组件。 它允许用户选择一项或多项。
#!/usr/local/bin/jruby# ZetCode JRuby Swing tutorial## In this program, we show all# available fonts of a system in# a JList component.## author: Jan Bodnar# website: www.zetcode.com# last modified: December 2010include Javaimport java.awt.BorderLayoutimport java.awt.Dimensionimport java.awt.Fontimport java.awt.GraphicsEnvironmentimport javax.swing.JFrameimport javax.swing.BorderFactoryimport javax.swing.JScrollPaneimport javax.swing.JPanelimport javax.swing.JLabelimport javax.swing.JListclass Example < JFramedef initializesuper "JList"initUIenddef initUIpanel = JPanel.newpanel.setLayout BorderLayout.newpanel.setBorder BorderFactory.createEmptyBorder 20, 20, 20, 20ge = GraphicsEnvironment.getLocalGraphicsEnvironmentfonts = ge.getAvailableFontFamilyNameslist = JList.new fontslist.add_list_selection_listener do |e|sender = e.sourceif not e.getValueIsAdjustingname = sender.getSelectedValuefont = Font.new name, Font::PLAIN, 13@label.setFont fontendendpane = JScrollPane.newpane.getViewport.add listpane.setPreferredSize Dimension.new 250, 200panel.add pane@label = JLabel.new "Aguirre, der Zorn Gottes"@label.setFont Font.new "Serif", Font::PLAIN, 12self.add @label, BorderLayout::SOUTHself.add panelself.packself.setDefaultCloseOperation JFrame::EXIT_ON_CLOSEself.setLocationRelativeTo nilself.setVisible trueendendExample.new
在我们的示例中,我们将显示JList和JLabel组件。 列表组件包含我们系统上所有可用字体系列名称的列表。 如果我们从列表中选择一项,则标签将以我们选择的字体显示。
ge = GraphicsEnvironment.getLocalGraphicsEnvironmentfonts = ge.getAvailableFontFamilyNames
在这里,我们获得系统上所有可能的字体系列名称。
list = JList.new fonts
我们创建JList组件的实例。 它将显示所有字体系列名称。
if not e.getValueIsAdjusting
列表选择中的事件被分组。 我们收到选择和取消选择事件。 为了仅过滤选择事件,我们使用getValueIsAdjusting方法。
name = sender.getSelectedValuefont = Font.new name, Font::PLAIN, 13@label.setFont font
我们得到所选项目并为标签设置新字体。
pane = JScrollPane.newpane.getViewport.add list
默认情况下,JList组件不可滚动。 我们将列表放入JScrollPane以使其可滚动。

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