You are on page 1of 59

ZetCode JRuby Swing tutorial

This is JRuby Swing tutorial. In this tutorial, you will learn the basics of GUI programming in JRuby & Swing. The tutorial is suitable for beginners and intermediate programmers.

Swing
Swing library is an official Ja a GUI tool!it for the Ja a programming language. It is used to create Graphical user interfaces with Ja a. Swing is an ad anced GUI tool!it. It has a rich set of components. "rom basic ones li!e buttons, labels, scrollbars to ad anced components li!e trees and tables. Swing itself is written in Ja a. Swing is a ailable for other languages too. "or e#ample JRuby, Jython, Groo y or Scala.

Introduction to JRuby Swing


In this part of the JRuby Swing tutorial, we will introduce the Swing tool!it and create our first programs using the JRuby programming language. The purpose of this tutorial is to get you started with the Swing tool!it with the JRuby language. Images used in this tutorial can be downloaded here. I used some icons from the Tango icons pac! of the Gnome pro$ect.

About
Swing library is an official Ja a GUI tool!it for the Ja a programming language. It is used to create Graphical user interfaces with Ja a. Swing is an ad anced GUI tool!it. It has a rich set of components. "rom basic ones li!e buttons, labels, scrollbars to ad anced components li!e trees and tables. Swing itself is written in Ja a. Swing is a ailable for other languages too. "or e#ample JRuby, Jython, Groo y or Scala. JRuby is a Ja a implementation of the Ruby programming language. JRuby can import any Ja a class. There are two basic ways to e#ecute the e#amples in this tutorial. %ne way is to install a Ruby &et'eans plugin. It contains JRuby as well. (hen you create a new Ruby pro$ect, be sure to select the JRuby platform. The other way is to download a release from the $ruby.org website.
$ tar -xzvf jruby-bin-1.5.6.tar.gz $ mv jruby-1.5.6/ ~/bin

Installing JRuby is ery easy. (e e#tract the contents of the compressed archi e and mo e the directory to a selected location. %n my system, I ha e mo ed the directory to the bin directory of my home directory.
$ ~/bin/jdk1.6.0_21/bin/java -jar ~/bin/jruby-1.5.6/lib/jruby.jar sim l!.rb

(e ha e installed JRuby in a selected directory. In the lib subdirectory, we will find $ruby.$ar file, which is used to e#ecute JRuby scripts.
$ "at /usr/l#"al/bin/jruby $%/bin/bas& ~/bin/jdk1.6.0_21/bin/java -jar ~/bin/jruby-1.5.6/lib/jruby.jar $1

%ptionally, we can create a bash file which will automatically start our JRuby scripts. (e can then put the *+,usr,local,bin,$ruby path to our scripts.

Simple example
In our first e#ample, we will show a basic window on the screen.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is !xam l! s&#,s a sim l! ,ind#, in t&! "!nt!r #f t&! s"r!!n. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im #rt javax.s,ing.)1ram! "lass 2xam l! 3 )1ram! d!f initializ! su !r 4+im l!4 s!lf.init56 !nd d!f init56 s!lf.s!t+iz! 7008 200 s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

(hile this code is ery small, the application window can do -uite a lot. It can be resi.ed, ma#imi.ed, minimi.ed. /ll the comple#ity that comes with it has been hidden from the application programmer.
in"lud! )ava

(e include Ja a /0I to JRuby. 1

im #rt javax.s,ing.)1ram!

(e import a )1ram! class. The )1ram! is a top2le el window with a titlebar and a border.
s!lf.init56

(e delegate the creation of the user interface to the init56 method.


s!lf.s!t+iz! 7008 200

(e set the si.e of the window.


s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2

This method ensures that the window terminates, if we clic! on the close button of the titlebar. 'y default nothing happens.
s!lf.s!t<#"ati#n*!lativ!-# nil

(e center the window on the screen.


s!lf.s!t=isibl! tru!

"inally, the window is showed on the screen.

Tooltip
/ tooltip is a small rectangular window, which gi es a brief information about an ob$ect. It is usually a GUI component. It is part of the help system of the application.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is "#d! s&#,s a t##lti a ,ind#, and a butt#n #n

aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im #rt javax.s,ing.)/utt#n im #rt javax.s,ing.)1ram! im #rt javax.s,ing.)>an!l "lass 2xam l! 3 )1ram! d!f initializ! su !r 4-##lti s4 s!lf.init56 !nd

d!f init56 an!l ? )>an!l.n!, s!lf.g!t(#nt!nt>an!.add an!l

an!l.s!t<ay#ut nil an!l.s!t-##l-i -!xt 4@ >an!l "#ntain!r4 butt#n ? )/utt#n.n!, 4/utt#n4 butt#n.s!t/#unds 1008 608 1008 70 butt#n.s!t-##l-i -!xt 4@ butt#n "#m #n!nt4 an!l.add butt#n s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In the e#ample, we set the tooltip for the frame and the button.
an!l ? )>an!l.n!, s!lf.g!t(#nt!nt>an!.add an!l

(e create a )>an!l component. It is a generic lightweight container. )1ram! has an area, where you put the components called the content pane. (e put the panel into this pane.
an!l.s!t<ay#ut nil

'y default, the )>an!l has a 1l#,<ay#ut manager. The layout manager is used to place widgets onto the containers. If we call s!t<ay#ut nil we can position our components absolutely. "or this, we use the s!t/#unds method.
an!l.s!t-##l-i -!xt 4@ >an!l "#ntain!r4

To enable a tooltip, we call the s!t-##lti -!xt method.

"igure4 Tooltip 5

Quit button
In the last e#ample of this section, we will create a -uit button. (hen we press this button, the application terminates.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram "r!at!s a Auit butt#n. B&!n ,! r!ss t&! butt#n8 t&! a li"ati#n t!rminat!s. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im #rt #rt #rt #rt javax.s,ing.)/utt#n javax.s,ing.)1ram! javax.s,ing.)>an!l java.lang.+yst!m

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4Cuit butt#n4 s!lf.init56 !nd d!f init56 an!l ? )>an!l.n!, s!lf.g!t(#nt!nt>an!.add an!l.s!t<ay#ut nil Abutt#n ? )/utt#n.n!, 4Cuit4 Abutt#n.s!t/#unds 508 608 D08 70 Abutt#n.add_a"ti#n_list!n!r d# E!E +yst!m.!xit 0 !nd an!l.add Abutt#n s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! an!l

!nd !nd

2xam l!.n!,

(e position a )/utt#n on the window. (e will add an action listener to this button.

Abutt#n ? )/utt#n.n!, 4Cuit4 Abutt#n.s!t/#unds 508 608 D08 70

7ere we create a button. (e position it by calling the s!t/#unds method.


Abutt#n.add_a"ti#n_list!n!r d# E!E +yst!m.!xit 0 !nd

(e add an action listener to the button. The listener terminates the application.

"igure4 8uit button This section was an introduction to the Swing tool!it with the JRuby language.

Layout management
In this part of the JRuby Swing programming tutorial, we will introduce layout managers. (hen we design the GUI of our application, we decide what components we will use and how we will organi.e those components in the application. To organi.e our components, we use speciali.ed non isible ob$ects called layout managers. The Swing tool!it has two !ind of components. 9ontainers and children. The containers group children into suitable layouts. To create layouts, we use layout managers.

Absolute positioning
In most cases, programmers should use layout managers. There are a few situations, where we can use absolute positioning. In absolute positioning, the programmer specifies the position and the si.e of each component in pi#els. The si.e and the position of a component do not change, if you resi.e a window. /pplications loo! different on arious platforms, and what loo!s %: on ;inu#, might not loo! %: on <ac. 9hanging fonts in your application might spoil the layout. If you translate your application into another language, you must redo your layout. "or all these issues, use the absolute positioning only when you ha e a reason to do so.
$%/usr/l#"al/bin/jruby $ '!t(#d! )*uby +,ing tut#rial

$ $ $ $ $ $ $

6n t&is r#gram8 ,! lay #ut t&r!! imag!s using abs#lut! #siti#ning. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im #rt #rt #rt #rt #rt java.a,t.(#l#r javax.s,ing.6mag!6"#n javax.s,ing.)<ab!l javax.s,ing.)>an!l javax.s,ing.)1ram!

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4@bs#lut!4 !nd s!lf.init56

d!f init56 an!l ? )>an!l.n!, an!l.s!t<ay#ut nil an!l.s!t/a"kgr#und (#l#r.n!, 668 668 66 s!lf.g!t(#nt!nt>an!.add an!l r#t ? 6mag!6"#n.n!, 4r#tunda.j g4 r#t<ab!l ? )<ab!l.n!, r#t r#t<ab!l.s!t/#unds 208 208 r#t.g!t6"#nBidt&8 r#t.g!t6"#nF!ig&t min ? 6mag!6"#n.n!, 4min"#l.j g4 min<ab!l ? )<ab!l.n!, min min<ab!l.s!t/#unds G08 1608 min.g!t6"#nBidt&8 min.g!t6"#nF!ig&t bar ? 6mag!6"#n.n!, 4bard!j#v.j g4 bar<ab!l ? )<ab!l.n!, bar bar<ab!l.s!t/#unds 1H08 508 bar.g!t6"#nBidt&8 bar.g!t6"#nF!ig&t an!l.add r#t<ab!l an!l.add min<ab!l an!l.add bar<ab!l s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7508 700 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd 2xam l!.n!,

In this e#ample, we show three images using absolute positioning.

>

an!l.s!t<ay#ut nil

9ontainers in Swing already ha e a default layout manager. )>an!l has a 1l#,<ay#ut manager as its default layout manager. (e use the s!t<ay#ut method with a nil parameter to remo e the default layout manager and use absolute positioning instead.
r#t ? 6mag!6"#n.n!, 4r#tunda.j g4 r#t<ab!l ? )<ab!l.n!, r#t r#t<ab!l.s!t/#unds 208 208 r#t.g!t6"#nBidt&8 r#t.g!t6"#nF!ig&t

(e create an 6mag!6"#n ob$ect. (e put the icon into the )<ab!l component to display it. Then we use the s!t/#unds method to position the label on the panel. The first two parameters are the #, y positions of the label. The 3th and 5th parameters are the width and the height of the icon.
an!l.add r#t<ab!l

(e add the label to the panel container.

"igure4 /bsolute positioning

Buttons example
In the following e#ample, we will position two buttons in the bottom right corner of the window.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 ,! us! t&! /#x<ay#ut manag!r t# #siti#n t,# butt#ns in t&! b#tt#m rig&t "#rn!r #f t&! ,ind#,. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m

$ last m#difi!d. 0!"!mb!r 2010 in"lud! )ava im im im im im im #rt #rt #rt #rt #rt #rt java.a,t.0im!nsi#n javax.s,ing.)/utt#n javax.s,ing.)>an!l javax.s,ing.)1ram! javax.s,ing./#x<ay#ut javax.s,ing./#x

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4/utt#ns4 s!lf.init56 !nd d!f init56 basi" ? )>an!l.n!, basi".s!t<ay#ut /#x<ay#ut.n!, basi"8 /#x<ay#ut..I_@:6+ s!lf.add basi" basi".add /#x."r!at!=!rti"alJlu! b#tt#m ? )>an!l.n!, b#tt#m.s!t<ay#ut /#x<ay#ut.n!, b#tt#m8 /#x<ay#ut..:_@:6+ b#tt#m.s!t@lignm!nt: 1.0 #k/utt#n ? )/utt#n.n!, 49K4 "l#s!/utt#n ? )/utt#n.n!, 4(l#s!4 b#tt#m.add b#tt#m.add b#tt#m.add b#tt#m.add #k/utt#n /#x."r!at!*igid@r!a 0im!nsi#n.n!, 58 0 "l#s!/utt#n /#x."r!at!*igid@r!a 0im!nsi#n.n!, 158 0

basi".add b#tt#m basi".add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 08 15 s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd 2xam l!.n!,

(e will create two panels. The basic panel has a ertical bo# layout. The bottom panel has a hori.ontal one. (e will put a bottom panel into the basic panel. (e will right align the bottom panel. The space between the top of the window and the bottom panel is e#pandable. It is done by the ertical glue.
basi" ? )>an!l.n!,

basi".s!t<ay#ut /#x<ay#ut.n!, basi"8 /#x<ay#ut..I_@:6+ ... b#tt#m ? )>an!l.n!, b#tt#m.s!t<ay#ut /#x<ay#ut.n!, b#tt#m8 /#x<ay#ut..:_@:6+

The basic panel has a ertical bo# layout. The bottom panel has a hori.ontal bo# layout.
b#tt#m.s!t@lignm!nt: 1.0

The bottom panel is right aligned.


basi".add /#x."r!at!=!rti"alJlu!

(e create a ertical glue. The glue is ertically e#pandable white space, which will push the hori.ontal bo# with the buttons to the bottom.
#k/utt#n ? )/utt#n.n!, 49K4 "l#s!/utt#n ? )/utt#n.n!, 4(l#s!4

These are the two buttons, that will go into the bottom right corner of the window.
b#tt#m.add #k/utt#n b#tt#m.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 58 0

(e put the %: button into the hori.ontal bo#. (e put some rigid space ne#t to the button. So that there is some space between the two buttons.
basi".add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 08 15

(e put some space between the buttons and the border of the window.

"igure4 'uttons e#ample

Windows example
The following e#ample creates the windows dialog using the Jr#u <ay#ut manager. The dialog comes from the JAe eloper application. The Jr#u <ay#ut manager di ides the creation of the layout into two steps. In one step, we lay out components alongside the hori.ontal a#is. In the second step, we lay out components along the ertical a#is. This is an unusual idea within layout managers, but it wor!s well. There are two types of arrangements. Se-uential and parallel. In both !inds of layouts we can arrange components se-uentially or in parallel. In a hori.ontal layout, a row of components is )B

called a se-uential group. / column of components is called a parallel group. In a ertical layout, a column of components is called a se-uential group. /nd a row of components is called a parallel group. Cou must understand these definitions right in order to wor! with the Jr#u <ay#ut manager.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 Jr#u <ay#ut manag!r t# "r!at! a Bind#,s !xam l!. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt java.a,t.0im!nsi#n java.a,t.(#l#r javax.s,ing.)/utt#n javax.s,ing.+,ing(#nstants javax.s,ing.)1ram! javax.s,ing.)<ab!l javax.s,ing.)-!xt@r!a javax.s,ing./#rd!r1a"t#ry javax.s,ing.Jr#u <ay#ut

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4Bind#,s4 s!lf.init56 !nd d!f init56 lay#ut ? Jr#u <ay#ut.n!, s!lf.g!t(#nt!nt>an! s!lf.g!t(#nt!nt>an!.s!t<ay#ut lay#ut lay#ut.s!t@ut#(r!at!Ja s tru! lay#ut.s!t@ut#(r!at!(#ntain!rJa s tru! s!lf.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, 7508 700 ,ind#,s ? )<ab!l.n!, 4Bind#,s4 ar!a ? )-!xt@r!a.n!, ar!a.s!t2ditabl! fals! ar!a.s!t/#rd!r /#rd!r1a"t#ry."r!at!<in!/#rd!r (#l#r.gray a"tivat!/utt#n ? )/utt#n.n!, 4@"tivat!4 "l#s!/utt#n ? )/utt#n.n!, 4(l#s!4 &!l /utt#n ? )/utt#n.n!, 4F!l 4 #k/utt#n ? )/utt#n.n!, 49K4 sg ? lay#ut."r!at!+!Au!ntialJr#u g1 ? lay#ut."r!at!>arall!lJr#u

))

g2 ? lay#ut."r!at!>arall!lJr#u g1.add(#m #n!nt ,ind#,s g1.add(#m #n!nt ar!a g1.add(#m #n!nt &!l /utt#n sg.addJr#u g1 g2.add(#m #n!nt a"tivat!/utt#n g2.add(#m #n!nt "l#s!/utt#n g2.add(#m #n!nt #k/utt#n sg.addJr#u g2 lay#ut.s!tF#riz#ntalJr#u sg sg1 ? lay#ut."r!at!+!Au!ntialJr#u sg2 ? lay#ut."r!at!+!Au!ntialJr#u g1 ? lay#ut."r!at!>arall!lJr#u g2 ? lay#ut."r!at!>arall!lJr#u sg1.add(#m #n!nt ,ind#,s g1.add(#m #n!nt ar!a sg2.add(#m #n!nt a"tivat!/utt#n sg2.add(#m #n!nt "l#s!/utt#n g1.addJr#u sg2 sg1.addJr#u g1 g2.add(#m #n!nt &!l /utt#n g2.add(#m #n!nt #k/utt#n sg1.addJr#u g2 lay#ut.s!t=!rti"alJr#u sg1 lay#ut.link+iz! +,ing(#nstants..F9*6'9;-@<8 #k/utt#n8 &!l /utt#n8 "l#s!/utt#n8 a"tivat!/utt#n s!lf. a"k s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

(e use Jr#u <ay#ut manager to create a layout which consists of si# components. Groups of components are formed along both a#es.
sg ? lay#ut."r!at!+!Au!ntialJr#u g1 ? lay#ut."r!at!>arall!lJr#u g2 ? lay#ut."r!at!>arall!lJr#u g1.add(#m #n!nt ,ind#,s g1.add(#m #n!nt ar!a g1.add(#m #n!nt &!l /utt#n sg.addJr#u g1 g2.add(#m #n!nt a"tivat!/utt#n g2.add(#m #n!nt "l#s!/utt#n g2.add(#m #n!nt #k/utt#n sg.addJr#u g2 lay#ut.s!tF#riz#ntalJr#u sg

In the first step, we ha e a hori.ontal layout. It consists of two parallel groups of three components.

)1

sg1 ? lay#ut."r!at!+!Au!ntialJr#u sg2 ? lay#ut."r!at!+!Au!ntialJr#u g1 ? lay#ut."r!at!>arall!lJr#u g2 ? lay#ut."r!at!>arall!lJr#u sg1.add(#m #n!nt ,ind#,s g1.add(#m #n!nt ar!a sg2.add(#m #n!nt a"tivat!/utt#n sg2.add(#m #n!nt "l#s!/utt#n g1.addJr#u sg2 sg1.addJr#u g1 g2.add(#m #n!nt &!l /utt#n g2.add(#m #n!nt #k/utt#n sg1.addJr#u g2 lay#ut.s!t=!rti"alJr#u sg1

Dertical layout is a bit more comple#. "irst, we add a single component. Then we add a parallel group of a single component and a se-uential group of two components. "inally, we add a parallel group of two components.
lay#ut.link+iz! +,ing(#nstants..F9*6'9;-@<8 #k/utt#n8 &!l /utt#n8 "l#s!/utt#n8 a"tivat!/utt#n

This code ma!es all buttons the same si.e. (e only need to set their width, because their height is already the same by default.

"igure4 (indows e#ample ;oo! at the screenshot of the e#ample. &otice, that components can be grouped into ertical and hori.ontal sets of components. "or e#ample, the label, the area and the 7elp button components can form a ertical group of components. This is e#actly what the Jr#u <ay#ut manager does. It lays out components by forming ertical and hori.ontal groups of components. In this part of the JRuby Swing tutorial, we mentioned layout management of components.

)3

Components
In this part of the JRuby Swing programming tutorial, we will co er basic Swing components. 9omponents are basic building bloc!s of a GUI application. % er the years, se eral components became a standard in all tool!its on all %S platforms. "or e#ample a button, a chec! bo# or a scroll bar. Swing has a rich set of components which co ers most of the programming needs. <ore speciali.ed components can be created as custom components.

JCheckBox
The )(&!"k/#x is a component, that has two states. %n and %ff. The %n state is isuali.ed by a chec! mar!. It is used to denote some boolean property. The J9hec!'o# component pro ides a chec! bo# with a te#t label.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram us!s )(&!"k/#x "#m #n!nt t# s&#,/&id! t&! titl! #f t&! ,ind#, aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im #rt #rt #rt #rt #rt java.a,t.0im!nsi#n javax.s,ing.)(&!"k/#x javax.s,ing./#x javax.s,ing./#x<ay#ut javax.s,ing.)1ram!

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4)(&!"k/#x !xam l!4 !nd s!lf.init56

d!f init56 s!lf.s!t<ay#ut /#x<ay#ut.n!, g!t(#nt!nt>an!8 /#x<ay#ut..I_@:6+ s!lf.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 158 20 "b ? )(&!"k/#x.n!, 4+&#, -itl!48 tru! "b.s!t/#unds 508 608 D08 70 "b.s!t1#"usabl!Lfals!M "b.add_a"ti#n_list!n!r d# E!E

)5

!nd

if s!lf.g!t-itl!.!m tyN s!lf.s!t-itl! 4)(&!"k/#x !xam l!4 !ls! s!lf.s!t-itl! 44 !nd

add "b s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In our e#ample, we place a chec! bo# on the window. The chec! bo# shows,hides the title of the window.
s!lf.s!t<ay#ut /#x<ay#ut.n!, g!t(#nt!nt>an!8 /#x<ay#ut..I_@:6+ s!lf.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 158 20

In this e#ample, we use a /#x<ay#ut layout manager. (e put some space there, so that the chec! bo# is not too close to the corner.
"b ? )(&!"k/#x.n!, 4+&#, -itl!48 tru!

The )(&!"k/#x component is created. The first parameter of the constructor is its te#t label. The second parameter is a boolean alue indicating the initial selection state. If true the chec! bo# is selected.
"b.s!t1#"usabl! fals!

(e disable the focus for the chec! bo#. / )(&!"k/#x that has a focus may be selected or unselected with a spacebar.
"b.add_a"ti#n_list!n!r d# E!E if s!lf.g!t-itl!.!m tyN s!lf.s!t-itl! 4)(&!"k/#x !xam l!4 !ls! s!lf.s!t-itl! 44 !nd !nd

Inside the action listener, we chec! if the title is set. If there is a title, we remo e it. If there is no title, we set one. This way we toggle the isibility of a title.

)6

"igure4 J9hec!'o#

JLabel
The )<ab!l component is used to display te#t, image or both. &o user interaction is a ailable.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 ,! s&#, lyri"s #f a s#ng in a ,ind#,. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im #rt java.a,t./#rd!r<ay#ut im #rt java.a,t.(#l#r im #rt java.a,t.1#nt im im im im #rt #rt #rt #rt javax.s,ing.)1ram! javax.s,ing./#rd!r1a"t#ry javax.s,ing.)>an!l javax.s,ing.)<ab!l

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4<yri"s4 s!lf.init56 !nd d!f init56 lyri"s ? 43&tmlO6tPs ,ay t## lat! t# t&ink #f3brO +#m!#n! 6 ,#uld "all n#,3brO @nd n!#n signs g#t tir!d3brO *!d !y! flig&ts &!l t&! stars #ut3brO 6Pm saf! in a "#rn!r3brO

)=

)ust &#urs b!f#r! m!3brO 3brO 6Pm ,aking ,it& t&! r#a"&!s3brO -&! ,#rld &as surr!nd!r!d3brO 6Pm dating an"i!nt g&#sts3brO -&! #n!s 6 mad! fri!nds ,it&3brO -&! "#mf#rt #f fir!fli!s3brO <#ng g#n! b!f#r! daylig&t3brO 3brO @nd if 6 &ad #n! ,is&ful fi!ld t#nig&t3brO 6Pd ask f#r t&! sun t# n!v!r ris!3brO 6f J#d l!ant &is v#i"! f#r m! t# s !ak3brO 6Pd say g# t# b!d8 ,#rld3brO 3brO 6Pv! al,ays b!!n t## lat!3brO -# s!! ,&atPs b!f#r! m!3brO @nd 6 kn#, n#t&ing s,!!t!r t&an3brO (&am aign fr#m last ;!, I!ars3brO +,!!t musi" in my !ars3brO @nd a nig&t full #f n# f!ars3brO 3brO /ut if 6 &ad #n! ,is&ful fi!ld t#nig&t3brO 6Pd ask f#r t&! sun t# n!v!r ris!3brO 6f J#d ass!d a mi" t# m! t# s !ak3brO 6Pd say stay in b!d8 ,#rld3brO +l!! in !a"!3/&tmlO4 an!l ? )>an!l.n!, an!l.s!t<ay#ut /#rd!r<ay#ut.n!, 108 10 lab!l ? )<ab!l.n!, lyri"s lab!l.s!t1#nt 1#nt.n!, 4J!#rgia48 1#nt..><@6;8 1G lab!l.s!t1#r!gr#und (#l#r.n!, 508 508 25 an!l.add lab!l8 /#rd!r<ay#ut..(2;-2* an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 108 108 108 10 s!lf.add an!l s!lf. a"k s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

%ur e#ample shows lyrics of a song in the window. (e can use 7T<; tags in )<ab!l component. (e use the EbrF tag to separate lines.
lyri"s ? 43&tmlO6tPs ,ay t## lat! t# t&ink #f3brO +#m!#n! 6 ,#uld "all n#,3brO @nd n!#n signs g#t tir!d3brO ...

(e define a multi line te#t.


lab!l ? )<ab!l.n!, lyri"s lab!l.s!t1#nt 1#nt.n!, 4J!#rgia48 1#nt..><@6;8 1G

)>

7ere we create the label component. (e set its font to plain Georgia, )5p# tall.
an!l.add lab!l8 /#rd!r<ay#ut..(2;-2* an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 108 108 108 10

(e put the label into the center of the panel. (e put )Bp# around the label.

"igure4 J;abel component

JSlider
is a component that lets the user graphically select a alue by sliding a !nob within a bounded inter al. %ur e#ample will show a olume control.
)+lid!r $%/usr/l#"al/bin/jruby $ '!t(#d! )*uby +,ing tut#rial $ $ 6n t&is r#gram ,! us! a )+lid!r $ "#m #n!nt t# "#ntr#l v#lum! imag!s.

)?

$ $ aut&#r. )an /#dnar $ ,!bsit!. ,,,.z!t"#d!."#m $ last m#difi!d. 0!"!mb!r 2010 in"lud! )ava im #rt java.a,t.0im!nsi#n im #rt java.a,t./#rd!r<ay#ut im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt javax.s,ing.!v!nt.(&ang!<ist!n!r javax.s,ing.)1ram! javax.s,ing.)+lid!r javax.s,ing.)<ab!l javax.s,ing.)>an!l javax.s,ing./#rd!r1a"t#ry javax.s,ing./#x javax.s,ing./#x<ay#ut javax.s,ing.6mag!6"#n

"lass (&ang!2v!nt in"lud! (&ang!<ist!n!r d!f s!t<ab!l lab!l Qlab!l ? lab!l !nd d!f s!t6"#ns mut!8 min8 m!d8 max Qmut! ? mut! Qmin ? min Qm!d ? m!d Qmax ? max !nd d!f stat!(&ang!d ! s!nd!r ? !.g!t+#ur"! valu! ? s!nd!r.g!t=alu! if valu! ?? 0 Qlab!l.s!t6"#nLQmut!M !lsif valu! O 0 and valu! 3? 70 Qlab!l.s!t6"#nLQminM !lsif valu! O 70 and valu! 3 D0 Qlab!l.s!t6"#nLQm!dM !ls! Qlab!l.s!t6"#nLQmaxM !nd

!nd !nd

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4)+lid!r4

)@

!nd

s!lf.init56

d!f init56 mut! ? 6mag!6"#n.n!, 4mut!. ng4 min ? 6mag!6"#n.n!, 4min. ng4 m!d ? 6mag!6"#n.n!, 4m!d. ng4 max ? 6mag!6"#n.n!, 4max. ng4 an!l ? )>an!l.n!, an!l.s!t<ay#ut /#x<ay#ut.n!, an!l8 /#x<ay#ut..:_@:6+ an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r G08 G08 G08 G0 s!lf.s!t<ay#ut /#rd!r<ay#ut.n!, an!l.add /#x."r!at!F#riz#ntalJlu! lab!l ? )<ab!l.n!, mut!8 )<ab!l..(2;-2* slid!r ? )+lid!r.n!, 08 1508 0 "! ? (&ang!2v!nt.n!, "!.s!t<ab!l lab!l "!.s!t6"#ns mut!8 min8 m!d8 max slid!r.add_"&ang!_list!n!r "! slid!r.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, 1508 70 an!l.add slid!r an!l.add lab!l an!l.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 58 0 an!l.add /#x."r!at!F#riz#ntalJlu! s!lf.add an!l8 /#rd!r<ay#ut..(2;-2* s!lf. a"k s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In the code e#ample, we show a )+lid!r and a )<ab!l. 'y dragging the slider, we change the icon on the label component. (e ha e four images that represent arious states of the sound.
mut! ? 6mag!6"#n.n!, 4mut!. ng4

7ere we create an image icon.


an!l.s!t<ay#ut /#x<ay#ut.n!, an!l8 /#x<ay#ut..:_@:6+

0anel component has a hori.ontal /#x<ay#ut.

1B

an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r G08 G08 G08 G0

(e creare a 5Bp# border around the panel.


an!l.add /#x."r!at!F#riz#ntalJlu!

(e put resi.able space to both sides, left and right. It is to pre ent )+lid!r from growing to unnatural si.es.
lab!l ? )<ab!l.n!, mut!8 )<ab!l..(2;-2*

This line creates a )<ab!l instance with the specified image and hori.ontal alignment. The label is centered ertically in its display area by default.
slid!r ? )+lid!r.n!, 08 1508 0

This is a )+lid!r constructor. The parameters are minimum alue, ma#imum alue and current alue.
"! ? (&ang!2v!nt.n!, "!.s!t<ab!l lab!l "!.s!t6"#ns mut!8 min8 m!d8 max

/ 9hangeG ent ob$ect is created. (e set a label and icons to this ob$ect.
slid!r.add_"&ang!_list!n!r "!

Gach time we mo e the slider, the stat!(&ang!d method of the 9hangeG ent ob$ect will be called.
an!l.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 58 0

(e place a 6p# rigid space between the two components. They are too close to each other, when the slider is at the end position.
"lass (&ang!2v!nt in"lud! (&ang!<ist!n!r

This is a 9hangeG ent class, which implements the (&ang!<ist!n!r. /s a conse-uence, this class must implement a "&ang!2v!nt method.
s!nd!r ? !.g!t+#ur"! valu! ? s!nd!r.g!t=alu!

Inside the "&ang!2v!nt method, we get the e ent source. It is the slider, which has generated the e ent. "rom the sender, we get the current alue.
if valu! ?? 0 Qlab!l.s!t6"#nLQmut!M

If the alue is e-ual to .ero, we update the label to ha e a mute.png image.

1)

"igure4 JSlider

JToggleButton
is a button that has two states. 0ressed and not pressed. Cou toggle between these two states by clic!ing on it. There are situations where this functionality fits well.
)-#ggl!/utt#n $%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram us!s t#ggl! butt#ns t# "&ang! t&! ba"kgr#und "#l#r #f a an!l. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt #rt java.a,t.(#l#r java.a,t.0im!nsi#n java.a,t.!v!nt.@"ti#n<ist!n!r javax.s,ing.)-#ggl!/utt#n javax.s,ing./#x javax.s,ing./#x<ay#ut javax.s,ing./#rd!r1a"t#ry javax.s,ing.)1ram! javax.s,ing.)>an!l javax.s,ing.b#rd!r.<in!/#rd!r

"lass 2xam l! 3 )1ram! in"lud! @"ti#n<ist!n!r d!f initializ! su !r 4)-#ggl!/utt#n4 !nd s!lf.init56

d!f init56 s!lf.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, 2D08 200 b#tt#m ? )>an!l.n!, b#tt#m.s!t<ay#ut /#x<ay#ut.n!, b#tt#m8 /#x<ay#ut..:_@:6+ b#tt#m.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 208 208 208 20

11

l!ft>an!l ? )>an!l.n!, l!ft>an!l.s!t<ay#ut /#x<ay#ut.n!, l!ft>an!l8 /#x<ay#ut..I_@:6+ Qdis Qdis Qdis Qdis lay ? )>an!l.n!, lay.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, 1108 110 lay.s!t/#rd!r <in!/#rd!r."r!at!Jray<in!/#rd!r lay.s!t/a"kgr#und (#l#r.bla"k

b#tt#m.add Qdis lay r!d/utt#n ? )-#ggl!/utt#n.n!, 4r!d4 r!d/utt#n.add@"ti#n<ist!n!r s!lf gr!!n/utt#n ? )-#ggl!/utt#n.n!, 4gr!!n4 gr!!n/utt#n.add@"ti#n<ist!n!r s!lf blu!/utt#n ? )-#ggl!/utt#n.n!, 4blu!4 blu!/utt#n.add@"ti#n<ist!n!r s!lf blu!/utt#n.s!tRaximum+iz! gr!!n/utt#n.g!tRaximum+iz! r!d/utt#n.s!tRaximum+iz! gr!!n/utt#n.g!tRaximum+iz! l!ft>an!l.add l!ft>an!l.add l!ft>an!l.add l!ft>an!l.add l!ft>an!l.add r!d/utt#n /#x."r!at!*igid@r!a 0im!nsi#n.n!, 258 H gr!!n/utt#n /#x."r!at!*igid@r!a 0im!nsi#n.n!, 258 H blu!/utt#n

b#tt#m.add l!ft>an!l b#tt#m.add /#x."r!at!*igid@r!a 0im!nsi#n.n!, 208 0 s!lf.add b#tt#m s!lf. a"k s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd

d!f a"ti#n>!rf#rm!d ! "#l#r ? Qdis lay.g!t/a"kgr#und r!d ? "#l#r.g!t*!d gr!!n ? "#l#r.g!tJr!!n blu! ? "#l#r.g!t/lu! if !.g!t@"ti#n(#mmand ?? 4r!d4 if r!d ?? 0 r!d ? 255 !ls! r!d ? 0 !nd !nd if !.g!t@"ti#n(#mmand ?? 4gr!!n4 if gr!!n ?? 0 gr!!n ? 255 !ls! gr!!n ? 0 !nd !nd

13

if !.g!t@"ti#n(#mmand ?? 4blu!4 if blu! ?? 0 blu! ? 255 !ls! blu! ? 0 !nd !nd s!t(#l ? (#l#r.n!, r!d8 gr!!n8 blu! Qdis lay.s!t/a"kgr#und s!t(#l

!nd !nd

2xam l!.n!,

In the code e#ample, we use three toggle buttons to change the color of a rectangular component.
"lass 2xam l! 3 )1ram! in"lud! @"ti#n<ist!n!r

The class implements the @"ti#n<ist!n!r. (e will do some action in the a"ti#n>!rf#rm!d method of the G#ample class.
r!d/utt#n ? )-#ggl!/utt#n.n!, 4r!d4 r!d/utt#n.add@"ti#n<ist!n!r s!lf

(e create a )-#ggl!/utt#n component. (e add an action listener to the button. The action listener is the G#ample class. (hen we clic! on the red'utton, the a"ti#n>!rf#rm!d method of the G#ample class will be called.
blu!/utt#n.s!tRaximum+iz! gr!!n/utt#n.g!tRaximum+iz! r!d/utt#n.s!tRaximum+iz! gr!!n/utt#n.g!tRaximum+iz!

(e ma!e all three buttons of e-ual si.e.


"#l#r ? Qdis lay.g!t/a"kgr#und r!d ? "#l#r.g!t*!d gr!!n ? "#l#r.g!tJr!!n blu! ? "#l#r.g!t/lu!

(e determine the current red, green, blue parts of the display bac!ground color.
if !.g!t@"ti#n(#mmand ?? 4r!d4 if r!d ?? 0 r!d ? 255 !ls! r!d ? 0 !nd !nd

(e determine, which button was toggled, and update the color part of the RG' alue accordingly.
s!t(#l ? (#l#r.n!, r!d8 gr!!n8 blu!

15

Qdis lay.s!t/a"kgr#und s!t(#l

7ere a new color is created and the display panel is updated to a new color.

"igure4 JToggle'utton

JList
)<ist

is a component that displays a list of ob$ects. It allows the user to select one or more

items.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 ,! s&#, all availabl! f#nts #f a syst!m in a )<ist "#m #n!nt. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt #rt java.a,t./#rd!r<ay#ut java.a,t.0im!nsi#n java.a,t.1#nt java.a,t.Jra &i"s2nvir#nm!nt javax.s,ing.)1ram! javax.s,ing./#rd!r1a"t#ry javax.s,ing.)+"r#ll>an! javax.s,ing.)>an!l javax.s,ing.)<ab!l javax.s,ing.)<ist

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4)<ist4 init56

16

!nd d!f init56 an!l ? )>an!l.n!, an!l.s!t<ay#ut /#rd!r<ay#ut.n!, an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 208 208 208 20 g! ? Jra &i"s2nvir#nm!nt.g!t<#"alJra &i"s2nvir#nm!nt f#nts ? g!.g!t@vailabl!1#nt1amily;am!s list ? )<ist.n!, f#nts list.add_list_s!l!"ti#n_list!n!r d# E!E s!nd!r ? !.s#ur"! if n#t !.g!t=alu!6s@djusting nam! ? s!nd!r.g!t+!l!"t!d=alu! f#nt ? 1#nt.n!, nam!8 1#nt..><@6;8 17 Qlab!l.s!t1#nt f#nt !nd !nd an! ? )+"r#ll>an!.n!, an!.g!t=i!, #rt.add list an!.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, 2508 200 an!l.add an! Qlab!l ? )<ab!l.n!, 4@guirr!8 d!r '#rn J#tt!s4 Qlab!l.s!t1#nt 1#nt.n!, 4+!rif48 1#nt..><@6;8 12 s!lf.add Qlab!l8 /#rd!r<ay#ut..+95-F s!lf.add an!l s!lf. a"k s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd 2xam l!.n!,

In our e#ample, we will display a )<ist and a )<ab!l components. The list component contains a list of all a ailable font family names on our system. If we select an item from the list, the label will be displayed in a font, we ha e chosen.
g! ? Jra &i"s2nvir#nm!nt.g!t<#"alJra &i"s2nvir#nm!nt f#nts ? g!.g!t@vailabl!1#nt1amily;am!s

7ere we obtain all possible font family names on our system.


list ? )<ist.n!, f#nts

(e create an instance of the )<ist component. It will display all font family names.

1=

if n#t !.g!t=alu!6s@djusting

G ents in list selection are grouped. (e recei e e ents for both selecting and unselecting. To filter only the selecting e ents, we use the g!t=alu!6s@djusting method.
nam! ? s!nd!r.g!t+!l!"t!d=alu! f#nt ? 1#nt.n!, nam!8 1#nt..><@6;8 17 Qlab!l.s!t1#nt f#nt

(e get the selected item and set a new font for the label.
an! ? )+"r#ll>an!.n!, an!.g!t=i!, #rt.add list

component is not scrollable by default. (e put the list into the )+"r#ll>an! to ma!e it scrollable.
)<ist

"igure4 J;ist component In this part of the JRuby Swing tutorial, we ha e presented se eral Swing components.

Menus & toolbars


In this part of the JRuby Swing programming tutorial, we will wor! with menus and toolbar. / menubar is one of the most isible parts of the GUI application. It is a group of commands located in arious menus. (hile in console applications you had to remember all those arcane commands, here we ha e most of the commands grouped into logical parts. There are accepted standards that further reduce the amount of time spending to learn a new application. <enus group commands that we can use in an application. Toolbars pro ide a -uic! access to the most fre-uently used commands.

1>

Simple menu
The first e#ample will show a simple menu.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram "r!at!s a sim l! m!nu. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt java.a,t.!v!nt.K!y2v!nt javax.s,ing.)/utt#n javax.s,ing.)1ram! javax.s,ing.)R!nu/ar javax.s,ing.)R!nu6t!m javax.s,ing.)R!nu javax.s,ing.6mag!6"#n java.lang.+yst!m

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4+im l! m!nu4 !nd s!lf.init56

d!f init56 m!nubar ? )R!nu/ar.n!, i"#n ? 6mag!6"#n.n!, 4!xit. ng4 fil!R!nu ? )R!nu.n!, 41il!4 fil!R!nu.s!tRn!m#ni" K!y2v!nt..=K_1 it!m2xit ? )R!nu6t!m.n!, 42xit48 i"#n it!m2xit.add@"ti#n<ist!n!r d# E!E +yst!m.!xit 0 !nd it!m2xit.s!tRn!m#ni" K!y2v!nt..=K_( it!m2xit.s!t-##l-i -!xt 42xit a li"ati#n4 fil!R!nu.add it!m2xit m!nubar.add fil!R!nu s!lf.s!t)R!nu/ar m!nubar s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 2508 200 s!lf.s!t<#"ati#n*!lativ!-# nil

1?

!nd !nd

s!lf.s!t=isibl! tru!

2xam l!.n!,

%ur e#ample will show a menu with one item. 'y selecting the e#it menu item we close the application.
m!nubar ? )R!nu/ar.n!,

7ere we create a menubar.


i"#n ? 6mag!6"#n.n!, 4!xit. ng4

(e will display an icon in the menu item.


fil!R!nu ? )R!nu.n!, 41il!4 fil!R!nu.s!tRn!m#ni" K!y2v!nt..=K_1

(e create a menu ob$ect. / menu is a popup window containing )R!nu6t!ms. <enus are located on the menubar. The menus can be accessed ia the !eyboard as well. To bind a menu to a particular !ey, we use the s!tRn!m#ni" method. In our case, the menu can be opened with the /;T H " shortcut.
it!m2xit ? )R!nu6t!m.n!, 4(l#s!48 i"#n it!m2xit.add@"ti#n<ist!n!r d# E!E +yst!m.!xit 0 !nd

7ere we create a )R!nu6t!m. / menu item is an ob$ect shown in a popup window of the selected menu. (e also pro ide a shortcut for the menu item and a tooltip as well.
fil!R!nu.add it!m2xit

/ menu item is added to the menu.


m!nubar.add fil!R!nu

/ menu is added to the menubar.

"igure4 Simple menu 1@

Submenu
/ submenu is a menu plugged into another menu ob$ect. The ne#t e#ample demonstrates this.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram "r!at!s a subm!nu. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt java.a,t.!v!nt.K!y2v!nt java.a,t.!v!nt.@"ti#n2v!nt javax.s,ing.)1ram! javax.s,ing.6mag!6"#n javax.s,ing.)R!nu/ar javax.s,ing.)R!nu javax.s,ing.)R!nu6t!m javax.s,ing.K!y+tr#k! java.lang.+yst!m

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4+ubm!nu4 !nd s!lf.init56

d!f init56 m!nubar ? )R!nu/ar.n!, i"#n;!, ? 6mag!6"#n.n!, 4n!,. ng4 i"#n9 !n ? 6mag!6"#n.n!, 4# !n. ng4 i"#n+av! ? 6mag!6"#n.n!, 4sav!. ng4 i"#n2xit ? 6mag!6"#n.n!, 4!xit. ng4 fil!R!nu ? )R!nu.n!, 41il!4 fil!R!nu.s!tRn!m#ni" K!y2v!nt..=K_1 im ? )R!nu.n!, 46m #rt4 im .s!tRn!m#ni" K!y2v!nt..=K_R n!,sf ? )R!nu6t!m.n!, 46m #rt n!,sf!!d list...4 b##km ? )R!nu6t!m.n!, 46m #rt b##kmarks...4 mail ? )R!nu6t!m.n!, 46m #rt mail...4 im .add n!,sf im .add b##km im .add mail

3B

fil!;!, ? )R!nu6t!m.n!, 4;!,48 i"#n;!, fil!;!,.s!tRn!m#ni" K!y2v!nt..=K_; fil!9 !n ? )R!nu6t!m.n!, 49 !n48 i"#n9 !n fil!;!,.s!tRn!m#ni" K!y2v!nt..=K_9 fil!+av! ? )R!nu6t!m.n!, 4+av!48 i"#n+av! fil!+av!.s!tRn!m#ni" K!y2v!nt..=K_+ fil!2xit ? )R!nu6t!m.n!, 42xit48 i"#n2xit fil!2xit.add@"ti#n<ist!n!r d# E!E +yst!m.!xit 0 !nd fil!2xit.s!tRn!m#ni" K!y2v!nt..=K_( fil!2xit.s!t-##l-i -!xt 42xit a li"ati#n4 fil!2xit.s!t@""!l!rat#r K!y+tr#k!.g!tK!y+tr#k! K!y2v!nt..=K_B8 @"ti#n2v!nt..(-*<_R@+K fil!R!nu.add fil!;!, fil!R!nu.add fil!9 !n fil!R!nu.add fil!+av! fil!R!nu.add+! arat#r fil!R!nu.add im fil!R!nu.add+! arat#r fil!R!nu.add fil!2xit m!nubar.add fil!R!nu s!lf.s!t)R!nu/ar m!nubar s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7208 220 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In the e#ample, we ha e three options in a submenu of a file menu.


im ? )R!nu.n!, 46m #rt4 ... fil!R!nu.add im

/ submenu is $ust li!e any other normal menu. It is created the same way. (e simply add a menu to e#isting menu.
fil!2xit.s!t@""!l!rat#r K!y+tr#k!.g!tK!y+tr#k! K!y2v!nt..=K_B8 @"ti#n2v!nt..(-*<_R@+K

/n accelerator is a !ey shortcut that launches a menu item. In our case, by pressing 9trl H ( we close the application.
fil!R!nu.add+! arat#r

3)

/ separator is a hori.ontal line that isually separates the menu items. This way we can group items into some logical places.

"igure4 Submenu

Popup menu
In the ne#t e#ample, we create a popup menu.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is # u r#gram "r!at!s a m!nu.

aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im #rt #rt #rt #rt #rt java.a,t.!v!nt.R#us!@da t!r javax.s,ing.)1ram! javax.s,ing.)># u R!nu javax.s,ing.)R!nu6t!m java.lang.+yst!m

"lass R#us!@"ti#n 3 R#us!@da t!r d!f m#us!*!l!as!d ! s#ur"! ? !.s#ur"! m!nu ? s#ur"!.g!tR!nu if !.g!t/utt#n ?? !.butt#n m!nu.s&#, !.g!t(#m #n!nt8 !.g!t:8 !.g!tI !nd !nd !nd

"lass 2xam l! 3 )1ram!

31

d!f initializ! su !r 4># u s!lf.init56 !nd d!f init56

m!nu4

Qm!nu ? )># u R!nu.n!, m!nu6t!m/!! ? )R!nu6t!m.n!, 4/!! 4 m!nu6t!m/!! .add@"ti#n<ist!n!r d# E!E t##lkit ? g!t-##lkit t##lkit.b!! !nd Qm!nu.add m!nu6t!m/!! m!nu6t!m2xit ? )R!nu6t!m.n!, 42xit4 m!nu6t!m2xit.add@"ti#n<ist!n!r d# E!E +yst!m.!xit 0 !nd Qm!nu.add m!nu6t!m2xit s!lf.addR#us!<ist!n!r R#us!@"ti#n.n!, s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 2508 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd d!f g!tR!nu Qm!nu !nd

!nd

2xam l!.n!,

In our e#ample, we create a popup menu with two menu items.


Qm!nu ? )># u R!nu.n!, m!nu6t!m/!! ? )R!nu6t!m.n!, 4/!! 4

(e create a popup menu and a menu item.


s!lf.addR#us!<ist!n!r R#us!@"ti#n.n!,

(e add a mouse listener to the G#ample class. The mouse listener is a <ouse/ction user defined class, which inherits from a R#us!@da t!r. It is a con enience class which implements all fi e re-uired methods. The methods are empty. Instead of implementing all fi e methods, we implement only the methods, that we need.
"lass R#us!@"ti#n 3 R#us!@da t!r d!f m#us!*!l!as!d ! ...

In our <ouse/ction class we implement the m#us!*!l!as!d method.

33

if !.g!t/utt#n ?? !.butt#n. m!nu.s&#, !.g!t(#m #n!nt8 !.g!t:8 !.g!tI !nd

(e show the popup menu window at the #, y coordinates of the mouse clic!.

"igure4 0opup menu

JToolbar
<enus group commands that we can use in an application. Toolbars pro ide a -uic! access to the most fre-uently used commands. In Swing, the )-##l/ar class creates a toolbar in an application.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram "r!at!s a t##lbar. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt java.a,t./#rd!r<ay#ut javax.s,ing.)1ram! javax.s,ing.6mag!6"#n javax.s,ing.)/utt#n javax.s,ing.)R!nu/ar javax.s,ing.)R!nu javax.s,ing.)-##l/ar java.lang.+yst!m

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4-##lbar4

35

!nd

s!lf.init56

d!f init56 m!nubar ? )R!nu/ar.n!, fil!R!nu ? )R!nu.n!, 41il!4 m!nubar.add fil!R!nu t##lbar ? )-##l/ar.n!, i"#n2xit ? 6mag!6"#n.n!, 4!xit2. ng4 !xit/utt#n ? )/utt#n.n!, i"#n2xit !xit/utt#n.add@"ti#n<ist!n!r d# E!E +yst!m.!xit 0 !nd t##lbar.add !xit/utt#n s!lf.add t##lbar8 /#rd!r<ay#ut..;9*-F s!lf.s!t)R!nu/ar m!nubar s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7508 250 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

The e#ample creates a toolbar with one e#it button.


t##lbar ? )-##l/ar.n!,

/ toolbar is created.
!xit/utt#n ? )/utt#n.n!, i"#n2xit ... t##lbar.add !xit/utt#n

(e create a button and add it to the toolbar.


s!lf.add t##lbar8 /#rd!r<ay#ut..;9*-F

The toolbar is placed into the north part of the /#rd!r<ay#ut manager. The /#rd!r<ay#ut manager is the default layout manager for the )1ram! container.

36

"igure4 Toolbar In this part of the JRuby Swing tutorial, we mentioned menus and toolbars.

Dialogs
In this part of the JRuby Swing programming tutorial, we will wor! with dialogs. Aialog windows or dialogs are an indispensable part of most modern GUI applications. / dialog is defined as a con ersation between two or more persons. In a computer application a dialog is a window which is used to Ital!I to the application. / dialog is used to input data, modify data, change the application settings etc. Aialogs are important means of communication between a user and a computer program.

essage boxes
<essage bo#es are con enient dialogs that pro ide messages to the user of the application. The message consists of te#t and image data.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram d!m#nstrat!s m!ssag! dial#gs. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im #rt #rt #rt #rt #rt java.a,t.Jrid<ay#ut javax.s,ing.)1ram! javax.s,ing.)/utt#n javax.s,ing.)>an!l javax.s,ing.)9 ti#n>an!

3=

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4R!ssag! b#x!s4 !nd s!lf.init56

d!f init56 an!l ? )>an!l.n!, an!l.s!t<ay#ut Jrid<ay#ut.n!, 28 2 !rr#r/utt#n ? )/utt#n.n!, 42rr#r4 !rr#r/utt#n.add@"ti#n<ist!n!r d# E!E )9 ti#n>an!.s&#,R!ssag!0ial#g an!l8 4(#uld n#t # !n fil!48 42rr#r48 )9 ti#n>an!..2**9*_R2++@J2 !nd ,arning/utt#n ? )/utt#n.n!, 4Barning4 ,arning/utt#n.add@"ti#n<ist!n!r d# E!E )9 ti#n>an!.s&#,R!ssag!0ial#g an!l8 4@ d! r!"at!d "all48 4Barning48 )9 ti#n>an!..B@*;6;J_R2++@J2 !nd Au!sti#n/utt#n ? )/utt#n.n!, 4Cu!sti#n4 Au!sti#n/utt#n.add@"ti#n<ist!n!r d# E!E )9 ti#n>an!.s&#,R!ssag!0ial#g an!l8 4@r! y#u sur! t# AuitN48 4Cu!sti#n48 )9 ti#n>an!..C52+-69;_R2++@J2 !nd inf#rm/utt#n ? )/utt#n.n!, 46nf#rmati#n4 inf#rm/utt#n.add@"ti#n<ist!n!r d# E!E )9 ti#n>an!.s&#,R!ssag!0ial#g an!l8 40#,nl#ad "#m l!t!d48 46nf#rmati#n48 )9 ti#n>an!..6;19*R@-69;_R2++@J2 !nd an!l.add an!l.add an!l.add an!l.add s!lf.add !rr#r/utt#n ,arning/utt#n Au!sti#n/utt#n inf#rm/utt#n an!l

s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7008 200 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

(e use the Jrid<ay#ut manager to set up a grid of four buttons. Gach of the buttons shows a different message bo#.
!rr#r/utt#n.add@"ti#n<ist!n!r d# E!E )9 ti#n>an!.s&#,R!ssag!0ial#g an!l8 4(#uld n#t # !n fil!48

3>

!nd

42rr#r48 )9 ti#n>an!..2**9*_R2++@J2

In case we pressed the error button, we show the error dialog. (e use the s&#,R!ssag!0ial#g method to show the dialog on the screen. The first parameter of this method is the panel, in which the dialog is displayed. The second parameter is the message to be displayed. The third parameter is the title of the dialog. The final parameter is the message type. The default icon is determined by the message type. In our case, we ha e 2**9*_R2++@J2 message type for the error dialog.

"igure4 Grror message dialog

J!ileChooser
)1il!(&##s!r

dialog allows user to select a file from the filesystem.

$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 ,! us! a )1il!(&##s!r t# l#ad a " fil!. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im im im im im im #rt #rt #rt #rt #rt #rt #rt #rt #rt #rt #rt #rt java.a,t./#rd!r<ay#ut java.a,t.(#l#r javax.s,ing.)1ram! javax.s,ing.)/utt#n javax.s,ing.)>an!l javax.s,ing.)-##l/ar javax.s,ing.)1il!(&##s!r javax.s,ing.)-!xt@r!a javax.s,ing.)-!xt>an! javax.s,ing.)+"r#ll>an! javax.s,ing./#rd!r1a"t#ry javax.s,ing.fil!"&##s!r..1il!;am!2xt!nsi#n1ilt!r

"lass 2xam l! 3 )1ram! d!f initializ! su !r 41il!(&##s!r4 s!lf.init56

3?

!nd d!f init56 Q an!l ? )>an!l.n!, Q an!l.s!t<ay#ut /#rd!r<ay#ut.n!, t##lbar ? )-##l/ar.n!, # !nb ? )/utt#n.n!, 4(&##s! fil!4 # !nb.add@"ti#n<ist!n!r d# E!E "&##s!1il! ? )1il!(&##s!r.n!, filt!r ? 1il!;am!2xt!nsi#n1ilt!r.n!, 4" fil!s48 4"4 "&##s!1il!.add(&##sabl!1il!1ilt!r filt!r r!t ? "&##s!1il!.s&#,0ial#g Q an!l8 4(&##s! fil!4 if r!t ?? )1il!(&##s!r..@>>*9=2_9>-69; fil! ? "&##s!1il!.g!t+!l!"t!d1il! t!xt ? s!lf.r!ad1il! fil! Qar!a.s!t-!xt t!xt.t#_s !nd

!nd

t##lbar.add # !nb Qar!a ? )-!xt@r!a.n!, Qar!a.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 108 108 108 10 an! ? )+"r#ll>an!.n!, an!.g!t=i!, #rt.add Qar!a Q an!l.s!t/#rd!r /#rd!r1a"t#ry."r!at!2m ty/#rd!r 108 108 108 10 Q an!l.add an! s!lf.add Q an!l s!lf.add t##lbar8 /#rd!r<ay#ut..;9*-F s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! G508 G00 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd

d!f r!ad1il! fil! fil!nam! ? fil!.g!t(an#ni"al>at& f ? 1il!.# !n fil!nam!8 4r4 t!xt ? 69.r!adlin!s fil!nam! r!turn t!xt

!nd !nd

2xam l!.n!,

In our code e#ample, we use the )1il!(&##s!r dialog to select a 9 file and display its contents in a )-!xt@r!a.
Qar!a ? )-!xt@r!a.n!,

This is the )-!xt@r!a in which we will show the contents of a selected file. 3@

"&##s!1il! ? )1il!(&##s!r.n!, filt!r ? 1il!;am!2xt!nsi#n1ilt!r.n!, 4" fil!s48 4"4 "&##s!1il!.add(&##sabl!1il!1ilt!r filt!r

(e create an instance of the )1il!(&##s!r dialog. (e create a filter which will show only 9 files.
r!t ? "&##s!1il!.s&#,0ial#g Q an!l8 4(&##s! fil!4

The dialog is shown on the screen. (e get the return alue.


if r!t ?? )1il!(&##s!r..@>>*9=2_9>-69; fil! ? "&##s!1il!.g!t+!l!"t!d1il! t!xt ? s!lf.r!ad1il! fil! Qar!a.s!t-!xt t!xt.t#_s !nd

If the user has selected a file, we get the name of the file. Read its contents and set the te#t to the te#t area component.
d!f r!ad1il! fil! fil!nam! ? fil!.g!t(an#ni"al>at& f ? 1il!.# !n fil!nam!8 4r4 t!xt ? 69.r!adlin!s fil!nam! r!turn t!xt

!nd

This code reads the te#t from the file. The g!t(an#ni"al>at& returns an absolute file name.

"igure4 J"ile9hooser In this part of the JRuby Swing tutorial, we wor!ed with dialog windows.

5B

Painting
In this part of the JRuby Swing programming tutorial we will do some painting. (e use painting to create charts, custom components or create games. To do the painting, we use the painting /0I pro ided by the Swing tool!it. The painting is done within the aint(#m #n!nt method. In the painting process, we use the Jra &i"s20 ob$ect. It is a graphics conte#t that allows an application to draw onto components. It is the fundamental class for rendering 12dimensional shapes, te#t and images.

Colors
/ color is an ob$ect representing a combination of Red, Green, and 'lue JRG'K intensity alues. (e use the (#l#r class to wor! with colors in Swing.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is !xam l! ,! dra, nin! r!"tangl!s fill!d ,it& nin! diff!r!nt "#l#rs. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im #rt java.a,t.(#l#r im #rt javax.s,ing.)1ram! im #rt javax.s,ing.)>an!l "lass (anvas 3 )>an!l d!f aint(#m #n!nt g s!lf.dra,(#l#r*!"tangl!s g !nd d!f dra,(#l#r*!"tangl!s g g.s!t(#l#r (#l#r.n!, 1258 16H8 116 g.fill*!"t 108 158 S08 60 g.s!t(#l#r (#l#r.n!, G28 1HS8 271 g.fill*!"t 1708 158 S08 60 g.s!t(#l#r (#l#r.n!, H08 6H8 127 g.fill*!"t 2508 158 S08 60 g.s!t(#l#r (#l#r.n!, 1708 1008 DG g.fill*!"t 108 1058 S08 60

5)

g.s!t(#l#r (#l#r.n!, 2528 2118 61 g.fill*!"t 1708 1058 S08 60 g.s!t(#l#r (#l#r.n!, 2G18 SD8 6S g.fill*!"t 2508 1058 S08 60 g.s!t(#l#r (#l#r.n!, 21H8 1G68 5G g.fill*!"t 108 1S58 S08 60 g.s!t(#l#r (#l#r.n!, 678 1218 1D6 g.fill*!"t 1708 1S58 S08 60 g.s!t(#l#r (#l#r.n!, 718 218 1 g.fill*!"t 2508 1S58 S08 60 !nd !nd "lass 2xam l! 3 )1ram! d!f initializ! su !r 4(#l#rs4 s!lf.init56 !nd d!f init56 "anvas ? (anvas.n!, s!lf.g!t(#nt!nt>an!.add "anvas s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7608 700 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In the code e#ample, we draw nine rectangles and fill them with different color alues.
d!f aint(#m #n!nt g

9ustom painting is done in aint(#m #n!nt in most cases. The g parameter is the graphics conte#t. (e call the painting operations on this ob$ect.
g.s!t(#l#r (#l#r.n!, 1258 16H8 116

(e set the conte#tLs current color to the specified color. /ll subse-uent graphics operations using this graphics conte#t use this specified color.
g.fill*!"t 108 158 S08 60

(e fill a rectangle located at #M)B, yM)6 ha ing widthM@B and heightM=B with the abo e specified color alue.

51

"igure4 9olors

Shapes
The Swing painting /0I can draw arious shapes. The following programming code e#ample will show some of them.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is !xam l! dra,s sim l! s&a !s #n a an!l. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im #rt #rt #rt #rt #rt java.a,t.(#l#r java.a,t.*!nd!ringFints java.a,t.g!#m.2lli s!20 javax.s,ing.)1ram! javax.s,ing.)>an!l

"lass (anvas 3 )>an!l d!f !nd aint(#m #n!nt g s!lf.dra,+&a !s g

d!f dra,+&a !s g g.s!t(#l#r (#l#r.n!, 1508 1508 150

53

r& ? *!nd!ringFints.n!, *!nd!ringFints..K2I_@;-6@<6@+6;J8 *!nd!ringFints..=@<52_@;-6@<6@+_9; r&. ut *!nd!ringFints..K2I_*2;02*6;J8 *!nd!ringFints..=@<52_*2;02*_C5@<6-I g.s!t*!nd!ringFints r& g.fill*!"t 208 208 508 50 g.fill*!"t 1208 208 S08 60 g.fill*#und*!"t 2508 208 H08 608 258 25 g.fill 2lli s!20..0#ubl!.n!, 108 1008 D08 100 g.fill@r" 1208 1708 1108 1008 58 150 g.fill9val 2H08 1708 508 50 !nd !nd "lass 2xam l! 3 )1ram! d!f initializ! su !r 4+&a !s4 s!lf.init56 !nd d!f init56 "anvas ? (anvas.n!, s!lf.g!t(#nt!nt>an!.add "anvas s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7508 250 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

In this code e#ample, we draw si# different shapes on the window. / s-uare, a rectangle, a rounded rectangle, an ellipse, an arc and an o al. (e do not draw outlines of the shapes, but we fill the inner space of the shapes with a gray color.
r& ? *!nd!ringFints.n!, *!nd!ringFints..K2I_@;-6@<6@+6;J8 *!nd!ringFints..=@<52_@;-6@<6@+_9;

(ith the rendering hints, we control the -uality of the painting. In the abo e code, we implement antialiasing. (ith antialiasing, the shapes are more smooth.
g.s!t(#l#r (#l#r.n!, 1508 1508 150

(e will be painting in some gray color.


g.fill*!"t 208 208 508 50 g.fill*!"t 1208 208 S08 60

55

g.fill*#und*!"t 2508 208 H08 608 258 25

7ere we draw a rectangle, a s-uare and a rounded rectangle. The first four parameters in these methods are the #, y coordinates and width and height. The last two parameters for the fill*#und*!"t are the hori.ontal and ertical diameter of the arc at the four corners.
g.fill 2lli s!20..0#ubl!.n!, 108 1008 D08 100 g.fill@r" 1208 1708 1108 1008 58 150 g.fill9val 2H08 1708 508 50

These three lines draw an ellipse, an arc and an o al.

"igure4 Shapes

Transparent rectangles
Transparency is the -uality of being able to see through a material. The easiest way to understand transparency is to imagine a piece of glass or water. Technically, the rays of light can go through the glass and this way we can see ob$ects behind the glass. In computer graphics, we can achie e transparency effects using alpha compositing. /lpha compositing is the process of combining an image with a bac!ground to create the appearance of partial transparency. The composition process uses an alpha channel. Jwi!ipedia.org, answers.comK
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial -&is r#gram dra,s t!n r!"tangl!s ,it& diff!r!nt l!v!ls #f trans ar!n"y. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava

56

im im im im

#rt #rt #rt #rt

java.a,t.(#l#r java.a,t.@l &a(#m #sit! javax.s,ing.)1ram! javax.s,ing.)>an!l

"lass (anvas 3 )>an!l d!f aint(#m #n!nt g g.s!t(#l#r (#l#r../<52 f#r i in 1..10 d# g.s!t(#m #sit! @l &a(#m #sit!.g!t6nstan"! @l &a(#m #sit!..+*(_9=2*8 !nd !nd !nd "lass 2xam l! 3 )1ram! d!f initializ! su !r 4-rans ar!nt r!"tangl!s4 s!lf.init56 !nd d!f init56 "anvas ? (anvas.n!, s!lf.g!t(#nt!nt>an!.add "anvas s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 5S08 120 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! g.fill*!"t 50 T i8 208 G08 G0

i T 0.1

!nd !nd

2xam l!.n!,

In the e#ample we will draw ten rectangles with different le els of transparency.
g.s!t(#m #sit! @l &a(#m #sit!.g!t6nstan"! @l &a(#m #sit!..+*(_9=2*8 i T 0.1

The @l &a(#m #sit! class implements basic alpha compositing rules.

5=

"igure4 Transparent rectangles

"onut Shape
In the following e#ample we create a comple# shape by rotating a bunch of ellipses. /n affine transform is composed of .ero or more linear transformations Jrotation, scaling or shearK and translation JshiftK. The @ffin!-ransf#rm is the class in Swing to perform affine transformations.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is "#d! !xam l!8 ,! "r!at! a 0#nut s&a !. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im im #rt #rt #rt #rt #rt #rt #rt java.a,t./asi"+tr#k! java.a,t.(#l#r java.a,t.*!nd!ringFints java.a,t.g!#m.@ffin!-ransf#rm java.a,t.g!#m.2lli s!20 javax.s,ing.)1ram! javax.s,ing.)>an!l

"lass (anvas 3 )>an!l d!f aint(#m #n!nt g s!lf.dra,0#nut g !nd d!f dra,0#nut g r& ? *!nd!ringFints.n!, *!nd!ringFints..K2I_@;-6@<6@+6;J8 *!nd!ringFints..=@<52_@;-6@<6@+_9; r&. ut *!nd!ringFints..K2I_*2;02*6;J8 *!nd!ringFints..=@<52_*2;02*_C5@<6-I g.s!t*!nd!ringFints r& siz! ? s!lf.g!t+iz! , ? siz!.g!tBidt& & ? siz!.g!tF!ig&t ! ? 2lli s!20..0#ubl!.n!, 08 08 D08 170 g.s!t+tr#k! /asi"+tr#k!.n!, 1 g.s!t(#l#r (#l#r.gray d!g ? 0

5>

H2.tim!s d# at ? @ffin!-ransf#rm.g!t-ranslat!6nstan"! , / 28 & / 2 at.r#tat! d!g/1D0.0 T Rat&..>6 g.dra, at."r!at!-ransf#rm!d+&a ! ! d!g U? 5 !nd !nd !nd

"lass 2xam l! 3 )1ram! d!f initializ! su !r 40#nut4 !nd s!lf.init56

d!f init56 "anvas ? (anvas.n!, s!lf.g!t(#nt!nt>an!.add "anvas s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! 7508 720 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

In this e#ample, we create a donut. The shape resembles a coo!ie, hence the name donut. The donut is centered in the window.
siz! ? s!lf.g!t+iz! , ? siz!.g!tBidt& & ? siz!.g!tF!ig&t

7ere we determine the width and height of the window. (e need these alues to center the donut shape.
! ? 2lli s!20..0#ubl!.n!, 08 08 D08 170

(e create an ellipse shape. (e will rotate this ellipse to create the donut shape.
g.s!t+tr#k! /asi"+tr#k!.n!, 1 g.s!t(#l#r (#l#r.gray

(e set the stro!e and the color for the outlines of the shapes.
d!g ? 0 H2.tim!s d#

5?

(e draw an ellipse ob$ect >1 times. Gach time, we rotate the ellipse by additional 6 degrees. This will create our donut shape.
at ? @ffin!-ransf#rm.g!t-ranslat!6nstan"! , / 28 & / 2 at.r#tat! d!g/1D0.0 T Rat&..>6 g.dra, at."r!at!-ransf#rm!d+&a ! !

(ith the help of the @ffin!-ransf#rm class we translate the drawing to the center of the window. Then we do rotation. The "r!at!-ransf#rm!d+&a ! method will apply these affine transforms to the ellipse. /nd the transformed ellipse is drawn using the dra, method. The r#tat! method ta!es angles in radians, so we calculate radians out of degrees.

"rawing text
In the last e#ample, we are going to draw te#t on the window.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is !xam l! ,! dra, lyri"s #f a s#ng #n t&! ,ind#, an!l. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im #rt #rt #rt #rt #rt #rt java.a,t.(#l#r java.a,t.1#nt java.a,t.*!nd!ringFints java.a,t.g!#m.2lli s!20 javax.s,ing.)1ram! javax.s,ing.)>an!l

"lass (anvas 3 )>an!l d!f !nd d!f dra,<yri"s g r& ? *!nd!ringFints.n!, *!nd!ringFints..K2I_@;-6@<6@+6;J8 *!nd!ringFints..=@<52_@;-6@<6@+_9; r&. ut *!nd!ringFints..K2I_*2;02*6;J8 *!nd!ringFints..=@<52_*2;02*_C5@<6-I g.s!t*!nd!ringFints r& g.s!t1#nt 1#nt.n!, 4>urisa48 1#nt..><@6;8 17 g.dra,+tring 4R#st r!lati#ns&i s s!!m s# transit#ry48 208 70 aint(#m #n!nt g s!lf.dra,<yri"s g

5@

120

g.dra,+tring 4-&!yPr! all g##d but n#t t&! !rman!nt #n!48 208 60 g.dra,+tring 4B&# d#!snPt l#ng f#r s#m!#n! t# &#ld48 208 S0 g.dra,+tring 4B&# kn#,s &#, t# l#v! y#u ,it&#ut b!ing t#ld48 208 g.dra,+tring 4+#m!b#dy t!ll m! ,&y 6Pm #n my #,n48 208 150 g.dra,+tring 46f t&!r!Ps a s#ulmat! f#r !v!ry#n!48 208 1D0 !nd

!nd "lass 2xam l! 3 )1ram! d!f initializ! su !r 4+#ulmat!4 init56 !nd d!f init56 "anvas ? (anvas.n!, s!lf.g!t(#nt!nt>an!.add "anvas s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t+iz! G008 250 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru!

!nd !nd

2xam l!.n!,

(e draw a lyrics of a song on the window.


r& ? *!nd!ringFints.n!, *!nd!ringFints..K2I_-2:-_@;-6@<6@+6;J8 *!nd!ringFints..=@<52_-2:-_@;-6@<6@+_9; g.s!t*!nd!ringFints r&

(e apply te#t antialiasing on the painting.


g.s!t1#nt 1#nt.n!, 4>urisa48 1#nt..><@6;8 17

(e specify the font name, style and point si.e, in which we draw the lyrics.
g.dra,+tring 4R#st r!lati#ns&i s s!!m s# transit#ry48 208 70

The dra,+tring method draws the te#t.

6B

"igure4 Arawing te#t In this part of the JRuby Swing programming tutorial, we did some painting.

Nibbles
In this part of the JRuby Swing programming tutorial, we will create a &ibbles game clone. Nibbles is an older classic ideo game. It was first created in late >Bs. ;ater it was brought to 09s. In this game the player controls a sna!e. The ob$ecti e is to eat as many apples as possible. Gach time the sna!e eats an apple, its body grows. The sna!e must a oid the walls and its own body.

"e#elopment
The si.e of each of the $oints of a sna!e is )Bp#. The sna!e is controlled with the cursor !eys. Initially, the sna!e has three $oints. The game starts immediately. (hen the game is finished, we display IGame % erI message in the center of the window.
$%/usr/l#"al/bin/jruby $ $ $ $ $ $ $ $ '!t(#d! )*uby +,ing tut#rial 6n t&is r#gram8 ,! "r!at! a ;ibbl!s gam! "l#n!. aut&#r. )an /#dnar ,!bsit!. ,,,.z!t"#d!."#m last m#difi!d. 0!"!mb!r 2010

in"lud! )ava im im im im im im #rt #rt #rt #rt #rt #rt java.a,t.(#l#r java.a,t.1#nt java.a,t.0im!nsi#n java.a,t.-##lkit java.a,t.!v!nt.@"ti#n<ist!n!r java.a,t.!v!nt.K!y2v!nt

6)

im im im im im

#rt #rt #rt #rt #rt

java.a,t.!v!nt.K!y<ist!n!r javax.s,ing.)1ram! javax.s,ing.6mag!6"#n javax.s,ing.)>an!l javax.s,ing.-im!r

;B60-F ? 700 ;F26JF- ? 700 09-_+6'2 ? 10 @<<_09-+ ? ;B60-F T ;F26JF- / L09-_+6'2 T 09-_+6'2M *@;0_>9+ ? 25 02<@I ? 1G0 $x ? V0W T @<<_09-+ $y ? V0W T @<<_09-+ "lass /#ard 3 )>an!l in"lud! K!y<ist!n!r8 @"ti#n<ist!n!r d!f initializ! su !r s!lf.s!t1#"usabl! tru! !nd s!lf.initJam!

d!f initJam! Ql!ft ? fals! Qrig&t ? tru! Qu ? fals! Qd#,n ? fals! QinJam! ? tru! Qd#ts ? 7 b!gin iid ? 6mag!6"#n.n!, 4d#t. ng4 Qball ? iid.g!t6mag! iia ? 6mag!6"#n.n!, 4a Qa l! ? iia.g!t6mag! l!. ng4

ii& ? 6mag!6"#n.n!, 4&!ad. ng4 Q&!ad ? ii&.g!t6mag! r!s"u! uts 4"ann#t l#ad imag!s4 !nd f#r i in 0..Qd#ts $xViW ? 50 - i T 10 $yViW ? 50 !nd s!lf.l#"at!@ l! s!lf.s!t/a"kgr#und (#l#r.bla"k s!lf.addK!y<ist!n!r s!lf

61

Qtim!r ? -im!r.n!, 02<@I8 s!lf Qtim!r.start !nd d!f aint g su !r g if QinJam! s!lf.dra,9bj!"ts g -##lkit.g!t0!fault-##lkit.syn" g.dis #s! !ls! !nd !nd s!lf.gam!9v!r g

d!f dra,9bj!"ts g g.dra,6mag! Qa l!8 Qa l!_x8 Qa l!_y8 s!lf

!nd

f#r z in 0..Qd#ts if z ?? 0 g.dra,6mag! Q&!ad8 $xVzW8 $yVzW8 s!lf !ls! g.dra,6mag! Qball8 $xVzW8 $yVzW8 s!lf !nd !nd

d!f gam!9v!r g msg ? 4Jam! 9v!r4 small ? 1#nt.n!, 4F!lv!ti"a48 1#nt../9<08 1G m!tr ? s!lf.g!t1#ntR!tri"s small g.s!t(#l#r (#l#r.,&it! g.s!t1#nt small g.dra,+tring msg8 L;B60-F - m!tr.stringBidt&LmsgMM / 28 ;F26JF- / 2 Qtim!r.st#

!nd

d!f "&!"k@

l! l!_y

if $xV0W ?? Qa l!_x and $yV0W ?? Qa Qd#ts ? Qd#ts U 1 s!lf.l#"at!@ l! !nd !nd d!f m#v!

63

z ? Qd#ts ,&il! z O $xVzW $yVzW z ? z !nd 0 ? $xVLz - 1MW ? $yVLz - 1MW - 1

if Ql!ft $xV0W -? 09-_+6'2 !nd if Qrig&t $xV0W U? 09-_+6'2 !nd if Qu $yV0W -? 09-_+6'2 !nd if Qd#,n $yV0W U? 09-_+6'2 !nd !nd d!f "&!"k(#llisi#n z ? Qd#ts ,&il! z O 0 if z O G and $xV0W ?? $xVzW and $yV0W ?? $yVzW QinJam! ? fals! !nd z ? z - 1 !nd if $yV0W O ;F26JF- - 09-_+6'2 QinJam! ? fals! !nd if $yV0W 3 0 QinJam! ? fals! !nd if $xV0W O ;B60-F - 09-_+6'2 QinJam! ? fals! !nd if $xV0W 3 0 QinJam! ? fals! !nd !nd d!f l#"at!@ l!

r ? rand *@;0_>9+ Qa l!_x ? r T 09-_+6'2

65

r ? rand *@;0_>9+ Qa l!_y ? r T 09-_+6'2 !nd d!f a"ti#n>!rf#rm!d ! if QinJam! s!lf."&!"k@ l! s!lf."&!"k(#llisi#n s!lf.m#v! !nd s!lf.r! aint !nd d!f k!y*!l!as!d ! !nd d!f k!y>r!ss!d ! k!y ? !.g!tK!y(#d! if k!y ?? Ql!ft Qu ? Qd#,n !nd K!y2v!nt..=K_<21- and n#t Qrig&t ? tru! fals! ? fals!

if k!y ?? K!y2v!nt..=K_*6JF- and n#t Ql!ft Qrig&t ? tru! Qu ? fals! Qd#,n ? fals! !nd if k!y ?? K!y2v!nt..=K_5> and n#t Qd#,n Qu ? tru! Qrig&t ? fals! Ql!ft ? fals! !nd if k!y ?? K!y2v!nt..=K_09B; and n#t Qu Qd#,n ? tru! Qrig&t ? fals! Ql!ft ? fals! !nd

!nd !nd

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4;ibbl!s4 !nd s!lf.init56

d!f init56

66

b#ard ? /#ard.n!, b#ard.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, ;B60-F8 ;F26JFs!lf.add b#ard s!lf. a"k s!lf.s!t*!sizabl! fals! s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

2xam l!.n!,

"irst we will define some constants used in our game. The B60-F and F26JF- constants determine the si.e of the 'oard. The 09-_+6'2 is the si.e of the apple and the dot of the sna!e. The @<<_09-+ constant defines the ma#imum number of possible dots on the 'oard. The *@;0_>9+ constant is used to calculate a random position of an apple. The 02<@I constant determines the speed of the game.
$x ? V0W T @<<_09-+ $y ? V0W T @<<_09-+

These two arrays store #, y coordinates of all possible $oints of a sna!e. The initJam! method initiali.es ariables, loads images and starts a timeout function.
d!f aint g su !r g if QinJam! s!lf.dra,9bj!"ts g -##lkit.g!t0!fault-##lkit.syn" g.dis #s! !ls! !nd !nd s!lf.gam!9v!r g

Inside the aint method, we chec! the NinGame ariable. If it is true, we draw our ob$ects. The apple and the sna!e $oints. %therwise we display IGame o erI te#t. The -##lkit.g!t0!fault-##lkit.syn" method ensures that the display is up2to2date. It is useful for animation.
d!f dra,9bj!"ts g g.dra,6mag! Qa l!8 Qa l!_x8 Qa l!_y8 s!lf

f#r z in 0..Qd#ts if z ?? 0 g.dra,6mag! Q&!ad8 $xVzW8 $yVzW8 s!lf

6=

!ls! !nd !nd !nd

g.dra,6mag! Qball8 $xVzW8 $yVzW8 s!lf

The dra,9bj!"ts method draws the apple and the $oints of the sna!e. The first $oint of a sna!e is its head, which is represented by a red circle.
d!f gam!9v!r g msg ? 4Jam! 9v!r4 small ? 1#nt.n!, 4F!lv!ti"a48 1#nt../9<08 1G m!tr ? s!lf.g!t1#ntR!tri"s small g.s!t(#l#r (#l#r.,&it! g.s!t1#nt small g.dra,+tring msg8 L;B60-F - m!tr.stringBidt&LmsgMM / 28 ;F26JF- / 2 Qtim!r.st# !nd

In the game% er method, we display IGame % erI message in the center of the window. (e also stop the timer.
d!f "&!"k@ l! l!_y

!nd

if $xV0W ?? Qa l!_x and $yV0W ?? Qa Qd#ts ? Qd#ts U 1 s!lf.l#"at!@ l! !nd

The "&!"k@ l! method chec!s, if the sna!e has hit the apple ob$ect. If so, we add another sna!e $oint and call the l#"at!@ l! method, which randomly places a new apple ob$ect. In the m#v! method we ha e the !ey algorithm of the game. To understand it, loo! at how the sna!e is mo ing. Cou control the head of the sna!e. Cou can change its direction with the cursor !eys. The rest of the $oints mo e one position up the chain. The second $oint mo es where the first was, the third $oint where the second was etc.
,&il! z O $xVzW $yVzW z ? z !nd 0 ? $xVLz - 1MW ? $yVLz - 1MW - 1

This code mo es the $oints up the chain.


if Ql!ft $xV0W -? 09-_+6'2 !nd

<o e the head to the left.

6>

In the "&!"k(#llisi#n method, we determine if the sna!e has hit itself or one of the walls.
,&il! z O 0 if z O G and $xV0W ?? $xVzW and $yV0W ?? $yVzW QinJam! ? fals! !nd z ? z - 1 !nd

"inish the game, if the sna!e hits one of its $oints with the head.
if $yV0W O ;F26JF- - 09-_+6'2 QinJam! ? fals! !nd

"inish the game, if the sna!e hits the bottom of the 'oard. The l#"at!@
l!

method locates an apple randomly on the board.

r ? rand *@;0_>9+

(e get a random number from B to R/&AO0%S 2 ).


Qa l!_x ? r T 09-_+6'2 ... Qa l!_y ? r T 09-_+6'2

These lines set the #, y coordinates of the apple ob$ect.


d!f a"ti#n>!rf#rm!d ! if QinJam! s!lf."&!"k@ l! s!lf."&!"k(#llisi#n s!lf.m#v! !nd s!lf.r! aint !nd

G ery AG;/C ms, the a"ti#n>!rf#rm!d method is called. If we are in the game, we call three methods, that build the logic of the game. In the k!y>r!ss!d method of the 'oard class, we determine the !eys that were pressed.
if k!y ?? Ql!ft Qu ? Qd#,n !nd K!y2v!nt..=K_<21- and n#t Qrig&t ? tru! fals! ? fals!

If we hit the left cursor !ey, we set Ql!ft ariable to true. This ariable is used in the m#v! method to change coordinates of the sna!e ob$ect. &otice also, that when the sna!e is heading to the right, we cannot turn immediately to the left. 6?

"lass 2xam l! 3 )1ram! d!f initializ! su !r 4;ibbl!s4 s!lf.init56 !nd d!f init56 b#ard ? /#ard.n!, b#ard.s!t>r!f!rr!d+iz! 0im!nsi#n.n!, ;B60-F8 ;F26JFs!lf.add b#ard s!lf. a"k s!lf.s!t*!sizabl! fals! s!lf.s!t0!fault(l#s!9 !rati#n )1ram!..2:6-_9;_(<9+2 s!lf.s!t<#"ati#n*!lativ!-# nil s!lf.s!t=isibl! tru! !nd !nd

In this class, we set up the &ibbles game.

"igure4 &ibbles This was the &ibbles computer game programmed with the Swing library and the JRuby programming language.

6@