Professional Documents
Culture Documents
The Java Swing Tutorial
The Java Swing Tutorial
com
First Programs
Swing Events
Swing Dialogs
Swing models
Drawing
Resizable component
Puzzle
Tetris
About Swing
Swing library is an official Java GUI toolkit released by Sun The !ain characteristics of the Swing toolkit platfor! independent custo!i"able extensible configurable lightweight icrosyste!s.
Swing consists of the following packages #avax.swing #avax.swing.border #avax.swing.colorchooser #avax.swing.event #avax.swing.filechooser #avax.swing.plaf #avax.swing.plaf.basic #avax.swing.plaf.!etal #avax.swing.plaf.!ulti #avax.swing.plaf.synth #avax.swing.table #avax.swing.text #avax.swing.text.ht!l
Created by dovari.sudheerkiran@gmail.com
Swing is probably the !ost advanced toolkit on this planet. It has a rich set of widgets. $ro! basic widgets like %uttons& Labels& Scrollbars to advanced widgets like Trees and Tables. Swing is written in '(() #ava. Swing is a part of J$*& Java $oundation *lasses. It is a collection of packages for creating full featured desktop applications. J$* consists of +,T& Swing& +ccessibility& Java -.& and .rag and .rop. Swing was released in '//0 with J.1 '.-. It is a !ature toolkit. The Java platfor! has Java-. library& which enables developers to create advanced -. graphics and i!aging. There are basically two types of widget toolkits. Lightweight 2eavyweight
+ heavyweight toolkit uses 3S4s +5I to draw the widgets. $or exa!ple %orland4s 6*L is a heavyweight toolkit. It depends on ,I78- +5I& the built in ,indows application progra!!ing interface. 3n Unix syste!s& we have GT19 toolkit& which is built on top of :'' library. Swing is a lightweight toolkit. It paints it4s own widgets. It is in fact the only lightweight toolkit I know about.
SWT library
There is also another GUI library for the Java progra!!ing language. It is called S,T. The Standard widget toolkit. The S,T library was initially developed by the I% corporation. 7ow it is an open source pro#ect& supported by I% . The S,T is an exa!ple of a heavyweight toolkit. It lets the underlying 3S to create GUI. S,T uses the #ava native interface to do the #ob. The !ain advantages of the S,T are speed and native look and feel. The S,T is on the other hand !ore error prone. It is less powerful then Swing. It is also ;uite ,indows centric library.
import javax.swing.JFrame;
public Simple() {
setSize(3
! "
);
set#itle($Simple$); set%e&ault'lose(peration()*+#,(-,'.(S)); /
Created by dovari.sudheerkiran@gmail.com
simple.set3isible(true);
/ /
,hile this code is very s!all& the application window can do ;uite a lot. It can be resi"ed& !axi!i"ed& !ini!i"ed. +ll the co!plexity that co!es with it has been hidden fro! the application progra!!er.
import javax.swing.JFrame; 2ere we i!port the J$ra!e widget. It is a toplevel container& which is used for placing other widgets.
setSize(3
! "
);
set#itle($Simple$); This code will resi"e the window to be 8((px wide and -((px tall. It will set the title of the window to Si!ple.
set%e&ault'lose(peration()*+#,(-,'.(S)); This !ethod will close the window& if we click on the close button. %y default nothing happens.
$igure< Si!ple
import javax.swing.JFrame;
public 'enter(nScreen() {
Created by dovari.sudheerkiran@gmail.com
setSize(3
! "
);
set#itle($'enter(nScreen$); set%e&ault'lose(peration()*+#,(-,'.(S));
#ool4it tool4it 2 get#ool4it(); %imension size 2 tool4it.getScreenSize(); set.ocation(size.widt56" 7 get8idt5()6"! size.5eig5t6" 7 get9eig5t()6"); /
/ /
To center the window on the screen& we !ust know the resolution of the !onitor. $or this& we use the Toolkit class.
%imension size 2 tool4it.getScreenSize(); ,e get the toolkit and figure out the screen si"e.
set.ocation(size.widt56" 7 get8idt5()6"! size.5eig5t6" 7 get9eig5t()6"); To place the window on the screen& we call the setLocation() !ethod.
Buttons
In our next exa!ple& we will show two buttons. The first button will beep a sound and the second button will close the window.
Created by dovari.sudheerkiran@gmail.com
public ;uttons() {
tool4it 2 get#ool4it(); %imension size 2 tool4it.getScreenSize(); set.ocation((size.widt5 7 get8idt5())6"! (size.5eig5t 7 get9eig5t())6"); set%e&ault'lose(peration()*+#,(-,'.(S));
panel.set.a=out(null);
J;utton beep 2 new J;utton($;eep$); beep.set;ounds(>? ! @ ! A ! 3 ); beep.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { tool4it.beep();
/ /);
J;utton close 2 new J;utton($'lose$); close.set;ounds(? ! @ ! A ! 3 ); close.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { S=stem.exit( ); / /);
panel.add(beep); panel.add(close);
Created by dovari.sudheerkiran@gmail.com
/ /
In this exa!ple& we will see two new topics. Layout !anage!ent and event handling. They will be touched only briefly. %oth of the topics will have their own chapter.
get'ontent<ane().add(panel); ,e create a JPanel co!ponent. It is a generic lightweight container. ,e add the J5anel to the J$ra!e.
panel.set.a=out(null); %y default& the J5anel has a FlowLayout !anager. The layout !anager is used to place widgets onto the containers. If we call setLayout(null) we can position our co!ponents absolutely. $or this& we use the setBounds() !ethod.
beep.set;ounds(>? ! @ ! A ! 3 );
beep.add:ction.istener(new :ction.istener() {
tool4it.beep();
/);
2ere we create a button. ,e position it by calling the setBounds() !ethod. Then we add an action listener. The action listener will be called& when we perfor! an action on the button. In our case& if we click on the button. The beep button will play a si!ple beep sound.
S=stem.exit( ); The close button will exit the application. $or this& we call the System.exit() !ethod.
panel.add(beep);
panel.add(close); In order to show the buttons& we !ust add the! to the panel.
$igure< %uttons
A tooltip
Tooltips are part of the internal application4s help syste!. The Swing shows a s!all rectangular window& if we hover a !ouse pointer over an ob#ect.
Created by dovari.sudheerkiran@gmail.com
public #ooltip() {
tool4it 2 get#ool4it(); %imension size 2 tool4it.getScreenSize(); set.ocation((size.widt5 7 get8idt5())6"! (size.5eig5t 7 get9eig5t())6"); set%e&ault'lose(peration()*+#,(-,'.(S));
get'ontent<ane().add(panel);
panel.add(button);
/ /
Created by dovari.sudheerkiran@gmail.com
In the exa!ple& we set the tooltip for the fra!e and the button.
$igure< Tooltip
Si!ple !enubar
,e begin with a si!ple !enubar exa!ple.
pac4age com.zetcode;
import javax.swing.+mage+con; import javax.swing.JFrame; import javax.swing.JCenu; import javax.swing.JCenu;ar; import javax.swing.JCenu+tem;
public Cenu() {
set#itle($JCenu;ar$);
Created by dovari.sudheerkiran@gmail.com
JCenu+tem &ile'lose 2 new JCenu+tem($'lose$! icon); &ile'lose.setCnemonic(Be=)vent.3B,'); &ile'lose.set#ool#ip#ext($)xit application$); &ile'lose.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { S=stem.exit( ); /
/);
&ile.add(&ile'lose);
menubar.add(&ile);
setJCenu;ar(menubar);
setSize("? ! "
);
new Cenu();
/ /
3ur exa!ple will show a !enu with one ite!. Selecting the close !enu ite! we close the application.
&ile.setCnemonic(Be=)vent.3B,F); ,e create a !enu ob#ect. The !enus can be accessed via the keybord as well. To bind a !enu to a particular key& we use the setMnemonic !ethod. In our case& the !enu can be opened with the A!T " # shortcut.
Created by dovari.sudheerkiran@gmail.com
&ile'lose.set#ool#ip#ext($)xit application$); This code line creates a tooltip for a !enu ite!.
$igure< J enu%ar
Sub!enu
=ach !enu can also have a sub!enu. This way we can group si!ilar co!!nads into groups. $or exa!ple we can place co!!ands that hide>show various toolbars like personal bar& address bar& status bar or navigation bar into a sub!enu called toolbars. ,ithin a !enu& we can seperate co!!ands with a separator. It is a si!ple line. It is co!!on practice to separate co!!ands like new& open& save fro! co!!ands like print& print preview with a single separator. enus co!!ands can be launched via keyboard shortcuts. $or this& we define !enu ite! accelerators.
import javax.swing.+mage+con;
import javax.swing.JFrame; import javax.swing.JCenu; import javax.swing.JCenu;ar; import javax.swing.JCenu+tem; import javax.swing.Be=Stro4e;
public Submenu() {
set#itle($Submenu$);
JCenu;ar menubar 2 new JCenu;ar(); +mage+con icon-ew 2 new +mage+con($new.png$); +mage+con icon(pen 2 new +mage+con($open.png$); +mage+con iconSave 2 new +mage+con($save.png$); +mage+con icon'lose 2 new +mage+con($exit.png$);
Created by dovari.sudheerkiran@gmail.com
JCenu+tem news& 2 new JCenu+tem($+mport news&eed list...$); JCenu+tem boo4m 2 new JCenu+tem($+mport boo4mar4s...$); JCenu+tem mail 2 new JCenu+tem($+mport mail...$);
JCenu+tem &ile'lose 2 new JCenu+tem($'lose$! icon'lose); &ile'lose.setCnemonic(Be=)vent.3B,'); &ile'lose.set#ool#ip#ext($)xit application$); &ile'lose.set:ccelerator(Be=Stro4e.getBe=Stro4e(Be=)vent.3B,8! :ction)vent.'#D.,C:SB));
/);
Created by dovari.sudheerkiran@gmail.com
menubar.add(&ile);
setJCenu;ar(menubar);
public static void main(String01 args) { new Submenu(); / / In this exa!ple& we create a sub!enu& a !enu separator and an accelerator key.
...
&ile.add(imp); + sub!enu is #ust like any other nor!al !enu. It is created the sa!e way. ,e si!ply add a !enu to existing !enu.
&ile'lose.set:ccelerator(Be=Stro4e.getBe=Stro4e(Be=)vent.3B,8!
:ction)vent.'#D.,C:SB)); +n accelerator is a key shortcut that launches a !enu ite!. In our case& by pressing Ctrl " W we close the application.
&ile.addSeparator(); + separator is a vertical line that visually separates the !enu ite!s. This way we can group ite!s into so!e logical places.
$igure< Sub!enu
J*heck%ox enuIte!
+ !enu ite! that can be selected or deselected. If selected& the !enu ite! typically appears with a check!ark next to it. If unselected or deselected& the !enu ite! appears without a check!ark. Like a regular !enu ite!& a check box !enu ite! can have either text or a graphic icon associated with it& or both.
Created by dovari.sudheerkiran@gmail.com
import java.awt.event.Be=)vent;
import javax.swing.;orderFactor=; import javax.swing.J'5ec4;oxCenu+tem; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.JCenu; import javax.swing.JCenu;ar; import javax.swing.E+Canager; import javax.swing.border.)tc5ed;order;
public '5ec4Cenu+tem() {
set#itle($'5ec4;oxCenu+tem$);
sbar.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { i& (statusbar.is3isible()) { statusbar.set3isible(&alse); / else { statusbar.set3isible(true); / /
/);
Created by dovari.sudheerkiran@gmail.com
view.add(sbar);
menubar.add(&ile); menubar.add(view);
setJCenu;ar(menubar);
/ / The exa!ple shows a JChec$BoxMenu tem%. %y selecting the !enu ite!& we toggle the visibility of the statusbar.
sbar.setState(true); ,e create the JChec$BoxMenu tem and check it by default. The statusbar is initially visible.
i& (statusbar.is3isible()) {
statusbar.set3isible(&alse);
/ else {
statusbar.set3isible(true);
statusbar.set;order(;orderFactor=.create)tc5ed;order()tc5ed;order.D:+S)%)); The statusbar is a si!ple J!abel co!ponent. ,e put a raised &tchedBorder around the label& so that it is discernible.
Created by dovari.sudheerkiran@gmail.com
+ popup !enu
+nother type of a !enu is a popup !enu. It is so!eti!es called a context !enu. It is usually shown& when we right click on a co!ponent. The idea is to provide only the co!!ands& that are relevant to the current context. Say we have an i!age. %y right clicking on the i!age& we get a window with co!!ands to save& rescale& !ove etc the i!age.
import java.awt.#ool4it;
public <opupCenu(){
tool4it 2 &rame.get#ool4it();
menu.add(menu+tem;eep);
Created by dovari.sudheerkiran@gmail.com
JCenu+tem menu+tem'lose 2 new JCenu+tem($'lose$); menu+tem'lose.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent e) { S=stem.exit( ); /
/);
menu.add(menu+tem'lose);
&rame.addCouse.istener(new Couse:dapter() { public void mouseDeleased(Couse)vent e) { i& (e.get;utton() 22 e.;E##(-3) { menu.s5ow(e.get'omponent()! e.get*()! e.getG()); / / /);
&rame.setSize("? ! "
);
&rame.set.ocationDelative#o(null);
&rame.set3isible(true); /
public static void main(String01 args) { new <opupCenu(); / / 3ur exa!ple shows a de!onstrational popup !enu with two co!!ands. The first option of the popup !enu will beep a sound& the second one will close the window. In our exa!ple& we create a sub!enu& !enu separators and create an accelerator key.
menu 2 new J<opupCenu(); To create a popup !enu& we have a class called J'opupMenu.
JCenu+tem menu+tem;eep 2 new JCenu+tem($;eep$); The !enu ite! is the sa!e& as with the standard JMenu
&rame.addCouse.istener(new Couse:dapter() {
Created by dovari.sudheerkiran@gmail.com
/); The popup !enu is shown& where we clicked with the !ouse button. The B(TTO)* constant is here to enable the popup !enu only for the !ouse right click.
JToolbar
enus group co!!ands that we can use in an application. Toolbars provide a ;uick access to the !ost fre;uently used co!!ands. In Java Swing& the JToolBar class creates a toolbar in an application.
public Simple#oolbar() {
set#itle($Simple#oolbar$);
JCenu;ar menubar 2 new JCenu;ar(); JCenu &ile 2 new JCenu($File$); menubar.add(&ile); setJCenu;ar(menubar);
Created by dovari.sudheerkiran@gmail.com
J;utton exit 2 new J;utton(icon); toolbar.add(exit); exit.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { S=stem.exit( ); /
/);
add(toolbar! ;order.a=out.-(D#9);
setSize(3
! "
);
public static void main(String01 args) { new Simple#oolbar(); / / The exa!ple creates a toolbar with one exit button.
Toolbars
Say& we wanted to create two toolbars. The next exa!ple shows& how we could do it.
import java.awt.;order.a=out;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.;ox.a=out; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.J#ool;ar;
public #oolbars() {
set#itle($#oolbars$);
+mage+con newi 2 new +mage+con( get'lass().getDesource($new.png$)); +mage+con open 2 new +mage+con( get'lass().getDesource($open.png$)); +mage+con save 2 new +mage+con( get'lass().getDesource($save.png$)); +mage+con exit 2 new +mage+con( get'lass().getDesource($exit.png$));
J;utton newb 2 new J;utton(newi); J;utton openb 2 new J;utton(open); J;utton saveb 2 new J;utton(save);
Created by dovari.sudheerkiran@gmail.com
toolbar".add(exitb); toolbar".set:lignment*( );
/);
panel.add(toolbar>); panel.add(toolbar");
add(panel! ;order.a=out.-(D#9);
setSize(3
! "
);
public static void main(String01 args) { new #oolbars(); / / ,e show only one way& how we could create toolbars. 3f course& there are several possibilities. ,e put a J'anel to the north of the Border!ayout !anager. The panel has a vertical Box!ayout. ,e add the two toolbars into this panel.
panel.add(toolbar>);
panel.add(toolbar");
add(panel! ;order.a=out.-(D#9); ,e add the toolbars to the panel. $inally& the panel is located into the north part of the fra!e.
Created by dovari.sudheerkiran@gmail.com
$igure< Toolbars
A vertical toobar
The following exa!ple shows a vertical toobar.
import java.awt.;order.a=out;
import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J#ool;ar; import javax.swing.E+Canager;
public 3ertical#oolbar() {
set#itle($3ertical toolbar$);
+mage+con select 2 new +mage+con( get'lass().getDesource($select.gi&$)); +mage+con &ree5and 2 new +mage+con( get'lass().getDesource($&ree5and.gi&$)); +mage+con s5apeed 2 new +mage+con( get'lass().getDesource($s5apeed.gi&$)); +mage+con pen 2 new +mage+con( get'lass().getDesource($pen.gi&$)); +mage+con rectangle 2 new +mage+con( get'lass().getDesource($rectangle.gi&$)); +mage+con ellipse 2 new +mage+con( get'lass().getDesource($ellipse.gi&$)); +mage+con Hs 2 new +mage+con( get'lass().getDesource($Hs.gi&$));
Created by dovari.sudheerkiran@gmail.com
J;utton selectb 2 new J;utton(select); J;utton &ree5andb 2 new J;utton(&ree5and); J;utton s5apeedb 2 new J;utton(s5apeed); J;utton penb 2 new J;utton(pen); J;utton rectangleb 2 new J;utton(rectangle); J;utton ellipseb 2 new J;utton(ellipse); J;utton Hsb 2 new J;utton(Hs); J;utton textb 2 new J;utton(text);
add(toolbar! ;order.a=out.8)S#);
public static void main(String01 args) { tr= { E+Canager.set.oo4:ndFeel( E+Canager.getS=stem.oo4:ndFeel'lass-ame()); / catc5 ()xception e) { S=stem.out.println($)rrorI$ J e.getStac4#race()); / new 3ertical#oolbar(); / / In the exa!ple& we put a vertical toolbar to the left side of the window. This is typical for a graphics applications like+ara &xtreme or n$scape. In our exa!ple& we use icons fro! :ara =xtre!e application.
Created by dovari.sudheerkiran@gmail.com
add(toolbar! ;order.a=out.8)S#); The toolbar is placed into the left part of the window.
E+Canager.set.oo4:ndFeel(
E+Canager.getS=stem.oo4:ndFeel'lass-ame()); I used the syste! look and feel. In !y case& it was the gtk the!e. The icons are not transparent& and they would not look ok on a different the!e.
The Java Swing toolkit has two kind of co!ponents. *ontainers and children. The containers group children into suitable layouts. To create layouts& we use layout managers. Layout !anagers are one of the !ost difficult parts of !odern GUI progra!!ing. progra!!ers have too !uch respect for layout !anagers. poorly docu!ented. I believe& that GUI builder4s like understanding of layout !anagers. ?et*ode offers a dedicated '/@ pages eAbook for the Swing layout !anage!ent process< Java Swing layout !anage!ent tutorial any beginning ainly because they are usually
)o manager
,e can use no layout !anager& if we want. There !ight be situations& where we !ight not need a layout !anager. $or exa!ple& in !y code exa!ples& I often go without a !anager. It is because I did not want to !ake the exa!ples too co!plex. %ut to create truly portable& co!plex applications& we need layout !anagers. ,ithout layout !anager& we position co!ponents using absolute values.
public :bsolute() {
set#itle($:bsolute positioning$);
Created by dovari.sudheerkiran@gmail.com
set.a=out(null);
add(o4); add(close);
setSize(3
! "? );
o4.set;ounds(? ! >? ! A ! "?); The setBounds,- !ethod positions the ok button. The para!eters are the x& y location values and the width and height of the co!ponent.
#low!ayout manager
This is the si!plest layout !anager in the Java Swing toolkit. It is !ainly used in co!bination with other layout !anagers. ,hen calculating it4s children si"e& a flow layout lets each co!ponent assu!e its natural BpreferredC si"e. The !anager puts co!ponents into a row. In the order& they were added. If they do not fit into one row& they go into the next one. The co!ponents can be added fro! the right to the left or vice versa. The !anager allows to align the co!ponents. I!plicitly& the co!ponents are centered and there is Dpx space a!ong co!ponents and co!ponents and the edges of the container.
Flow.a=out() Flow.a=out(int align) Flow.a=out(int align! int 5gap! int vgap) There are three constructors available for the $lowLayout !anager. The first one creates a !anager with i!plicit values. *entered and Dpx spaces. The others allow to specify those para!etes.
import java.awt.%imension;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.J#ext:rea; import javax.swing.J#ree;
public Flow.a=out)xample() {
set#itle($Flow.a=out )xample$);
panel.add(button);
panel.add(area);
add(panel);
pac4();
Created by dovari.sudheerkiran@gmail.com
The exa!ple shows a button& a tree and a text area co!ponent in the window. Interesingly& if we create an e!pty tree co!ponent& there are so!e default values inside the co!ponent.
J<anel panel 2 new J<anel(); The i!plicit layout !anager of the J'anel co!ponent is a flow layout !anager. ,e do not have to set it !anually.
area.set<re&erredSize(new %imension(>
! >
));
The flow layout !anager sets a preferred si"e for it4s co!ponents. This !eans& that in our case& the area co!ponent will have '((x'(( px. If we didn4t set the preferred si"e& the co!ponent would have a si"e of it4s text. 7o !ore& no less. ,ithout the text& the co!ponent would not be visible at all. Try to write or delete so!e text in the area co!ponent. The co!ponent will grow and shrink accordingly.
panel.add(area); To put a co!ponent inside a container& we si!ply call the add,- !ethod.
.rid!ayout
The .rid!ayout layout !anager lays out co!ponents in a rectangular grid. The container is divided into e;ually si"ed rectangles. 3ne co!ponent is placed in each rectangle.
import java.awt.Krid.a=out;
import javax.swing.;orderFactor=; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel;
public Krid.a=out)xample() {
set#itle($Krid.a=out$);
String01 buttons 2 { $'ls$! $;c4$! $$! $'lose$! $M$! $A$! $N$! $6$! $L$!
Created by dovari.sudheerkiran@gmail.com
$?$! $@$! $F$! $>$! $"$! $3$! $7$! $ $! $.$! $2$! $J$ /;
&or (int i 2
; i O buttons.lengt5; iJJ) {
add(panel);
setSize(3? ! 3
);
public static void main(String01 args) { new Krid.a=out)xample(); / / The exa!ple shows a skeleton of a si!ple calculator tool. It is an ideal exa!ple for this layout !anager. ,e put '/ buttons and one label into the !anager. 7otice& that each button is of the sa!e si"e.
panel.set.a=out(new Krid.a=out(?! L! ?! ?)); 2ere we set the grid layout !anager for the panel co!ponent. The layout !anager takes four para!eters. The nu!ber of rows& the nu!ber of colu!ns and the hori"ontal and vertical gaps between co!ponents.
Border!ayout
Created by dovari.sudheerkiran@gmail.com
+ Border!ayout !anager is a very handy layout !anager. I haven4t seen it elsewhere. It divides the space into five regions. 7orth& ,est& South& =ast and *entre. =ach region can have only one co!ponent. If we need to put !ore co!ponents into a region& we can si!ply put a panel there with a !anager of our choice. The co!ponents in 7& ,& S& = regions get their preferred si"e. The co!ponent in the centre takes up the whole space left. It does not look good& if child co!ponents are too close to each other. ,e !ust put so!e space a!ong the!. =ach co!ponent in Swing toolkit can have borders around it4s edges. To create a border& we either create a new instance of an &mptyBorder class or we use a Border#actory. =xcept for =!pty%order& there are other types of borders as well. %ut for layout !anage!ent we will use only this one.
public ;order)xample() {
set#itle($;order )xample$);
add(panel);
pac4();
Created by dovari.sudheerkiran@gmail.com
public static void main(String01 args) { new ;order)xample(); / / The exa!ple will display a gray panel and border around it.
J<anel top 2 new J<anel(); ,e place a panel into a panel. ,e used a Border!ayout !anager for the first panel& because this !anager will resi"e it4s children.
panel.add(top); 2ere we placed a top panel into the panel co!ponent. center area of theBorder!ayout !anager. ore precisely& we placed into the
panel.set;order(new )mpt=;order(new +nsets(" ! " ! " ! " ))); 2ere we created a -(px border around the panel. The border values are as follows< top& left& botto! and right. They go counterclockwise.
The next exa!ple will show a typical usage of a border layout !anager.
import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.JCenu; import javax.swing.JCenu;ar; import javax.swing.J#ext:rea; import javax.swing.J#ool;ar; import javax.swing.border.)mpt=;order; import javax.swing.border..ine;order;
public ;order.a=out)xample() {
Created by dovari.sudheerkiran@gmail.com
set#itle($;order.a=out$);
menubar.add(&ile); setJCenu;ar(menubar);
+mage+con exit 2 new +mage+con($exit.png$); J;utton bexit 2 new J;utton(exit); bexit.set;order(new )mpt=;order( toolbar.add(bexit); ! ! ! ));
add(toolbar! ;order.a=out.-(D#9);
+mage+con select 2 new +mage+con($drive.png$); +mage+con &ree5and 2 new +mage+con($computer.png$); +mage+con s5apeed 2 new +mage+con($printer.png$);
J;utton &ree5andb 2 new J;utton(&ree5and); &ree5andb.set;order(new )mpt=;order(3! J;utton s5apeedb 2 new J;utton(s5apeed); s5apeedb.set;order(new )mpt=;order(3! ! 3! )); ! 3! ));
add(vertical! ;order.a=out.8)S#);
Created by dovari.sudheerkiran@gmail.com
J.abel statusbar 2 new J.abel($ Statusbar$); statusbar.set<re&erredSize(new %imension(7>! "")); statusbar.set;order(.ine;order.createKra=.ine;order()); add(statusbar! ;order.a=out.S(E#9);
setSize(3? ! 3
);
public static void main(String01 args) { new ;order.a=out)xample(); / / The exa!ple shows a typical application skeleton. ,e show a vertical and hori"ontal toolbars& a statusbar and a central co!ponent. Ba text areaC + default layout !anager for a J#rame co!ponent is Border!ayout !anager. So we don4t have to set it.
add(toolbar! ;order.a=out.-(D#9);
Box!ayout
%oxLayout is a powerful !anager& that can be used to create sofisticated layouts. This layout !anager puts co!ponents into a row or into a colu!n. It enables nesting& a powerful feature& that !akes this !anager very flexible. It !eans& that we can put a box layout into another box layout.
Created by dovari.sudheerkiran@gmail.com
The box layout !anager is often used with the Box class. This class creates several invisible co!ponents& which affect the final layout. glue strut rigid area
Let4s say& we want to put two buttons into the right botto! corner of the window. ,e will use the boxlayut !anagers to acco!plish this.
import java.awt.%imension;
import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel;
public #wo;uttons() {
set#itle($#wo ;uttons$);
basic.add(;ox.create3erticalKlue());
Created by dovari.sudheerkiran@gmail.com
setSize(3
! "? );
public static void main(String01 args) { new #wo;uttons(); / / The following drawing illustrates the exa!ple.
$igure< Two buttons ,e will create two panels. The basic panel has a vertical box layout. The botto! panel has a hori"ontal one. ,e will put a botto! panel into the basic panel. ,e will right align the
botto! panel. The space between the top of the window and the botto! panel is expandable. It is done by the vertical glue.
basic.set.a=out(new ;ox.a=out(basic! ;ox.a=out.G,:*+S)); 2ere we create a basic panel with the vertical Box!ayout.
bottom.set:lignment*(>&);
bottom.set.a=out(new ;ox.a=out(bottom! ;ox.a=out.*,:*+S)); The botto! panel is right aligned. This is done by the setAlignment+,- !ethod. The panel has a hori"ontal layout.
)));
basic.add(bottom); 2ere we put the botto! panel with a hori"ontal box layout to the vertical basic panel.
basic.add(;ox.createDigid:rea(new %imension( ! >?))); ,e also put so!e space between the botto! panel and the border of the window.
Created by dovari.sudheerkiran@gmail.com
$igure< Two buttons ,hen we use a Box!ayout !anager& we can set a rigid area a!ong our co!ponents.
import java.awt.%imension;
import java.awt.+nsets;
import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.border.)mpt=;order;
public Digid:rea() {
set#itle($Digid:rea$);
panel.add(new J;utton($;utton$)); panel.add(;ox.createDigid:rea(new %imension( ! ?))); panel.add(new J;utton($;utton$)); panel.add(;ox.createDigid:rea(new %imension( ! ?))); panel.add(new J;utton($;utton$)); panel.add(;ox.createDigid:rea(new %imension( ! ?))); panel.add(new J;utton($;utton$));
add(panel);
pac4();
Created by dovari.sudheerkiran@gmail.com
public static void main(String01 args) { new Digid:rea(); / / In this exa!ple& we display four buttons. %y default& there is no space a!ong the buttons. To put so!e space a!ong the!& we add so!e rigid area.
panel.set.a=out(new ;ox.a=out(panel! ;ox.a=out.G,:*+S)); ,e use a vertical Box!ayout !anager for our panel.
panel.add(new J;utton($;utton$));
panel.add(new J;utton($;utton$)); ,e add buttons and create a rigid area in between the!.
$igure< Tip of the .ay ,e will create a si!ilar dialog. ,e will use a co!bination of various layout !anagers. 7a!ely a border layout& flow layout and box layout !anager.
import java.awt.;order.a=out; import java.awt.'olor; import java.awt.%imension; import java.awt.Flow.a=out; import java.awt.event.Be=)vent;
import javax.swing.;orderFactor=;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.;ox.a=out; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.J'5ec4;ox; import javax.swing.J%ialog; import javax.swing.J.abel; import javax.swing.J<anel; import javax.swing.JSeparator; import javax.swing.J#ext<ane;
public #ip(&%a=() {
));
J.abel 5int 2 new J.abel($J%eveloper <roductivit= 9ints$); 5int.set;order(;orderFactor=.create)mpt=;order( ! "?! top<anel.add(5int); ! ));
+mage+con icon 2 new +mage+con($jdev.png$); J.abel label 2 new J.abel(icon); label.set;order(;orderFactor=.create)mpt=;order(?! ?! ?! ?)); top<anel.add(label! ;order.a=out.):S#);
top<anel.add(separator! ;order.a=out.S(E#9);
basic.add(top<anel);
Created by dovari.sudheerkiran@gmail.com
"?));
pane.set'ontent#=pe($text65tml$); String text 2 $OpPObP'losing windows using t5e mouse w5eelO6bPO6pP$ J $OpP'lic4ing wit5 t5e mouse w5eel on an editor tab closes t5e
window. $ J
$#5is met5od wor4s also wit5 doc4able windows or .og window tabs.O6pP$; pane.set#ext(text); pane.set)ditable(&alse); text<anel.add(pane);
basic.add(text<anel);
));
box<anel.add(box);
basic.add(box<anel);
J;utton ntip 2 new J;utton($-ext #ip$); ntip.setCnemonic(Be=)vent.3B,-); J;utton close 2 new J;utton($'lose$); close.setCnemonic(Be=)vent.3B,');
bottom.setCaximumSize(new %imension(L? !
));
Created by dovari.sudheerkiran@gmail.com
public static void main(String01 args) { new #ip(&%a=(); / / The exa!ple uses a !ix of layout !anagers. Si!ply we put four panels into the vertically organi"ed basic panel.
add(basic); This is the very botto! panel. It has a vertical box layout !anager. The basic panel is added to the default J/ialogco!ponent. This co!ponent has a border layout !anager by default.
));
The top5anel panel has a border layout !anager. ,e will put three co!ponents into it. Two labels and a separator.
top<anel.setCaximumSize(new %imension(L? !
));
If we want to have a panel& that is not greater than it4s co!ponents& we !ust set it4s !axi!u! si"e. The "ero value is ignored. The !anager calculates the necessary heights.
...
text<anel.add(pane);
The text pane co!ponent is added to the center area of the border layout !anager. It takes all space left. =xactly& as we wanted.
));
The check box is shown in the box5anel panel. It is left aligned. The flow layout !anager has a -(px hori"ontal gap. 3ther co!ponents have -Dpx. ,hy is thatF It is because the flow layout !anager puts so!e space to between the co!ponent and the edge as well.
...
bottom.setCaximumSize(new %imension(L? !
));
The botto! panel displays two buttons. It has a right aligned flow layout !anager. In order to show the buttons on the right edge of the dialog& the panel !ust stretch hori"ontally fro! the beginning to the end.
The &0ent source is the ob#ect whose state changes. It generates =vents. The &0ent ob1ect B=ventC encapsulates the state changes in the event source. The &0ent listener is the ob#ect that wants to be notified. =vent source ob#ect delegates the task of handling an event to the event listener.
Created by dovari.sudheerkiran@gmail.com
=vent handling in Java Swing toolkit is very powerful and flexible. Java uses =vent .elegation occurs. odel. ,e specify the ob#ects that are to be notified when a specific event
+n event ob#ect
,hen so!ething happens in the application& an event ob#ect is created. $or exa!ple& when we click on the button or select an ite! fro! list. There are several types of events. +n Action&0ent& Text&0ent& #ocus&0ent&Component&0ent etc. =ach of the! is created under specific conditions. =vent ob#ect has infor!ation about an event& that has happened. In the next exa!ple& we will analy"e an Action&0entin !ore detail.
import java.text.%ateFormat;
import javax.swing.J<anel;
public )vent(bject() {
set#itle($)vent (bject$);
Created by dovari.sudheerkiran@gmail.com
.ocale locale 2 .ocale.get%e&ault(); %ate date 2 new %ate(); String s 2 %ateFormat.get#ime+nstance(%ateFormat.S9(D#! locale).&ormat(date);
model.add)lement(bu&&er); / /);
panel.add(o4);
Created by dovari.sudheerkiran@gmail.com
panel.add(list); add(panel);
public static void main(String01 args) { new )vent(bject(); / / The code exa!ple shows a button and a list. If we click on the button& infor!ation about the event is displayed in the list. In our case& we are talking about an Action&0ent class. The data will be the ti!e& when the event occured& the id of the event& the event source and the !odifier keys.
public void action<er&ormed(:ction)vent event) { Inside the action listener& we have an event para!eter. It is the instance of the event& that has occured. In our case it is an Action&0ent.
cal.set#ime+nCillis(event.get85en()); 2ere we get the ti!e& when the event occured. The !ethod returns ti!e value in !illiseconds. So we !ust for!at it appropriately.
model.add)lement($ SourceI $ J source); 2ere we add the na!e of the source of the event to the list. In our case the source is a JButton.
int mod 2 event.getCodi&iers(); ,e get the !odifier keys. It is a bitwiseAor of the !odifier constants.
I!ple!entation
There are several ways& how we can i!ple!ent event handling in Java Swing toolkit. +nony!ous inner class Inner class .erived class
public Simple)vent() {
set#itle($Simle )vent$);
close.set;ounds(L ! ? ! A ! "?);
/);
panel.add(close); add(panel);
setSize(3
! "
);
Created by dovari.sudheerkiran@gmail.com
/ In this exa!ple& we have a button that closes the window upon clicking.
J;utton close 2 new J;utton($'lose$); The button is the e0ent source. It will generate events.
close.add:ction.istener(new :ction.istener() {
S=stem.exit( );
/); 2ere we register an action listener with the button. This way& the events are sent to the e0ent target. The event target in our case is Action!istener class. In this code& we use an anonymous inner class.
Inner class
2ere we i!ple!ent the exa!ple using an inner Action!istener class.
public +nner'lass() {
panel.add(close); add(panel);
setSize(3
! "
);
set.ocationDelative#o(null);
Created by dovari.sudheerkiran@gmail.com
set%e&ault'lose(peration()*+#,(-,'.(S)); set3isible(true); /
S=stem.exit( );
public Esing+nter&ace() {
Created by dovari.sudheerkiran@gmail.com
panel.add(close); add(panel);
setSize(3
! "
);
add:ction.istener(t5is); /
public static void main(String01 args) { new Esing+nter&ace(); / / In this exa!ple& we create a y%utton class& which will i!ple!ent the action listener.
C=;utton close 2 new C=;utton($'lose$); 2ere we create the y%utton custo! class.
class C=;utton extends J;utton implements :ction.istener { The class. y%utton class is extended fro! the JButton class. It i!ple!ents y%utton the Action!istener interface. This way& the event handling is !anaged within the
import javax.swing.;orderFactor=; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel; import javax.swing.border.)tc5ed;order;
J.abel statusbar;
public CultipleSources() {
set#itle($Cultiple Sources$); J<anel panel 2 new J<anel(); statusbar 2 new J.abel($ Set'ode$);
statusbar.set;order(;orderFactor=.create)tc5ed;order( )tc5ed;order.D:+S)%));
panel.set.a=out(null);
Created by dovari.sudheerkiran@gmail.com
setSize(L
! 3
);
J;utton o 2 (J;utton) e.getSource(); String label 2 o.get#ext(); statusbar.set#ext($ $ J label J $ button clic4ed$); / /
public static void main(String01 args) { new CultipleSources(); / / ,e create four buttons and a statusbar. The statusbar will display an infor!ative !essage upon clicking on the button.
close.add:ction.istener(new ;utton.istener());
...
open.add:ction.istener(new ;utton.istener());
Created by dovari.sudheerkiran@gmail.com
$igure<
ultiple Sources
ultiple listeners
,e can register several listeners for one event.
import java.util.'alendar;
import javax.swing.;orderFactor=;
import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel; import javax.swing.JSpinner; import javax.swing.SpinnerCodel; import javax.swing.Spinner-umberCodel; import javax.swing.border.)tc5ed;order;
private J.abel statusbar; private JSpinner spinner; private static int count 2 ;
public Cultiple.isteners() {
set#itle($Cultiple .isteners$); J<anel panel 2 new J<anel(); statusbar 2 new J.abel($ $);
Created by dovari.sudheerkiran@gmail.com
statusbar.set;order(;orderFactor=.create)tc5ed;order( )tc5ed;order.D:+S)%));
panel.set.a=out(null);
J;utton add 2 new J;utton($J$); add.set;ounds(L ! 3 ! A ! "?); add.add:ction.istener(new ;utton.istener>()); add.add:ction.istener(new ;utton.istener"());
spinner.set;ounds(>N ! 3 ! A ! "?);
panel.add(add); panel.add(spinner);
setSize(3
! "
);
class ;utton.istener> implements :ction.istener { public void action<er&ormed(:ction)vent e) { +nteger val 2 (+nteger) spinner.get3alue(); spinner.set3alue(JJval); /
Created by dovari.sudheerkiran@gmail.com
public static void main(String01 args) { new Cultiple.isteners(); / / In this exa!ple& we have a button& spinner and a statusbar. ,e use two button listeners for one event. 3ne click of a button will add one year to the spinner co!ponent and update the statusbar. The statusbar will show& how !any ti!es we have clicked on the button.
add.add:ction.istener(new ;utton.istener>());
currentGear 7 >
currentGear J >
>);
spinner 2 new JSpinner(=earCodel); 2ere we create the spinner co!ponent. ,e use a year !odel for the spinner. The Spinner)umberModel argu!ents are initial value& !in& !ax values and the step.
$igure<
ultiple Listeners
Ee!oving listeners
The Java Swing toolkit enables us to re!ove the registered listeners.
Created by dovari.sudheerkiran@gmail.com
import javax.swing.J;utton; import javax.swing.J'5ec4;ox; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel;
private J.abel text; private J;utton add; private J'5ec4;ox active; private ;utton.istener buttonlistener; private static int count 2 ;
public Demove.istener() {
set#itle($Demove listener$);
panel.set.a=out(null);
active.add+tem.istener(new +tem.istener() { public void itemState'5anged(+tem)vent event) { i& (active.isSelected()) { add.add:ction.istener(buttonlistener);/ else { add.remove:ction.istener(buttonlistener); / / /);
Created by dovari.sudheerkiran@gmail.com
add(panel);
setSize(3> ! "
);
public static void main(String01 args) { new Demove.istener(); / / ,e have three co!ponents on the panel. + button& check box and a label. %y toggling the check box& we add or re!ove the listener for a button.
buttonlistener 2 new ;utton.istener(); ,e have to create a non anony!ous listener& if we want to later re!ove it. ,e need a reference to it.
i& (active.isSelected()) {
add.add:ction.istener(buttonlistener);/
else {
add.remove:ction.istener(buttonlistener);
/ ,e deter!ine& whether the check box is selected. Then we add or re!ove the listener.
Created by dovari.sudheerkiran@gmail.com
oving a window
The following exa!ple will look for a position of a window on the screen.
public Coving8indow() {
set#itle($Coving window$);
labelx 2 new J.abel($xI $); labelx.setFont(new Font($Seri&$! Font.;(.%! >L)); labelx.set;ounds(" ! " ! @ ! "?);
label= 2 new J.abel($=I $); label=.setFont(new Font($Seri&$! Font.;(.%! >L)); label=.set;ounds(" ! L?! @ ! "?);
panel.add(labelx); panel.add(label=);
Created by dovari.sudheerkiran@gmail.com
add(panel);
add'omponent.istener(t5is);
setSize(3> ! "
);
public void componentCoved('omponent)vent e) { int x 2 e.get'omponent().get*(); int = 2 e.get'omponent().getG(); labelx.set#ext($xI $ J x); label=.set#ext($=I $ J =); /
public static void main(String01 args) { new Coving8indow(); / / The exa!ple shows the current window coordinates on the panel. To get the window position& we use theComponent!istener
labelx.setFont(new Font($Seri&$! Font.;(.%! >L)); ,e !ake the font bigger& the default one is a bit s!all.
int x 2 e.get'omponent().get*();
int = 2 e.get'omponent().getG(); 2ere we get the x and the y positions. 7otice& that we have to i!ple!ent all four !ethods& that are available in the Component!istener. =ven& if we do not use the!.
Created by dovari.sudheerkiran@gmail.com
$igure<
oving a window
+dapters
+dapters are convenient classes. In the previous code exa!ple& we had to i!ple!ent all four !ethods of aComponent!istener class. =ven if we did not use the!. To avoid unnecessary coding& we can use adapters. +dapter is a class that i!ple!ents all necessary !ethods. They are e!pty. ,e then use only those !ethods& that we actually need. There is no adapter for a button click event. %ecause there we have only one !ethod to i!ple!ent. Theaction'erformed,- !ethod. ,e can use adapters in situations& where we have !ore than one !ethod to i!ple!ent. The following exa!ple is a rewrite of the previous one& using a ComponentAdapter.
import javax.swing.J<anel;
public :dapter() {
set#itle($:dapter$);
labelx 2 new J.abel($xI $); labelx.setFont(new Font($Seri&$! Font.;(.%! >L)); labelx.set;ounds(" ! " ! @ ! "?);
Created by dovari.sudheerkiran@gmail.com
panel.add(labelx); panel.add(label=);
setSize(3> ! "
);
class Cove:dapter extends 'omponent:dapter { public void componentCoved('omponent)vent e) { int x 2 e.get'omponent().get*(); int = 2 e.get'omponent().getG(); labelx.set#ext($xI $ J x);
label=.set#ext($=I $ J =); / /
public static void main(String01 args) { new :dapter(); / / This exa!ple is a rewrite of the previous one. 2ere we use the ComponentAdapter.
int x 2 e.get'omponent().get*();
int = 2 e.get'omponent().getG();
labelx.set#ext($xI $ J x);
label=.set#ext($=I $ J =);
Created by dovari.sudheerkiran@gmail.com
Inside the
other top level windows.Modeless dialogs allow input to other windows. ,hat type of dialog to use& depends on the circu!stances. +n open file dialog is a good exa!ple of a !odal dialog. ,hile choosing a file to open& no other operation should be per!itted. + typical !odeless dialog is a find text dialog. BLike in =clipse I.=.C It is handy to have the ability to !ove the cursor in the text control and define& where to start the finding of the particular text.
import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.J%ialog; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.JCenu; import javax.swing.JCenu;ar; import javax.swing.JCenu+tem;
public :bout%ialog() {
set#itle($:bout -otes$);
Created by dovari.sudheerkiran@gmail.com
+mage+con icon 2 new +mage+con($notes.png$); J.abel label 2 new J.abel(icon); label.set:lignment*( .?&); add(label);
J.abel name 2 new J.abel($-otes! >."3$); name.setFont(new Font($Seri&$! Font.;(.%! >3)); name.set:lignment*( .?&); add(name);
setCodalit=#=pe(Codalit=#=pe.:<<.+':#+(-,C(%:.);
Created by dovari.sudheerkiran@gmail.com
public Simple%ialog() {
set#itle($Simple %ialog$);
about.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { :bout%ialog ad 2 new :bout%ialog(); ad.set3isible(true); /
/);
setSize(3
! "
);
public static void main(String01 args) { new Simple%ialog(); / / The sa!ple code will popup a s!all dialog box. The dialog will display an icon a text and one close button.
class :bout%ialog extends J%ialog { The custo! dialog is based on the J/ialog class.
Created by dovari.sudheerkiran@gmail.com
ad.set3isible(true); 2ere we display the about dialog& fro! the !enu of the !ain fra!e.
Message boxes
essage boxes provide infor!ation to the user.
public Cessage;oxes() {
set#itle($Cessage ;oxes$);
J;utton error 2 new J;utton($)rror$); J;utton warning 2 new J;utton($8arning$); J;utton Huestion 2 new J;utton($Uuestion$);
Created by dovari.sudheerkiran@gmail.com
error.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { J(ption<ane.s5owCessage%ialog(panel! $'ould not open
&ile$!
$)rror$! J(ption<ane.)DD(D,C)SS:K)); /
/);
warning.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { J(ption<ane.s5owCessage%ialog(panel! $: deprecated call$! $8arning$! J(ption<ane.8:D-+-K,C)SS:K)); /
/);
HuitV$!
$Uuestion$! J(ption<ane.UE)S#+(-,C)SS:K)); /
/);
in&ormation.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { J(ption<ane.s5owCessage%ialog(panel! $%ownload completed$! $Uuestion$! J(ption<ane.+-F(DC:#+(-,C)SS:K)); /
/);
add(panel);
Created by dovari.sudheerkiran@gmail.com
setSize(3
! "
);
public static void main(String01 args) { new Cessage;oxes(); / / The exa!ple shows an error& ;uestion& warning and infor!ation !essage boxes.
panel.set.a=out(new Krid.a=out("! ")); ,e use a .rid!ayout layout !anager to organi"e buttons& that will popup !essage boxes.
J;utton in&ormation 2 new J;utton($+n&ormation$); 2ere are the four buttons& that we will use.
$)rror$! J(ption<ane.)DD(D,C)SS:K)); To create a !essage box& we call the showMessage/ialog static !ethod of the JOption'ane class. ,e provide the co!ponent na!e& !essage text& title and a !essage type. The !essage type is deter!ined by the constant we choose. +vailable constants are< =EE3EH =SS+G= ,+E7I7GH =SS+G= IU=STI37H =SS+G= I7$3E +TI37H =SS+G=
$igure<
essage boxes
Created by dovari.sudheerkiran@gmail.com
$igure<
essage boxes
J#ileChooser
J$ile*hooser is a standard dialog for selecting a file fro! the file syste!.
import javax.swing.;orderFactor=; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFile'5ooser; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.JScroll<ane;
public File'5ooser%ialog() {
set#itle($File'5ooser%ialog$);
Created by dovari.sudheerkiran@gmail.com
openb.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { JFile'5ooser &ileopen 2 new JFile'5ooser(); FileFilter &ilter 2 new File-ame)xtensionFilter($c
&iles$! $c$);
&ileopen.add'5oosableFileFilter(&ilter);
i& (ret 22 JFile'5ooser.:<<D(3),(<#+(-) { File &ile 2 &ileopen.getSelectedFile(); String text 2 readFile(&ile); area.set#ext(text); /
/ /);
toolbar.add(openb);
add(toolbar! ;order.a=out.-(D#9);
setSize(L
! 3
);
Created by dovari.sudheerkiran@gmail.com
tr= { FileDeader in 2 new FileDeader (&ile); ;u&&eredDeader brd 2 new ;u&&eredDeader (in); &ile;u&&er 2 new String;u&&er() ;
public static void main(String01 args) { new File'5ooser%ialog(); / / The code exa!ple will de!onstrate how to use a file chooser dialog in order to load file contents into the text area co!ponent.
JFile'5ooser &ileopen 2 new JFile'5ooser(); This is the constructor of the file chooser dialog.
&ileopen.add'5oosableFileFilter(&ilter); 2ere we define the file filter. In our case& we will have c files with extension .c. ,e have also the default +ll files option.
int ret 2 &ileopen.s5ow%ialog(panel! $(pen &ile$); 2ere we show the file chooser dialog. Upon clicking on the open file button& the return value is e;ual toJ#ileChooser%A''2O3&4O'T O).
area.set#ext(text);
Created by dovari.sudheerkiran@gmail.com
/ 2ere we get the na!e of the selected file. ,e read the contents of the file and set the text into the textarea.
JColorChooser
J*olor*hooser is a standard dialog for selecting a color.
import javax.swing.;orderFactor=; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.J'olor'5ooser; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.J#ool;ar;
public 'olor'5ooser%ialog() {
set#itle($'olor'5ooser%ialog$);
Created by dovari.sudheerkiran@gmail.com
openb.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { J'olor'5ooser clr 2 new J'olor'5ooser(); 'olor color 2 clr.s5ow%ialog(panel! $'5oose 'olor$!
'olor.w5ite);
displa=.set;ac4ground(color); / /);
toolbar.add(openb);
add(toolbar! ;order.a=out.-(D#9);
setSize(L
! 3
);
public static void main(String01 args) { new 'olor'5ooser%ialog(); / / In the exa!ple& we have a white panel. ,e will change the background color of the panel by selecting a color fro! the color chooser dialog.
displa=.set;ac4ground(color); This code shows a color chooser dialog. The show/ialog,- !ethod returns the selected color value. ,e change the display panel background to the newly selected color.
Created by dovari.sudheerkiran@gmail.com
J!abel Component
J!abel is a si!ple co!ponent for displaying text& i!ages or both. It does not react to input events.
import java.awt.;order.a=out; import java.awt.'olor; import java.awt.%imension; import java.awt.Font; import java.awt.#ool4it;
public C=.abel() {
set#itle($-o Sleep$);
String l=rics 2
Created by dovari.sudheerkiran@gmail.com
$Someone + would call nowObrP$ J $:nd neon signs got tiredObrP$ J $Ded e=e &lig5ts 5elp t5e stars outObrP$ J $+Wm sa&e in a cornerObrP$ J $Just 5ours be&ore meObrP$ J $ObrP$ J $+Wm wa4ing wit5 t5e roac5esObrP$ J $#5e world 5as surrenderedObrP$ J $+Wm dating ancient g5ostsObrP$ J $#5e ones + made &riends wit5ObrP$ J $#5e com&ort o& &ire&liesObrP$ J $.ong gone be&ore da=lig5tObrP$ J $ObrP$ J $:nd i& + 5ad one wis5&ul &ield tonig5tObrP$ J $+Wd as4 &or t5e sun to never riseObrP$ J $+& Kod leant 5is voice &or me to spea4ObrP$ J $+Wd sa= go to bed! worldObrP$ J $ObrP$ J $+Wve alwa=s been too lateObrP$ J $#o see w5atWs be&ore meObrP$ J $:nd + 4now not5ing sweeter t5anObrP$ J
$'5ampaign &rom last -ew GearsObrP$ J $Sweet music in m= earsObrP$ J $:nd a nig5t &ull o& no &earsObrP$ J $ObrP$ J $;ut i& + 5ad one wis5&ul &ield tonig5tObrP$ J $+Wd as4 &or t5e sun to never riseObrP$ J $+& Kod passed a mic to me to spea4ObrP$ J $+Wd sa= sta= in bed! worldObrP$ J $Sleep in peaceO65tmlP$;
J.abel label 2 new J.abel(l=rics); label.setFont(new Font($Keorgia$! Font.<.:+-! >L)); label.setForeground(new 'olor(? ! ? ! "?));
Created by dovari.sudheerkiran@gmail.com
pac4();
tool4it 2 get#ool4it(); %imension screensize 2 tool4it.getScreenSize(); set.ocation((screensize.widt5 7 get8idt5())6"! (screensize.5eig5t 7 get9eig5t())6"); set%e&ault'lose(peration()*+#,(-,'.(S)); /
/ /
In our exa!ple& we show lyrics of no sleep song fro! cardigans. ,e can use ht!l tags in J!abel co!ponent. ,e use the JbrK tag to separate lines.
panel.set.a=out(new ;order.a=out(> ! > )); ,e create a panel and set a Border!ayout !anager.
label.setForeground(new 'olor(? ! ? ! "?)); 2ere we create the label co!ponent. ,e set it4s font to plain georgia& 'L px tall. ,e also change the foreground color.
panel.add(label! ;order.a=out.')-#)D);
panel.set;order(;orderFactor=.create)mpt=;order(> ! > ! > ! > )); ,e put the label into the center of the panel. ,e put '(px around the label.
add(panel);
pac4(); The panel is added to the fra!e co!ponent. ,e call the pac$,- !ethod& which will resi"e the window& so that all co!ponents are visible.
Created by dovari.sudheerkiran@gmail.com
$igure< JLabel
JChec$Box
J*heck%ox is a widget that has two states. 3n and 3ff. It is a box with a label. If the checkbox is checked& it is represented by a tick in a box. + checkbox can be used to show>hide splashscreen at startup& toggle visibility of a toolbar etc.
public '5ec4;ox() {
Created by dovari.sudheerkiran@gmail.com
setSize("A ! "
);
new '5ec4;ox();
public void action<er&ormed(:ction)vent e) { i& (t5is.get#itle() 22 $$) { t5is.set#itle($'5ec4box example$); / else { t5is.set#itle($$);
/ / 3ur code exa!ple shows or hides the title of the window depending on it4s state.
add(;ox.createDigid:rea(new %imension(>?! " ))); In this exa!ple& we use a Box!ayout layout !anager. ,e put so!e space there& so that the checkbox is not too close to the corner.
J'5ec4;ox c5ec4box 2 new J'5ec4;ox($S5ow #itle$! true); 2ere we have a constructor for the checkbox. ,e provide text and state.
c5ec4box.setFocusable(&alse); ,e have disabled the focus for the checkbox. The rectangle around the text looks ugly& so we go without the focus.
t5is.set#itle($'5ec4box example$);
/ else {
t5is.set#itle($$);
Created by dovari.sudheerkiran@gmail.com
$igure< J*heck%ox
JSlider
JSlider is a co!ponent that lets the user graphically select a value by sliding a knob within a bounded interval. 3ur exa!ple will show a volu!e control.
import javax.swing.;orderFactor=; import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.+mage+con; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel;
+mage+con mute 2 new +mage+con('lass.oader.getS=stemDesource($mute.png$)); +mage+con min 2 new +mage+con('lass.oader.getS=stemDesource($min.png$)); +mage+con med 2 new +mage+con('lass.oader.getS=stemDesource($med.png$)); +mage+con max 2 new +mage+con('lass.oader.getS=stemDesource($max.png$));
public Slider() {
set#itle($JSlider$); set%e&ault'lose(peration()*+#,(-,'.(S));
Created by dovari.sudheerkiran@gmail.com
J<anel panel 2 new J<anel(); panel.set.a=out(new ;ox.a=out(panel! ;ox.a=out.*,:*+S)); panel.set;order(;orderFactor=.create)mpt=;order(L ! L ! L ! L )); set.a=out(new ;order.a=out());
slider.add'5ange.istener(new '5ange.istener() { public void state'5anged('5ange)vent event) { int value 2 slider.get3alue(); i& (value 22 ) {
label.set+con(med); / else {
label.set+con(max); / / /);
pac4(); set.ocationDelative#o(null);
Created by dovari.sudheerkiran@gmail.com
Slider button 2 new Slider(); button.set3isible(true); / / In the code exa!ple& we show a JSlider and a J!abel. %y dragging the slider& we change the icon on the label co!ponent.
panel.add(;ox.create9orizontalKlue()); ,e put resi"able space to bo both sides& left and right. It is to prevent JSlider fro! growing to unnatural si"es.
);
This is a JSlider constructor. The para!eters are !ini!u! value& !axi!u! value and current value.
slider.add'5ange.istener(new '5ange.istener() {
...
/);
,e add a Change!istener to the slider. Inside the listener& we deter!ine the current slider value and update the label accordingly.
panel.add(;ox.createDigid:rea(new %imension(?!
)));
,e place a Dpx rigid space between the two co!ponents. They are too close to each other& when the slider is at the end position.
$igure< JSlider
JComboBox
*o!bobox is a co!ponent that co!bines a button or editable field and a dropAdown list. The user can select a value fro! the dropAdown list& which appears at the user4s re;uest. If you !ake the co!bo box editable& then the co!bo box includes an editable field into which the user can type a value.
import java.awt.'omponent; import java.awt.%imension; import java.awt.event.:ction)vent; import java.awt.event.:ction.istener; import java.awt.event.+tem)vent; import java.awt.event.+tem.istener;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.J'ombo;ox; import javax.swing.J%ialog; import javax.swing.J.abel; import javax.swing.border..ine;order;
&inal String01 aut5ors 2 { $.eo #olsto=$! $Jo5n Kalswort5=$! $9onore de ;alzac$! $Ste&an Sweig$! $;oris <asterna4$! $#om 8ol&e$ /;
private J.abel displa= 2 null; private J'ombo;ox combobox 2 null; private J;utton button 2 null;
public 'ombo;ox() {
displa=.set:lignment*('omponent.')-#)D,:.+K-C)-#);
Created by dovari.sudheerkiran@gmail.com
displa=.set;order(.ine;order.createKra=.ine;order()); add(displa=);
combobox 2 new J'ombo;ox(aut5ors); combobox.setSelected+ndex(7>); combobox.set<re&erredSize(new %imension(>L ! "")); combobox.setCaximumSize(new %imension(>L ! "")); combobox.add+tem.istener(t5is); add(combobox);
set#itle($J'ombo;ox$); setSize(3 ! 3 );
i& (e.getState'5ange() 22 +tem)vent.S).)'#)%) { J'ombo;ox combo 2 (J'ombo;ox) e.getSource(); int index 2 combo.getSelected+ndex(); displa=.set+con(new +mage+con( 'lass.oader.getS=stemDesource(images0index1)));
Created by dovari.sudheerkiran@gmail.com
/ / In our exa!ple& we have three co!ponents. + label& a co!bobox and a button. The button closes the window. ,e have six na!es of fa!ous novelists in our co!bobox. If we select a na!e& an i!age is displayed in the label.
combobox.setSelected+ndex(7>); The constructor of the JComboBox takes a string array of novelists. If we provide A' as an argu!ent in thesetSelected ndex,- !ethod& no ite! to be selected.
combobox.add+tem.istener(t5is); ,e add an tem!istener to our co!bobox. In the event handler& we get the selected index of the co!bobox and set an appropriate icon for the label. The selected ite! is an index to the array of i!ages.
$igure< J*o!bo%ox
J'rogressBar
+ progress bar is a widget that is used& when we process lengthy tasks. It is ani!ated so that the user knows& that our task is progressing. The J'rogressBar widget provides a hori"ontal or vertical progress bar. The initial and !ini!u! values are (& and the !axi!u! is '((.
Created by dovari.sudheerkiran@gmail.com
import javax.swing.;ox.a=out; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.J<rogress;ar; import javax.swing.#imer;
public <rogress;ar() {
set#itle($J<rogress;ar$);
progress;ar.setCaximumSize(new %imension(>? ! " )); progress;ar.setCinimumSize(new %imension(>? ! " )); progress;ar.set<re&erredSize(new %imension(>? ! " ));
progress;ar.set:lignment*( &);
Created by dovari.sudheerkiran@gmail.com
progress;ar.set3alue(JJval); / /;
button.set#ext($Stop$); /
/ /);
panel.add(button); add(panel);
new <rogress;ar();
Created by dovari.sudheerkiran@gmail.com
/ /
The exa!ple displays a progress bar and a button. The button starts and stops the progress.
progress;ar 2 new J<rogress;ar(); 2ere we create the J'rogressBar. The !ini!u! value is (& !axi!u! '(( and the initial value is (. These are the default values.
progress;ar.set<re&erredSize(new %imension(>? ! " )); These lines are for design purposes only. I want !y exa!ples to look nice. The default height on !y box was only 'Lpx which looked bad.
progress;ar.set:lignment*( &); This line aligns both progress bar with the button. To the left.
panel.add(;ox.createDigid:rea(new %imension( ! " ))); 2ere we put so!e rigid space between the two co!ponents.
timer 2 new #imer(? ! update<ro;ar); The ti!er ob#ect launches update5ro%ar listener every D(!s. Inside that listener& we check& if the progress bar reached the value '(( and stop the ti!er& or update the progress bar.
i& (timer.isDunning()) {
timer.stop();
button.set#ext($Start$);
timer.start();
button.set#ext($Stop$);
/ *licking on the button starts or stops the progress. The text of the button is updated dyna!ically. It can have Start& Stop or =nd String values.
$igure< J5rogress%ar
JToggleButton
JToggleButton is a button that has two states. 5ressed and not pressed. Mou toggle between these two states by clicking on it. There are situations where this functionality fits well.
import java.awt.'olor;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.;orderFactor=; import javax.swing.;ox; import javax.swing.;ox.a=out; import javax.swing.J%ialog; import javax.swing.J<anel; import javax.swing.J#oggle;utton; import javax.swing.border..ine;order;
private J#oggle;utton red; private J#oggle;utton green; private J#oggle;utton blue; private J<anel displa=;
public #oggle;utton() {
set#itle($J#oggle;utton$);
J<anel bottom 2 new J<anel(); bottom.set.a=out(new ;ox.a=out(bottom! ;ox.a=out.*,:*+S)); bottom.set;order(;orderFactor=.create)mpt=;order(" ! " ! " ! " ));
blue.setCaximumSize(green.getCaximumSize()); red.setCaximumSize(green.getCaximumSize());
Created by dovari.sudheerkiran@gmail.com
bottom.add(displa=); add(bottom);
pac4(); setDesizable(&alse);
'olor color 2 displa=.get;ac4ground(); int red 2 color.getDed(); int green 2 color.getKreen(); int blue 2 color.get;lue();
red 2 "??;
Created by dovari.sudheerkiran@gmail.com
/ else { red 2 / / ;
The exa!ple has three panels and three toggle buttons. 5anels are botto! panel& left panel and display panel. The botto! panel is use to organi"e the left and display panels. $or this& we use hori"ontal Box!ayout !anager. The left panel will holt three toggle buttons. This ti!e we use vertical Box!ayout !anager. ,e set the background color of the display panel to black. The toggle buttons will toggle the red& green and blue parts of the color value. The background color will depend on which togglebuttons we have pressed.
red.add:ction.istener(t5is); 2ere we create a toggle button and set an action listener to it.
blue.setCaximumSize(green.getCaximumSize());
int blue 2 color.get;lue(); In the action'erformed !ethod& we deter!ine the current red& green& blue parts of the display background color.
Created by dovari.sudheerkiran@gmail.com
i& (red 22
) {
red 2 "??;
/ else {
red 2
/ ,e deter!ine& which button was toggled& and update the color part of the EG% value accordingly.
displa=.set;ac4ground(set'ol); 2ere a new color is created and the display panel is updated to a new color.
$igure< JToggle%utton
J!ist Component
J!ist is a co!ponent that displays a list of ob#ects. It allows the user to select one or !ore ite!s.
import javax.swing.;orderFactor=; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J.ist; import javax.swing.J<anel; import javax.swing.JScroll<ane; import javax.swing.E+Canager; import javax.swing.event..istSelection)vent;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.event..istSelection.istener;
public .ist() {
set#itle($.ist$); set%e&ault'lose(peration()*+#,(-,'.(S));
J<anel panel 2 new J<anel(); panel.set.a=out(new ;order.a=out()); panel.set;order(;orderFactor=.create)mpt=;order(" ! " ! " ! " ));
Krap5ics)nvironment ge 2 Krap5ics)nvironment.get.ocalKrap5ics)nvironment();
list 2 new J.ist(&onts); list.add.istSelection.istener(new .istSelection.istener() { public void value'5anged(.istSelection)vent e) { i& (Qe.get3alue+s:djusting()) { String name 2 (String) list.getSelected3alue(); Font &ont 2 new Font(name! Font.<.:+-! >"); label.setFont(&ont); / / /);
JScroll<ane pane 2 new JScroll<ane(); pane.get3iewport().add(list); pane.set<re&erredSize(new %imension("? ! " panel.add(pane); ));
label 2 new J.abel($:guirre! der Sorn Kottes$); label.setFont(new Font($Seri&$! Font.<.:+-! >")); add(label! ;order.a=out.S(E#9);
Created by dovari.sudheerkiran@gmail.com
add(panel);
In our exa!ple& we will display a J!ist and a J!abel co!ponents. The list co!ponent contains a list of all available font fa!ily na!es on our syste!. If we select an ite! fro! the list& the label will be displayed in a font& we have chosen.
Krap5ics)nvironment ge 2
Krap5ics)nvironment.get.ocalKrap5ics)nvironment();
String01 &onts 2 ge.get:vailableFontFamil=-ames(); 2ere we obtain all possible font fa!ily na!es on our syste!.
i& (Qe.get3alue+s:djusting()) { This code is ;uite confusing. =vents in list selection are grouped. ,e receive events for both selecting and deselecting. To filter only the selecting events& we use the get3alue sAd1usting,- !ethod. ,hy this weird na!eF 7o idea.
label.setFont(&ont); ,e get the selected ite! and set a new font for the label.
pane.get3iewport().add(list); Interesingly& JLabel co!ponent is not scrollable by default. ,e !ust put the list into the JScroll5ane to !ake it scrollable.
Created by dovari.sudheerkiran@gmail.com
$igure< JList
JTextArea component
+ JTextArea is a !ultiAline text area that displays plain text. It is lightweight co!ponent for working with text. The co!ponent does not handle scrolling. $or this task& we use JScroll'ane co!ponent.
import javax.swing.J#ext:rea;
public #ext:rea() {
set#itle($J#ext:rea$); set%e&ault'lose(peration()*+#,(-,'.(S));
J<anel panel 2 new J<anel(); panel.set.a=out(new ;order.a=out()); panel.set;order(;orderFactor=.create)mpt=;order(" ! " ! " ! " ));
Created by dovari.sudheerkiran@gmail.com
pane.get3iewport().add(area); panel.add(pane);
set.ocationDelative#o(null); set3isible(true);
new #ext:rea();
/ /
The exa!ple shows a si!ple JTextArea co!ponent with an excerpt fro! 1ing speech.
artin Luther
J#ext:rea area 2 new J#ext:rea(); This is the constructor of the JTextArea co!ponent.
area.set.ine8rap(true); ake the lines wrapped& if they are too long to fit the width.
area.set8rapSt=le8ord(true); 2ere we specify& how is line going to be wrapped. In our case& lines will be wrapped at word boundaries& whitespaces.
area.set;order(;orderFactor=.create)mpt=;order(A! A! A! A)); ,e put so!e border around the text in the co!ponent.
pane.get3iewport().add(area); To !ake the text scrollable& we put the JTextArea co!ponent into the JScroll'ane co!ponent.
$igure< JText+ra
JText'ane component
Created by dovari.sudheerkiran@gmail.com
JText'ane co!ponent is a !ore advanced co!ponent for working with text. The co!ponent can do so!e co!plex for!atting operations over the text. It can display also ht!l docu!ents.
import java.io.+()xception;
import javax.swing.;orderFactor=; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.JScroll<ane; import javax.swing.J#ext<ane;
public #ext<ane() {
set#itle($J#ex<ane$); set%e&ault'lose(peration()*+#,(-,'.(S));
J<anel panel 2 new J<anel(); panel.set.a=out(new ;order.a=out()); panel.set;order(;orderFactor=.create)mpt=;order(" ! " ! " ! " ));
textpane.set'ontent#=pe($text65tml$); textpane.set)ditable(&alse);
textpane.set;order(;orderFactor=.create)mpt=;order(A! A! A! A));
Created by dovari.sudheerkiran@gmail.com
pane.get3iewport().add(textpane); panel.add(pane);
set.ocationDelative#o(null); set3isible(true);
new #ext<ane();
/ / This is the ht!l code& that we are loading into the JText'ane co!ponent. The co!ponent does not handle scrolling.
O5tmlP O5eadP
ObrP
Created by dovari.sudheerkiran@gmail.com
O6bod=P
O65tmlP In our exa!ple we show a JText'ane co!ponent and load a ht!l docu!ent. =xa!ple shows for!atting capabilities of the co!ponent.
textpane.set'ontent#=pe($text65tml$);
textpane.set)ditable(&alse); ,e create a JText'ane co!ponent& set the content of the co!ponent to be a ht!l docu!ent and disable editing.
String cd 2 S=stem.get<ropert=($user.dir$) J $6$; 2ere we deter!ine the current working directory of the user. The ht!l docu!ent is located there.
tr= {
textpane.set<age($FileI666$ J cd J $test.5tml$);
/ catc5 (+()xception e) {
S=stem.out.println($)xceptionI $ J e);
$igure< JText5ane
cotroller. The !odel represents the data in the application. The view is the visual representation of the data. +nd finally the controller processes and responds to events& typically user actions& and !ay invoke changes on the !odel. The idea is to separate the data access and business logic fro! data presentation and user interaction& by introducing an inter!ediate co!ponent< the controller.
Created by dovari.sudheerkiran@gmail.com
6* design pattern. The Swing has single ( ob1ect for 6* is so!eti!es called a separable
In the Swing toolkit& every co!ponent has it4s !odel. =ven the basic ones like buttons. There are two kinds of !odels in Swing toolkit. state !odels data !odels
The state !odels handle the state of the co!ponent. $or exa!ple the !odel keeps track whether the co!ponent is selected or pressed. The data !odels handle data& they work with. + list co!ponent keeps a list of ite!s& it is displaying. $or Swing developer it !eans& that we often need to get a !odel instance in order to !anipulate the data in the co!ponent. %ut there are exceptions. $or convenience& there are so!e !ethods that return data without the !odel.
public int get3alue() { return getCodel().get3alue(); / $or exa!ple the get3alue,- !ethod of the JSlider co!ponent. The developer does not need to work with the !odel directly. Instead& the access to the !odel is done behind the scenes. It would be an overkill to work with !odels directly in such si!ple situations. %ecause of this& the Swing tookit provides so!e convenience !ethods like the previous one. To ;uery the state of the !odel& we have two kinds of notifications. lightweight notification stateful notification
The lightweight notification uses a Change!istener class. ,e have only one single event BChange&0ent- for all notifications co!ing fro! the co!ponent. $or !ore co!plicated co!ponents& the stateful notification is used. $or such notifications& we have different kinds of events. $or exa!ple the J!ist co!ponent has !ist/ata&0ent and!istSelection&0ent. If we do not set a !odel for a co!ponent& a default one is created. $or exa!ple the button co!ponent has/efaultButtonModel !odel
public J;utton(String text! +con icon) { 66 'reate t5e model setCodel(new %e&ault;uttonCodel());
66 initialize init(text! icon); / If we look at the J%utton.#ava source file& we find out& that the default !odel is created at the construction of the co!ponent.
ButtonModel
The !odel is used for various kinds of buttons like push buttons& check boxes& radio boxes and for !enu ite!s. The following exa!ple illustrates the !odel for a JButton. ,e can !anage only the state of the button& because no data can be associated with a push button.
import javax.swing.%e&ault;uttonCodel; import javax.swing.J;utton; import javax.swing.J'5ec4;ox; import javax.swing.JFrame; import javax.swing.J.abel;
Created by dovari.sudheerkiran@gmail.com
private J;utton o4; private J.abel enabled; private J.abel pressed; private J.abel armed;
public ;uttonCodel() {
set#itle($;uttonCodel$);
%e&ault;uttonCodel model 2 (%e&ault;uttonCodel) o4.getCodel(); i& (model.is)nabled()) enabled.set#ext($)nabledI true$); else enabled.set#ext($)nabledI &alse$);
Created by dovari.sudheerkiran@gmail.com
/);
cb.add:ction.istener(new :ction.istener() {
cb.set;ounds(>A ! 3 ! >
! "?);
enabled 2 new J.abel($)nabledI true$); enabled.set;ounds(L ! N ! N ! "?); pressed 2 new J.abel($<ressedI &alse$); pressed.set;ounds(L ! >" ! N ! "?); armed 2 new J.abel($:rmedI &alse$);
add(panel);
public static void main(String01 args) { new ;uttonCodel(); / / In our exa!ple& we have a button& check box and three labels. The labels represent three properties of the button. ,hether it is pressed& disabled or ar!ed.
Created by dovari.sudheerkiran@gmail.com
o4.add'5ange.istener(new '5ange.istener() { ,e use a lightweight Change!istener to listen for button state changes.
%e&ault;uttonCodel model 2 (%e&ault;uttonCodel) o4.getCodel(); 2ere we get the default button !odel.
i& (model.is)nabled())
enabled.set#ext($)nabledI true$);
else
enabled.set#ext($)nabledI &alse$); ,e ;uery the !odel& whether the button is enabled or not. ,e update the label accordingly.
i& (o4.is)nabled())
o4.set)nabled(&alse);
else
o4.set)nabled(true); The check box enables or disables the button. To enable the ok button& we call the set&nable,- !ethod. So we change the state of the button. ,here is the !odelF The answer lies in the +bstract%utton.#ava file.
super.set)nabled(b); model.set)nabled(b); / The answer is& that internally& we the Swing toolkit works with a !odel. The set&nable,- is another convenience !ethod for progra!!ers.
Custom ButtonModel
In the previous exa!ple& we used a default button !odel. In the following code exa!ple we will use our own button !odel.
Created by dovari.sudheerkiran@gmail.com
import javax.swing.J;utton; import javax.swing.J'5ec4;ox; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel;
private J;utton o4; private J.abel enabled; private J.abel pressed; private J.abel armed;
public ;uttonCodel"() {
set#itle($;uttonCodel$);
o4.set;ounds(L ! 3 ! A ! "?);
cb.add:ction.istener(new :ction.istener() {
cb.set;ounds(>A ! 3 ! >
! "?);
enabled 2 new J.abel($)nabledI true$); enabled.set;ounds(L ! N ! N ! "?); pressed 2 new J.abel($<ressedI &alse$); pressed.set;ounds(L ! >" ! N ! "?);
Created by dovari.sudheerkiran@gmail.com
armed
;uttonCodel model 2 new %e&ault;uttonCodel() { public void set)nabled(boolean b) { i& (b) enabled.set#ext($<ressedI true$); else enabled.set#ext($<ressedI &alse$);
super.set)nabled(b); /
public void set:rmed(boolean b) { i& (b) armed.set#ext($:rmedI true$); else armed.set#ext($:rmedI &alse$);
super.set:rmed(b); /
public void set<ressed(boolean b) { i& (b) pressed.set#ext($<ressedI true$); else pressed.set#ext($<ressedI &alse$);
super.set<ressed(b); /
/;
o4.setCodel(model);
add(panel);
Created by dovari.sudheerkiran@gmail.com
public static void main(String01 args) { new ;uttonCodel"(); / / This exa!ple does the sa!e thing as the previous one. The difference is that we don4t use a change listener and we use a custo! button !odel.
;uttonCodel model 2 new %e&ault;uttonCodel() { ,e create a button !odel and overwrite the necessary !ethods.
i& (b)
enabled.set#ext($<ressedI true$);
else
enabled.set#ext($<ressedI &alse$);
super.set)nabled(b);
/ ,e overwrite the set&nabled,- !ethod and add so!e functionality there. ,e !ust not forget to call the parent !ethod as well to procede with the processing.
J!ist models
Several co!ponents have two !odels. The J!ist co!ponent has the following !odels< !istModel and!istSelectionModel. The List odel handles data. +nd the ListSelection odel works with the GUI. The following exa!ple shows both !odels.
import java.awt.;order.a=out; import java.awt.%imension; import java.awt.event.:ction)vent; import java.awt.event.:ction.istener; import java.awt.event.Couse:dapter; import java.awt.event.Couse)vent;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.%e&ault.istCodel; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.ist; import javax.swing.J(ption<ane; import javax.swing.J<anel; import javax.swing.JScroll<ane; import javax.swing..istSelectionCodel;
public .ist() {
set#itle($J.ist models$);
list.addCouse.istener(new Couse:dapter() {
Created by dovari.sudheerkiran@gmail.com
i&(e.get'lic4'ount() 22 "){ int index 2 list.location#o+ndex(e.get<oint()); (bject item 2 model.get)lement:t(index); String text 2 J(ption<ane.s5ow+nput%ialog($Dename
item$! item);
String newitem 2 null; i& (text Q2 null) newitem 2 text.trim(); else return;
/);
" ));
le&t<anel.add(pane);
J;utton removeall 2 new J;utton($Demove :ll$); J;utton add 2 new J;utton($:dd$); add.setCaximumSize(removeall.getCaximumSize()); J;utton rename 2 new J;utton($Dename$); rename.setCaximumSize(removeall.getCaximumSize()); J;utton delete 2 new J;utton($%elete$); delete.setCaximumSize(removeall.getCaximumSize());
add.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent e) { String text 2 J(ption<ane.s5ow+nput%ialog($:dd a new item$); String item 2 null;
Created by dovari.sudheerkiran@gmail.com
delete.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { .istSelectionCodel selmodel 2 list.getSelectionCodel(); int index 2 selmodel.getCinSelection+ndex(); i& (index P2 )
model.remove(index); /
/);
rename.add:ction.istener(new :ction.istener() {
public void action<er&ormed(:ction)vent e) { .istSelectionCodel selmodel 2 list.getSelectionCodel(); int index 2 selmodel.getCinSelection+ndex(); i& (index 22 7>) return; (bject item 2 model.get)lement:t(index); String text 2 J(ption<ane.s5ow+nput%ialog($Dename item$!
item);
Created by dovari.sudheerkiran@gmail.com
rig5t<anel.add(add); rig5t<anel.add(;ox.createDigid:rea(new %imension( !L))); rig5t<anel.add(rename); rig5t<anel.add(;ox.createDigid:rea(new %imension( !L))); rig5t<anel.add(delete); rig5t<anel.add(;ox.createDigid:rea(new %imension( !L))); rig5t<anel.add(removeall);
" ));
rig5t<anel.set;order(;orderFactor=.create)mpt=;order( !
panel.add(le&t<anel); panel.add(rig5t<anel);
add(panel);
public static void main(String01 args) { new .ist(); / / The exa!ple shows a list co!ponent and four buttons. The buttons control the data in the list co!ponent. The exa!ple is a bit larger& because we did so!e additional checks there. ,e do not allow to input e!pty spaces into the list co!ponent.
model.add)lement($:melie$);
Created by dovari.sudheerkiran@gmail.com
list.setSelectionCode(.istSelectionCodel.S+-K.),S).)'#+(-);
list.set;order(;orderFactor=.create)mpt=;order("! "! "! ")); ,e create a list co!ponent. The para!eter of the constructor is the !odel& we have created. ,e put the list into the single selection !ode. ,e also put so!e space around the list.
item 2 text.trim();
else
return;
i& (Qitem.is)mpt=())
model.add)lement(item); ,e add only ite!s that are not e;ual to null and are not e!pty. e.g. that contain at least one character other than white space. It !akes no sense to add white spaces or null values into the list.
i& (index P2
model.remove(index); This is the code& that runs when we press the delete button. In order to delete an ite! fro! the list& it !ust be selected. So we !ust figure out the currently selected ite!. $or this& we call the getSelectionModel,- !ethod This is a GUI work& so we use
a !istSelectionModel. Ee!oving an ite! is working with data. $or that we use the list data !odel. So& in our exa!ple we used both list !odels. ,e called addBC& re!oveBC and clearBC !ethods of the list data !odel to work with our data. +nd we used a list selection !odel in order to find out the selected ite!& which is a GUI #ob.
$igure< List
odels
A document model
This is an excellent exa!ple of a separation of a data fro! the visual representation. In a JText'ane co!ponent& we have a Styled/ocument for setting the style of the text data.
import javax.swing.;orderFactor=;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J<anel; import javax.swing.JScroll<ane; import javax.swing.J#ext<ane; import javax.swing.J#ool;ar; import javax.swing.text.St=le; import javax.swing.text.St=le'onstants; import javax.swing.text.St=led%ocument;
public %ocumentCodel() {
set#itle($%ocument Codel$);
+mage+con bold 2 new +mage+con($bold.png$); +mage+con italic 2 new +mage+con($italic.png$); +mage+con stri4e 2 new +mage+con($stri4e.png$); +mage+con underline 2 new +mage+con($underline.png$);
J;utton boldb 2 new J;utton(bold); J;utton italb 2 new J;utton(italic); J;utton strib 2 new J;utton(stri4e); J;utton undeb 2 new J;utton(underline);
add(toolbar! ;order.a=out.-(D#9);
Created by dovari.sudheerkiran@gmail.com
doc 2 textpane.getSt=led%ocument();
boldb.add:ction.istener(new :ction.istener() {
italb.add:ction.istener(new :ction.istener() {
/);
strib.add:ction.istener(new :ction.istener() {
Created by dovari.sudheerkiran@gmail.com
/);
undeb.add:ction.istener(new :ction.istener() {
pane.get3iewport().add(textpane); panel.add(pane);
add(panel);
public static void main(String01 args) { new %ocumentCodel(); / / The exa!ple has a text pane and a toolbar. In the toolbar& we have four buttons& that change attributes of the text.
doc 2 textpane.getSt=led%ocument(); 2ere we get the styled docu!ent& which is a !odel for the text pane co!ponent.
St=le'onstants.set;old(st=le! true); + style is a set of text attributes& such as color& si"e. 2ere we register a bold style for the text pane co!ponent. The registered styles can be retrieved at any ti!e.
Created by dovari.sudheerkiran@gmail.com
doc.set'5aracter:ttributes(textpane.getSelectionStart()!
textpane.getSelection)nd() 7 textpane.getSelectionStart()!
textpane.getSt=le($;old$)! &alse); 2ere we change the attributes of the text. The para!eters are the offset& length of the selection& the style and the boolean value replace. The offset is the beginning of the text& where we apply the bold text. ,e get the length value by substracting the selection end and selection start values. %oolean value false !eans& we are not replacing an old style with a new one& but we !erge the!. This !eans& if the text is underlined and we !ake it bold& the result is an underlined bold text.
virtual ob#ect. In general& it can be used to invoke !any kinds of actions& or create various types of associations between two abstract ob#ects. B,ikipediaC .rag and drop functionality is one of the !ost visible aspects of the graphical user interface. .rag and drop operation enables users to do co!plex things intuitively. Usually& we can drag and drop two things. .ata or so!e graphical ob#ects. If we drag an i!age fro! one application to another& we drag and drop binary data. If we drag a tab in $irefox and !ove it to another place& we drag and drop a graphical co!ponent. The sheer a!ount of various classes involved with drag and drop operations in Java Swing toolkit !ight be overwhel!ing. The best way how to cope with this co!plexity is to create a s!all exa!ple for all situations. +nd slowly !ake it to !ore co!plex exa!ples.
The co!ponent& where the drag operation begins !ust have a /ragSource ob#ect registered. + /ropTarget is an ob#ect responsible for accepting drops in an drag and drop operation. + Transferable encapsulates data being transferred. The transferred data can be of various type. + /ata#la0or ob#ect provides infor!ation about the data being transferred.
Several Swing co!ponents have already a builtAin support for drag and drop operations. In such cases& a Swing progra!!er uses a Transfer5andler to !anage the drag and drop
Created by dovari.sudheerkiran@gmail.com
functionality. In situations& where there is no builtAin support& the progra!!er has to create everything fro! scratch.
public Simple%n%() {
set.a=out(null);
add(button); add(&ield);
Created by dovari.sudheerkiran@gmail.com
/ / In our exa!ple we have a text field and a button. ,e can drag a text fro! the field and drop it onto the button.
&ield.set%rag)nabled(true); The text field has a built in support for dragging. ,e !ust enable it.
button.set#rans&er9andler(new #rans&er9andler($text$)); The Transfer5andler is a class responsible for transfering data between co!ponents. The constructor takes a property na!e as a para!eter.
import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.J'omponent; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel; import javax.swing.#rans&er9andler;
public +con%n%() {
>?));
Created by dovari.sudheerkiran@gmail.com
+mage+con icon> 2 new +mage+con($sad.png$); +mage+con icon" 2 new +mage+con($plain.png$); +mage+con icon3 2 new +mage+con($cr=ing.png$);
panel.add(label>); panel.add(button);
panel.add(label"); add(panel);
class %ragCouse:dapter extends Couse:dapter { public void mouse<ressed(Couse)vent e) { J'omponent c 2 (J'omponent) e.getSource(); #rans&er9andler 5andler 2 c.get#rans&er9andler(); 5andler.export:s%rag(c! e! #rans&er9andler.'(<G); / /
Created by dovari.sudheerkiran@gmail.com
In the code exa!ple& we have two labels and a button. =ach co!ponent displays an icon. The two labels enable drag gestures& the button accepts a drop gesture.
label>.addCouse.istener(listener);
label".addCouse.istener(listener); The drag support is not enabled by default for the label. ,e register a custo! !ouse adapter for both labels.
label>.set#rans&er9andler(new #rans&er9andler($icon$));
button.set#rans&er9andler(new #rans&er9andler($icon$));
label".set#rans&er9andler(new #rans&er9andler($icon$)); =ach of the three co!ponents has a Transfer5andler class for an icon property. The Transfer5andler is needed for both drag sources and drag targets as well.
5andler.export:s%rag(c! e! #rans&er9andler.'(<G); These code lines initiate the drag support. ,e get the drag source. In our case it is a label instance. ,e get it4s transfer handler ob#ect. +nd finally initiate the drag support with the exportAs/rag,- !ethod call.
import javax.swing.%e&ault.istCodel; import javax.swing.%ropCode; import javax.swing.JFrame; import javax.swing.J.ist; import javax.swing.J<anel; import javax.swing.JScroll<ane; import javax.swing.J#extField; import javax.swing..istSelectionCodel; import javax.swing.#rans&er9andler;
Created by dovari.sudheerkiran@gmail.com
public .ist%rop() {
set#itle($.ist%rop$);
>?));
add(panel);
pac4();
Created by dovari.sudheerkiran@gmail.com
return support.is%ataFlavorSupported(%ataFlavor.stringFlavor); /
#rans&erable trans&erable 2 support.get#rans&erable(); String line; tr= { line 2 (String) trans&erable.get#rans&er%ata(%ataFlavor.stringFlavor); / catc5 ()xception e) { return &alse; /
String01 data 2 line.split($!$); &or (String itemI data) { i& (Qitem.is)mpt=()) model.add(indexJJ! item.trim()); / return true; / /
public static void main(String01 args) { new .ist%rop(); / / In the above exa!ple& we have a text field and a list co!ponent. The text in the text field can be dragged and dropped into the list. If the text is co!!a separated& the words will be split into rows. If not& the text will be inserted into one row.
list.set%ropCode(%ropCode.+-S)D#);
Created by dovari.sudheerkiran@gmail.com
2ere we specify a drop !ode. The /ropMode% )S&2T specifies& that we are going to insert new ite!s into the list co!ponent. If we chose /ropMode% )S&2T& we would drop new ite!s onto the existing ones.
&ield.set%rag)nabled(true); ,e enable the drag support for the text field co!ponent.
i& (Qsupport.is%rop()) {
return &alse;
return support.is%ataFlavorSupported(%ataFlavor.stringFlavor);
/ This !ethod tests suitability of a drop operation. 2ere we filter out the clipboard paste operations and allow only String drop operations. If the !ethod returns false& the drop operation is cancelled.
...
/ The import/ata,- !ethod transfers the data fro! the clipboard or fro! the drag and drop operation to the drop location.
int index 2 dl.get+ndex(); ,e get a drop location for the list. ,e retrieve the index& where the data will be inserted.
i& (Qitem.is)mpt=())
model.add(indexJJ! item.trim());
/ 2ere we split the text into parts and insert it into one or !ore rows.
$igure< JList drop exa!ple The previous exa!ples used co!ponents with builtAin drag and drop support. 7ext we are going to create a drag and drop functionality fro! scratch.
Created by dovari.sudheerkiran@gmail.com
/rag .esture
In the following exa!ple we will inspect a si!ple drag gesture. ,e will work with several classes needed to create a drag gesture. + /ragSource& /rag.esture&0ent& /rag.esture!istener& Transferable.
import java.awt.'olor; import java.awt.'ursor; import java.awt.%imension; import java.awt.Flow.a=out; import java.awt.datatrans&er.%ataFlavor; import java.awt.datatrans&er.#rans&erable; import java.awt.dnd.%n%'onstants; import java.awt.dnd.%ragKesture)vent; import java.awt.dnd.%ragKesture.istener; import java.awt.dnd.%ragSource;
public %ragKesture() {
set#itle($%rag Kesture$);
>?));
panel.add(le&t); add(panel);
pac4(); set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S));
Created by dovari.sudheerkiran@gmail.com
set.ocationDelative#o(null); set3isible(true); /
public void dragKestureDecognized(%ragKesture)vent event) { S=stem.out.println($grag gesture$); 'ursor cursor 2 null; i& (event.get%rag:ction() 22 %n%'onstants.:'#+(-,'(<G) { cursor 2 %ragSource.%e&ault'op=%rop; / event.start%rag(cursor! t5is); /
public boolean is%ataFlavorSupported(%ataFlavor &lavor) { return &alse; / / This si!ple exa!ple de!ostrates a drag gesture. The drag gesture is created& when we click on a co!ponent and !ove a !ouse pointer& while the button is pressed. The exa!ple will show& how we can create a .ragSource for a co!ponent.
%ragKesture.istener! #rans&erable { The .ragGesture i!ple!ents two interfaces. The /rag.esture!istener will listen for drag gestures. The Transferablehandles data for a transfer operation. In the exa!ple& we will not transfer any data. ,e will only de!onstrate a drag gesture. So the three necessary !ethods of the Transferable interface are left uni!ple!ented.
ds.create%e&ault%ragKestureDecognizer(le&t!
%n%'onstants.:'#+(-,'(<G! t5is); 2ere we create a /ragSource ob#ect and register it for the left panel. The .ragSource is the entity responsible for the initiation of the .rag and .rop operation. The create/efault/rag.esture2ecogni7er,- associates a drag source and/rag.esture!istener with a particular co!ponent.
Created by dovari.sudheerkiran@gmail.com
cursor 2 %ragSource.%e&ault'op=%rop;
event.start%rag(cursor! t5is); The start/rag,- !ethod of the .ragGesture=vent finally starts the drag operation. ,e will specify two para!eters. The cursor type and the Transferable ob#ect.
return null;
return &alse;
/ The ob#ect that i!ple!ents the Transferable interface !ust i!ple!ent these three !ethods. +s I have already !entioned& we left these !ethods uni!ple!ented for now.
import java.awt.'olor; import java.awt.'ursor; import java.awt.%imension; import java.awt.Flow.a=out; import java.awt.datatrans&er.%ataFlavor; import java.awt.datatrans&er.#rans&erable; import java.awt.datatrans&er.EnsupportedFlavor)xception; import java.awt.dnd.%n%'onstants; import java.awt.dnd.%ragKesture)vent; import java.awt.dnd.%ragKesture.istener; import java.awt.dnd.%ragSource; import java.awt.dnd.%rop#arget; import java.awt.dnd.%rop#arget:dapter;
Created by dovari.sudheerkiran@gmail.com
public 'omplex)xample() {
set#itle($'omplex )xample$);
panel
openb.add:ction.istener(new :ction.istener() { public void action<er&ormed(:ction)vent event) { J'olor'5ooser clr 2 new J'olor'5ooser(); 'olor color 2 clr.s5ow%ialog(panel! $'5oose 'olor$!
'olor.w5ite);
le&t.set;ac4ground(color); / /);
Created by dovari.sudheerkiran@gmail.com
new C=%rop#arget.istener(rig5t);
public void dragKestureDecognized(%ragKesture)vent event) { 'ursor cursor 2 null; J<anel panel 2 (J<anel) event.get'omponent();
Created by dovari.sudheerkiran@gmail.com
i& (event.is%ataFlavorSupported(#rans&erable'olor.colorFlavor)) {
'olor color;
Created by dovari.sudheerkiran@gmail.com
public boolean is%ataFlavorSupported(%ataFlavor &lavor) { i& (&lavor.eHuals(colorFlavor) XX &lavor.eHuals(%ataFlavor.stringFlavor)) return true; return &alse; /
public (bject get#rans&er%ata(%ataFlavor &lavor) t5rows EnsupportedFlavor)xception { i& (&lavor.eHuals(colorFlavor)) return color; else i& (&lavor.eHuals(%ataFlavor.stringFlavor)) return color.toString(); else t5row new EnsupportedFlavor)xception(&lavor); /
/ The code exa!ple shows a button and two panels. The button displays a color chooser dialog and sets a color for the first panel. The color can be dragged into the second panel. This exa!ple will enhance the previous one. ,e will add a drop target and a custo! transferable ob#ect.
new C=%rop#arget.istener(rig5t); ,e register a drop target listener with the right panel.
event.start%rag(cursor! new #rans&erable'olor(color)); The start/rag,- !ethod has two para!eters. + cursor and a Transferable ob#ect.
t5is.panel 2 panel;
#rans&erable tr 2 event.get#rans&erable();
i& (event.is%ataFlavorSupported(#rans&erable'olor.colorFlavor)) {
Created by dovari.sudheerkiran@gmail.com
event.accept%rop(%n%'onstants.:'#+(-,'(<G);
t5is.panel.set;ac4ground(color);
event.drop'omplete(true);
return;
/ ,e get the data being transferred. In our case it is a color ob#ect. 2ere we set the color of the right panel.
event.reject%rop(); If the conditions for a drag and drop operation are not fulfilled& we re#ect it.
new %ataFlavor('olor.class! $: 'olor (bject$); In the Transferable*olor& we create a new /ata#la0or ob#ect.
colorFlavor!
%ataFlavor.stringFlavor!
/; 2ere we specify& what data flavors we support. In our case it is a custo! defined color flavor and a preAdefined/ata#la0or%string#la0or.
t5rows EnsupportedFlavor)xception
i& (&lavor.eHuals(colorFlavor))
return color;
return color.toString();
else
Painting in Swing
Created by dovari.sudheerkiran@gmail.com
5ainting is used& when we want to change or enhance an existing widget. 3r if we are creating a custo! widget fro! scratch. To do the painting& we use the painting +5I provided by the Swing toolkit. The painting is done within the paintComponent,- !ethod. In the painting process& we use the .raphics8/ ob#ect.
-. 6ector Graphics
There are two different co!puter graphics. 6ector and raster graphics. Easter graphics represents i!ages as a collection of pixels. 6ector graphics is the use of geo!etrical pri!itives such as points& lines& curves or polygons to represent i!ages. These pri!itives are created using !athe!atical e;uations. %oth types of co!puter graphics have advantages and disadvantages. The advantages of vector graphics over raster are< s!aller si"e ability to "oo! indefinitely !oving& scaling& filling or rotating does not degrade the ;uality of an i!age
Types of primitives
points lines polylines polygons circles ellipses Splines
5oints
The !ost si!ple graphics pri!itive is point. It is a single dot on the window. Interesingly& there is no !ethod to draw a point in Swing. B3r I could not find it.C To draw a point& I used a draw!ine,- !ethod. I used one point twice.
import java.awt.'olor; import java.awt.%imension; import java.awt.Krap5ics; import java.awt.Krap5ics"%; import java.awt.+nsets;
import java.util.Dandom;
Created by dovari.sudheerkiran@gmail.com
g"d.set'olor('olor.blue);
; iJJ) {
int w 2 int 5 2
&rame.set.ocationDelative#o(null); &rame.set3isible(true); / /
3ne point is difficult to observe. ,hy not paint '((( of the!. In our exa!ple& we do so. ,e draw '((( blue points on the panel.
+nsets insets 2 get+nsets(); The si"e of the window includes borders and titlebar. ,e don4t paint there.
int w 2
int 5 2
2ere we calculate the area& where we will effectively paint our points.
int x 2 Cat5.abs(r.next+nt()) Y w;
Created by dovari.sudheerkiran@gmail.com
int = 2 Cat5.abs(r.next+nt()) Y 5; ,e get a rando! nu!ber in range of the si"e of area& that we co!puted above.
g"d.draw.ine(x! =! x! =); 2ere we draw the point. +s I already said& we use a draw!ine,- !ethod. ,e specify the sa!e point twice.
$igure< 5oints
Lines
+ line is a si!ple graphics pri!itive. It is drawn using two points.
&! "& /;
&loat01 das5" 2 { >&! >&! >& /; &loat01 das53 2 { L&! &! "& /;
g"d.draw.ine(" ! L ! "? ! L );
;asicStro4e bs> 2 new ;asicStro4e(>! ;asicStro4e.':<,;E##! ;asicStro4e.J(+-,D(E-%! >. &! das5>! "& );
;asicStro4e bs" 2 new ;asicStro4e(>! ;asicStro4e.':<,;E##! ;asicStro4e.J(+-,D(E-%! >. &! das5"! "& );
Created by dovari.sudheerkiran@gmail.com
;asicStro4e bs3 2 new ;asicStro4e(>! ;asicStro4e.':<,;E##! ;asicStro4e.J(+-,D(E-%! >. &! das53! "& );
;asicStro4e bsL 2 new ;asicStro4e(>! ;asicStro4e.':<,;E##! ;asicStro4e.J(+-,D(E-%! >. &! das5L! "& );
.ines lines 2 new .ines(); JFrame &rame 2 new JFrame($.ines$); &rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(lines); &rame.setSize("A ! "M ); &rame.set.ocationDelative#o(null); &rame.set3isible(true);
/ /
In the exa!ple& we draw five lines. The first line is drawn using the default values. 3ther will have a different stro$e. The stroke is created using the BasicStro$e class. It defines a basic set of rendering attributes for the outlines of graphics pri!itives.
&! "& /;
;asicStro4e.J(+-,D(E-%! >. &! das5>! "& ) This code creates a stroke. The stroke defines the line width& end caps& line #oins& !iter li!it& dash and the dash phase.
Created by dovari.sudheerkiran@gmail.com
$igure< Lines
Eectangles
To draw rectangles& we use the draw2ect,- !ethod. To fill rectangles with the current color& we use the fill2ect,-!ethod.
g"d.set'olor(new 'olor(">"! ">"! ">")); g"d.drawDect(> ! >?! N ! @ ); g"d.drawDect(>3 ! >?! N ! @ ); g"d.drawDect("? ! >?! N ! @ ); g"d.drawDect(> ! > ?! N ! @ ); g"d.drawDect(>3 ! > ?! N ! @ ); g"d.drawDect("? ! > ?! N ! @ ); g"d.drawDect(> ! >N?! N ! @ ); g"d.drawDect(>3 ! >N?! N ! @ ); g"d.drawDect("? ! >N?! N ! @ );
Created by dovari.sudheerkiran@gmail.com
! AL));
Dectangles rects 2 new Dectangles(); JFrame &rame 2 new JFrame($Dectangles$); &rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(rects); &rame.setSize(3@ ! 3 );
&rame.set.ocationDelative#o(null); &rame.set3isible(true); / /
g"d.drawDect(> ! >?! N ! @ );
Created by dovari.sudheerkiran@gmail.com
... ,e set the color of the outline of the rectangle to a soft gray color& so that it does not interfere with the fill color. To draw the outline of the rectangle& we use the draw2ect,- !ethod. The first two para!eters are the x and y values. The third and fourth are width and height.
g"d.&illDect(> ! >?! N ! @ ); To fill the rectangle with a color& we use the fill2ect,- !ethod.
$igure< Eectangles
Textures
+ texture is a bit!ap i!age applied to the surface in co!puter graphics. %esides colors and gradients& we can fill our graphics shapes with textures.
Created by dovari.sudheerkiran@gmail.com
g"d.drawDect(> ! >?! N ! @ ); g"d.drawDect(>3 ! >?! N ! @ ); g"d.drawDect("? ! >?! N ! @ ); g"d.drawDect(> ! > ?! N ! @ ); g"d.drawDect(>3 ! > ?! N ! @ ); g"d.drawDect("? ! > ?! N ! @ );
;u&&ered+mage bimage> 2 null; ;u&&ered+mage bimage" 2 null; ;u&&ered+mage bimage3 2 null; ;u&&ered+mage bimageL 2 null; ;u&&ered+mage bimage? 2 null; ;u&&ered+mage bimage@ 2 null;
ED. url> 2 'lass.oader.getS=stemDesource($texture>.png$); ED. url" 2 'lass.oader.getS=stemDesource($texture".png$); ED. url3 2 'lass.oader.getS=stemDesource($texture3.png$); ED. urlL 2 'lass.oader.getS=stemDesource($textureL.png$); ED. url? 2 'lass.oader.getS=stemDesource($texture?.png$); ED. url@ 2 'lass.oader.getS=stemDesource($texture@.png$);
tr= { bimage> 2 +mage+(.read(url>); bimage" 2 +mage+(.read(url"); bimage3 2 +mage+(.read(url3); bimageL 2 +mage+(.read(urlL); bimage? 2 +mage+(.read(url?); bimage@ 2 +mage+(.read(url@); / catc5 (+()xception ioe) { ioe.printStac4#race(); /
bimage>.get8idt5()! bimage>.get9eig5t());
bimage".get8idt5()! bimage".get9eig5t());
bimage3.get8idt5()! bimage3.get9eig5t());
Created by dovari.sudheerkiran@gmail.com
bimageL.get8idt5()! bimageL.get9eig5t());
bimage?.get8idt5()! bimage?.get9eig5t());
bimage@.get8idt5()! bimage@.get9eig5t());
#exture<aint texture> 2 new #exture<aint(bimage>! rect>); #exture<aint texture" 2 new #exture<aint(bimage"! rect"); #exture<aint texture3 2 new #exture<aint(bimage3! rect3); #exture<aint textureL 2 new #exture<aint(bimageL! rectL); #exture<aint texture? 2 new #exture<aint(bimage?! rect?); #exture<aint texture@ 2 new #exture<aint(bimage@! rect@);
#extures rects 2 new #extures(); JFrame &rame 2 new JFrame($#extures$); &rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(rects); &rame.setSize(3@ ! "> ); &rame.set.ocationDelative#o(null);
Created by dovari.sudheerkiran@gmail.com
&rame.set3isible(true);
/ /
In our exa!ple& we will draw six rectangles filled with different textures. To work with textures& Java Swing has aTexture'aint class.
...
...
#exture<aint texture> 2 new #exture<aint(bimage>! rect>); 2ere we create a Texture'aint ob#ect. The para!eters are a buffered i!age and a rectangle of the i!age. The rectangle is used to anchor and replicate the i!age. The i!ages are tiled.
g"d.set<aint(texture>);
g"d.&illDect(> ! >?! N ! @ );
2ere we apply the texture and fill the rectangle with it.
$igure< Textures
Gradients
In co!puter graphics& gradient is a s!ooth blending of shades fro! light to dark or fro! one color to another. In -. drawing progra!s and paint progra!s& gradients are used to create colorful backgrounds and special effects as well as to si!ulate lights and shadows. Banswers.co!C
import java.awt.;asicStro4e; import java.awt.'olor; import java.awt.Kradient<aint; import java.awt.Krap5ics; import java.awt.Krap5ics"%;
import javax.swing.JFrame;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.J<anel;
Kradient<aint gp" 2 new Kradient<aint(?! "?! 'olor.=ellow! " ! "! 'olor.blac4! true);
g"d.set<aint(gp");
g"d.&illDect(" ! A ! 3
! L );
Kradient<aint gp3 2 new Kradient<aint(?! "?! 'olor.green! "! "! 'olor.blac4! true);
Kradient<aint gpL 2 new Kradient<aint("?! "?! 'olor.blue! >?! "?! 'olor.blac4! true);
Created by dovari.sudheerkiran@gmail.com
Kradients gradients 2 new Kradients(); JFrame &rame 2 new JFrame($Kradients$); &rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(gradients); &rame.setSize(3? ! 3? ); &rame.set.ocationDelative#o(null); &rame.set3isible(true);
/ /
'olor.blue! >?! "?! 'olor.blac4! true); To work with gradients& we use Java Swing4s .radient'aint class.%y !anipulating the color values and the starting end ending points& we can get interesting results.
$igure< Gradients
.rawing text
.rawing is done with the drawString,- !ethod. ,e specify the string we want to draw and the position of the text on the window area.
import javax.swing.JFrame;
Created by dovari.sudheerkiran@gmail.com
import javax.swing.J<anel;
r5.put(Dendering9ints.B)G,D)-%)D+-K! Dendering9ints.3:.E),D)-%)D,UE:.+#G);
g"d.setDendering9ints(r5);
g"d.setFont(&ont);
g"d.drawString($-ot marble! nor t5e gilded monuments$! " ! 3 ); g"d.drawString($(& princes! s5all outlive t5is power&ul r5=me;$ !" ! @ ); g"d.drawString($;ut =ou s5all s5ine more brig5t in t5ese contents$! " ! N ); g"d.drawString($#5an unswept stone! besmearWd wit5 sluttis5 time.$! " ! >" ); g"d.drawString($85en waste&ul war s5all statues overturn!$! " !
>? );
g"d.drawString($:nd broils root out t5e wor4 o& masonr=!$! " ! >A ); g"d.drawString($-or Cars 5is sword! nor warWs Huic4 $ J $&ire s5all burn$! " ! "> ); g"d.drawString($#5e living record o& =our memor=.$! " ! "L ); g"d.drawString($WKainst deat5! and all oblivious enmit=$! " !
"M );
g"d.drawString($S5all =ou pace &ort5; =our praise s5all still $ J $&ind room$! " ! 3 );
g"d.drawString($)ven in t5e e=es o& all posterit=$! " ! 33 ); g"d.drawString($#5at wear t5is world out to t5e ending doom.$! " ! 3@ );
Created by dovari.sudheerkiran@gmail.com
3N );
#ext text 2 new #ext(); JFrame &rame 2 new JFrame($Sonnet ??$); &rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(text); &rame.setSize(? ! LM );
&rame.set.ocationDelative#o(null); &rame.set3isible(true); / /
Dendering9ints.B)G,:-#+:.+:S+-K!
Dendering9ints.3:.E),:-#+:.+:S,(-);
r5.put(Dendering9ints.B)G,D)-%)D+-K!
Dendering9ints.3:.E),D)-%)D,UE:.+#G);
g"d.setDendering9ints(r5); This code is to !ake our text look better. ,e apply a techni;ue called antialiasing.
g"d.drawString($-ot marble! nor t5e gilded monuments$! " ! 3 ); This is the code& that actually draws the text.
Created by dovari.sudheerkiran@gmail.com
$igure< Sonnet DD
I!ages
3n of the !ost i!portant capabililies of a toolkit is the ability to display i!ages. +n i!age is an array of pixels. =ach pixel represents a color at a given position. ,e can use co!ponents like J!abel to display an i!age& or we can draw it using the Ja0a 8/ A' .
import java.awt.+mage;
Krap5ics"% g"d 2 (Krap5ics"%) g; +mage image 2 new +mage+con($dumbier.jpg$).get+mage(); g"d.draw+mage(image! > ! > ! null); /
Created by dovari.sudheerkiran@gmail.com
&rame.set%e&ault'lose(peration(JFrame.)*+#,(-,'.(S)); &rame.add(image); &rame.setSize(3A ! 3" ); &rame.set.ocationDelative#o(null); &rame.set3isible(true); / / This exa!ple will draw an i!age on the panel.
g"d.draw+mage(image! > ! > ! null); These two lines read and draw the i!age.
$igure< I!age
2esi7able component
Eesi"able co!ponents are !ost often used when creating charts& diagra!s and si!ilar. The !ost co!!on resi"able co!ponent is a chart in a spreadsheet application. $or exa!ple& when we create a chart in a 3pen3ffice application. The chart can be !oved over the grid widget of the application and resi"ed. In order to create a co!ponent that can be freely dragged over a panel& we need a panel with absolute positioning enabled. ,e !ust not use a layout !anager. In our exa!ple& we will create a co!ponent Ba J5anelC that we can freely !ove over a parent window and resi"e. In order to distinguish which co!ponent has a focus& we draw O s!all rectangles on the border of our resi"able co!ponent. This way we know& that the co!ponent has focus. The rectangles serve as a dragging points& where we can draw the co!ponent and start resi"ing. I have learnt to use resi"able co!ponents fro! this blog.
pac4age resizablecomponent;
Created by dovari.sudheerkiran@gmail.com
6F Desizable'omponent.java F6
public Desizable'omponent() {
add(panel);
J<anel area 2 new J<anel(); area.set;ac4ground('olor.w5ite); resizer 2 new Desizable(area); resizer.set;ounds(? ! ? ! " panel.add(resizer); ! >? );
Created by dovari.sudheerkiran@gmail.com
private J<anel panel 2 new J<anel(null); ,e have already !entioned& that we cannot use any layout !anager. ,e !ust use absolute positioning for resi"able co!ponent. %y providing null to the constructor& we create a panel with absolute positioning.
addCouse.istener(new Couse:dapter() {
reHuestFocus();
resizer.repaint();
/); If we press on the parent panel& e.g outside the resi"able co!ponent& we grab focus and repaint the co!ponent. The rectangles over the border will disappear.
pac4age resizablecomponent;
66 Desizable;order.java
int locations01 2 { Swing'onstants.-(D#9! Swing'onstants.S(E#9! Swing'onstants.8)S#! Swing'onstants.):S#! Swing'onstants.-(D#9,8)S#! Swing'onstants.-(D#9,):S#! Swing'onstants.S(E#9,8)S#! Swing'onstants.S(E#9,):S# /;
int cursors01 2
Created by dovari.sudheerkiran@gmail.com
public +nsets get;order+nsets('omponent component) { return new +nsets(dist! dist! dist! dist); /
i& (component.5asFocus()) {
&or (int i 2
; i O locations.lengt5; iJJ) {
Dectangle rect 2 getDectangle(x! =! w! 5! locations0i1); g.set'olor('olor.89+#)); g.&illDect(rect.x! rect.=! rect.widt5 7 >! rect.5eig5t 7 >); g.set'olor('olor.;.:'B); g.drawDect(rect.x! rect.=! rect.widt5 7 >! rect.5eig5t 7 >); / / /
private Dectangle getDectangle(int x! int =! int w! int 5! int location) { switc5 (location) { case Swing'onstants.-(D#9I return new Dectangle(x J w 6 " 7 dist 6 "! =! dist! dist);
Created by dovari.sudheerkiran@gmail.com
case Swing'onstants.S(E#9I return new Dectangle(x J w 6 " 7 dist 6 "! = J 5 7 dist! dist! dist); case Swing'onstants.8)S#I return new Dectangle(x! = J 5 6 " 7 dist 6 "! dist! dist); case Swing'onstants.):S#I return new Dectangle(x J w 7 dist! = J 5 6 " 7 dist 6 "! dist! dist); case Swing'onstants.-(D#9,8)S#I return new Dectangle(x! =! dist! dist); case Swing'onstants.-(D#9,):S#I return new Dectangle(x J w 7 dist! =! dist! dist); case Swing'onstants.S(E#9,8)S#I return new Dectangle(x! = J 5 7 dist! dist! dist); case Swing'onstants.S(E#9,):S#I return new Dectangle(x J w 7 dist! = J 5 7 dist! dist! dist); / return null; /
&or (int i 2
return 'ursor.C(3),'EDS(D; / / The 2esi7ableBorder is responsible for drawing the border of the co!ponent and deter!ining the type of the cursor to use.
int locations01 2
Swing'onstants.):S#! Swing'onstants.-(D#9,8)S#!
Swing'onstants.-(D#9,):S#! Swing'onstants.S(E#9,8)S#!
Created by dovari.sudheerkiran@gmail.com
Swing'onstants.S(E#9,):S#
/; These are locations& where we will draw rectangles. These locations are grabbing points& where we can grab the co!ponent and resi"e it.
g.set'olor('olor.blac4);
g.drawDect(x J dist 6 "! = J dist 6 "! w 7 dist! 5 7 dist); In the paintBorder,- !ethod& we draw the border of the resi"able co!ponent. The upper code draws the outer border of the co!ponent.
i& (component.5asFocus()) {
&or (int i 2
; i O locations.lengt5; iJJ) {
g.set'olor('olor.89+#));
g.set'olor('olor.;.:'B);
/ The eight rectangles are drawn only in case that the resi"able co!ponent has currently focus.
$inally& the get2ectangle,- !ethod gets the coordinates of the rectangles and the getCursor,- !ethods gets the cursor type for the grab point in ;uestion.
pac4age resizablecomponent;
import java.awt.;order.a=out; import java.awt.'omponent; import java.awt.'ursor; import java.awt.<oint; import java.awt.Dectangle; import java.awt.event.Couse)vent;
66 Desizable.java
Created by dovari.sudheerkiran@gmail.com
public Desizable('omponent comp! Desizable;order border) { set.a=out(new ;order.a=out()); add(comp); addCouse.istener(resize.istener); addCouseCotion.istener(resize.istener); set;order(border); /
Couse+nput.istener resize.istener 2 new Couse+nput:dapter() { public void mouseCoved(Couse)vent me) { i& (5asFocus()) { Desizable;order border 2 (Desizable;order)get;order(); set'ursor('ursor.get<rede&ined'ursor(border.get'ursor(me)));
/ /
public void mouse<ressed(Couse)vent me) { Desizable;order border 2 (Desizable;order)get;order(); cursor 2 border.get'ursor(me); start<os 2 me.get<oint(); reHuestFocus(); repaint(); /
Created by dovari.sudheerkiran@gmail.com
switc5 (cursor) { case 'ursor.-,D)S+S),'EDS(DI i& (Q(5 7 d= O ? )) { set;ounds(x! = J d=! w! 5 7 d=); resize(); / brea4;
resize(); / brea4;
case 'ursor.8,D)S+S),'EDS(DI i& (Q(w 7 dx O ? )) { set;ounds(x J dx! =! w 7 dx! 5); resize(); / brea4;
case 'ursor.),D)S+S),'EDS(DI i& (Q(w J dx O ? )) { set;ounds(x! =! w J dx! 5); start<os 2 me.get<oint(); resize(); / brea4;
Created by dovari.sudheerkiran@gmail.com
case 'ursor.-),D)S+S),'EDS(DI i& (Q(w J dx O ? ) RR Q(5 7 d= O ? )) { set;ounds(x! = J d=! w J dx! 5 7 d=); start<os 2 new <oint(me.get*()! start<os.=); resize(); / brea4;
case 'ursor.S8,D)S+S),'EDS(DI i& (Q(w 7 dx O ? ) RR Q(5 J d= O ? )) { set;ounds(x J dx! =! w 7 dx! 5 J d=); start<os 2 new <oint(start<os.x! me.getG()); resize(); / brea4;
case 'ursor.S),D)S+S),'EDS(DI i& (Q(w J dx O ? ) RR Q(5 J d= O ? )) { set;ounds(x! =! w J dx! 5 J d=); start<os 2 me.get<oint(); resize(); / brea4;
set'ursor('ursor.get<rede&ined'ursor(cursor)); / /
Created by dovari.sudheerkiran@gmail.com
start<os 2 null; / /; / The 2esi7able class represents the co!ponent& that is being resi"ed and !oved on the window.
((J'omponent)get<arent()).revalidate();
/ The resi7e,- !ethod is called& after we have resi"ed the co!ponent. The re0alidate,- !ethod will cause the co!ponent to be redrawn.
i& (5asFocus()) {
set'ursor('ursor.get<rede&ined'ursor(border.get'ursor(me)));
/ ,e change the cursor type& when we hover the cursor over the grip points. The cursor type changes only if the co!ponent has focus.
cursor 2 border.get'ursor(me);
start<os 2 me.get<oint();
reHuestFocus();
repaint();
/ If we click on the resi"able co!ponent& we change the cursor& get the starting point of dragging& give focus to the co!ponent and redraw it.
int x 2 get*();
int = 2 getG();
int w 2 get8idt5();
int 5 2 get9eig5t();
Created by dovari.sudheerkiran@gmail.com
In the mouse/ragged,- !ethod& we deter!ine the x& y coordinates of the cursor& width and height of the co!ponent. ,e calculate the distances& that we !ake during the !ouse drag event.
case 'ursor.-,D)S+S),'EDS(DI
i& (Q(5 7 d= O ? )) {
resize();
brea4; $or all resi"ing we ensure& that the co!ponent is not s!aller than D( px. 3therwise& we could !ake it so s!all& that we would eventually hide the co!ponent. The setBounds,- !ethod relocates and resi"es the co!ponent.
'u77le
,e have an i!age of a Sid character fro! the Ice +ge !ovie. It is cut into '- pieces. The goal is to for! the picture. Mou can download the picture here.
import java.awt.;order.a=out; import java.awt.%imension; import java.awt.Krid.a=out; import java.awt.+mage; import java.awt.event.:ction)vent; import java.awt.event.:ction.istener; import java.awt.image.'rop+mageFilter; import java.awt.image.Filtered+mageSource;
import javax.swing.;ox; import javax.swing.+mage+con; import javax.swing.J;utton; import javax.swing.JFrame; import javax.swing.J.abel; import javax.swing.J<anel;
Created by dovari.sudheerkiran@gmail.com
private J<anel center<anel; private J;utton button; private J.abel label; private +mage source; private +mage image; int0101 pos; int widt5! 5eig5t;
public <uzzle() {
pos 2 new int0101 { { ! >! "/! {3! L! ?/! {@! M! A/! {N! > ! >>/ /;
&or ( int i 2
; i O L; iJJ) { ; j O 3; jJJ) {
&or ( int j 2
Created by dovari.sudheerkiran@gmail.com
/ else { button 2 new J;utton(); button.add:ction.istener(t5is); center<anel.add(button); image 2 create+mage(new Filtered+mageSource(source.getSource()! new 'rop+mageFilter(jFwidt563! iF5eig5t6L! (widt563)J>! 5eig5t6L))); button.set+con(new +mage+con(image)); / / /
new <uzzle();
public void action<er&ormed(:ction)vent e) { J;utton button 2 (J;utton) e.getSource(); %imension size 2 button.getSize();
int label* 2 label.get*(); int labelG 2 label.getG(); int button* 2 button.get*(); int buttonG 2 button.getG(); int button<os* 2 button* 6 size.widt5; int button<osG 2 buttonG 6 size.5eig5t; int button+ndex 2 pos0button<osG10button<os*1;
Created by dovari.sudheerkiran@gmail.com
The goal of this little ga!e is to for! the original picture. ,e !ove the buttons by clicking on the!. 3nly buttons ad#acent to the label can be !oved.
Created by dovari.sudheerkiran@gmail.com
{ ! >! "/!
{3! L! ?/!
{@! M! A/!
source 2 sid.get+mage(); ,e use the mage con class to load the i!age.
&or ( int i 2
; i O L; iJJ) {
&or ( int j 2
; j O 3; jJJ) {
i& ( j 22 " RR i 22 3) {
center<anel.add(label);
/ else {
button.add:ction.istener(t5is);
center<anel.add(button);
button.set+con(new +mage+con(image));
/ The code creates '' buttons and one label. ,e crop the i!age into pieces and place the! on the buttons.
int buttonG 2 button.getG(); ,e get the x& y coordinates of the button that we hit and an e!pty label. The x& y coordinates are i!portant in the logic of the progra!.
int button+ndex 2 pos0button<osG10button<os*1; 2ere we get the index of the button in the two di!ensional array of the button positions.
Created by dovari.sudheerkiran@gmail.com
center<anel.remove(button+ndex);
center<anel.add(label! button+ndex);
center<anel.add(button!label+ndex);
center<anel.validate();
/ In this case& we check if we clicked on the button& that is right above the e!pty label. If it is above the label& they share the x coordinate. If the button is right above the label& the e;uation (labelG 7 buttonG) 22 size.5eig5t is true.
$igure< 5u""le
Tetris
The Tetris ga!e is one of the !ost popular co!puter ga!es ever created. The original ga!e was designed and progra!!ed by a russian progra!!er Alexey 'a1itno0 in '/OD. Since then& Tetris is available on al!ost every co!puter platfor! in lots of variations. =ven !y !obile phone has a !odified version of the Tetris ga!e. Tetris is called a falling block pu""le ga!e. In this ga!e& we have seven different shapes called tetrominoes. SAshape& ?Ashape& TAshape& LAshape& LineAshape& irroredLAshape and a S;uareAshape. =ach of these shapes is for!ed with four s;uares. The shapes are falling down the board. The ob#ect of the Tetris ga!e is to !ove and rotate the shapes& so that they fit as !uch as possible. If we !anage to for! a row& the row is destroyed and we score. ,e play the tetris ga!e until we top out.
$igure< Tetro!inoes
The de0elopment
,e do not have i!ages for our tetris ga!e& we draw the tetro!inoes using Swing drawing +5I. %ehind every co!puter ga!e& there is a !athe!atical !odel. So it is in Tetris. So!e ideas behind the ga!e. ,e use a Timer class to create a ga!e cycle
Created by dovari.sudheerkiran@gmail.com
The tetro!inoes are drawn The shapes !ove on a s;uare by s;uare basis Bnot pixel by pixelC athe!atically a board is a si!ple list of nu!bers
I have si!plified the ga!e a bit& so that it is easier to understand. The ga!e starts i!!ediately& after it is launched. ,e can pause the ga!e by pressing the p key. The space key will drop the tetris piece i!!ediately to the botto!. The d key will drop the piece one line down. BIt can be used to speed up the falling a bit.C The ga!e goes at constant speed& no acceleration is i!ple!ented. The score is the nu!ber of lines& that we have re!oved.
66 #etris.java
pac4age tetris;
import java.awt.;order.a=out;
J.abel statusbar;
public #etris() {
$);
setSize("
! L
);
set#itle($#etris$); set%e&ault'lose(peration()*+#,(-,'.(S)); /
Created by dovari.sudheerkiran@gmail.com
game.set3isible(true);
/ /
In the Tetris.#ava file& we set up the ga!e. ,e create a board on which we play the ga!e. ,e create a statusbar.
board.start(); The start,- !ethod starts the Tetris ga!e. I!!ediately& after the window appears on the screen.
66 S5ape.java
pac4age tetris;
enum #etrominoes { -oS5ape! SS5ape! SS5ape! .ineS5ape! #S5ape! SHuareS5ape! .S5ape! Cirrored.S5ape /;
public S5ape() {
{ 7>! { >! {
! > /! /!
{ { 7>!
{ >!
Created by dovari.sudheerkiran@gmail.com
{ {
/!
{ >!
/!
{ { {
! > /! ! ! /! /!
! 7> /! ! 7> /!
&or (int i 2
&or (int j 2
private void set*(int index! int x) { coords0index10 1 2 x; / private void setG(int index! int =) { coords0index10>1 2 =; / public int x(int index) { return coords0index10 1; / public int =(int index) { return coords0index10>1; / public #etrominoes getS5ape() { return pieceS5ape; /
{ Dandom r 2 new Dandom(); int x 2 Cat5.abs(r.next+nt()) Y M J >; #etrominoes01 values 2 #etrominoes.values(); setS5ape(values0x1); /
public int min*() { int m 2 coords0 10 1; &or (int i2 ; i O L; iJJ) { m 2 Cat5.min(m! coords0i10 1); / return m; /
Created by dovari.sudheerkiran@gmail.com
&or (int i 2
; i O L; JJi) {
&or (int i 2
; i O L; JJi) {
#S5ape! SHuareS5ape! .S5ape! Cirrored.S5ape /; The Tetrominoes enu! holds all seven tetris shapes. 5lus the e!pty shape called here )oShape.
Created by dovari.sudheerkiran@gmail.com
public S5ape() {
setS5ape(#etrominoes.-oS5ape);
/ This is the constructor of the Shape class. The coords array holds the actual coordinates of a tetris piece.
{ {
/!
/!
/!
/ /!
{ {
! 7> /!
/!
{ 7>!
/!
{ 7>! > / /!
{ {
! 7> /!
/!
{ >!
/!
{ >! > / /!
{ {
! 7> /!
/!
! > /!
! " / /!
{ { 7>!
/!
/!
{ >!
/!
! > / /!
{ {
/!
{ >!
/!
! > /!
{ >! > / /!
{ { 7>! 7> /! {
! 7> /!
/!
! > / /!
{ { >! 7> /!
! 7> /!
/!
! > / /
/;
The coordsTable array holds all possible coordinate values of our tetris pieces. This is a te!plate fro! which all pieces take their coordiate values.
&or (int i 2
; i O L ; iJJ) {
&or (int j 2
; j O "; JJj) {
coords0i10j1 2 coords#able0s5ape.ordinal()10i10j1;
/ 2ere we put one row of the coordiate values fro! the coordsTable to a coords array of a tetris piece. 7ote the use of the ordinal,- !ethod. In *99& an enu! type is esencially an integer. Unlike in *99& Java enu!s are full classes. +nd the ordinalBC !ethod returns the current position of the enu! type in the enu! ob#ect. The following i!age will help understand the coordinate values a bit !ore. The coords array saves the coordinates of the tetris piece. $or exa!ple& nu!bers P (& A' Q& P (& ( Q& P '& ( Q& P '& ' Q & represent a rotated SAshape. The following diagra! illustrates the shape.
$igure< Tetris
Created by dovari.sudheerkiran@gmail.com
return t5is;
result.pieceS5ape 2 pieceS5ape;
&or (int i 2
; i O L; JJi) {
result.set*(i! =(i));
result.setG(i! 7x(i));
return result;
/ This code rotates the piece to the left. The s;uare does not have to be rotated. That4s why we si!ply return the reference to the current ob#ect. Looking at the previous i!age will help to understand the rotation.
66 ;oard.java
pac4age tetris;
import java.awt.'olor; import java.awt.%imension; import java.awt.Krap5ics; import java.awt.event.:ction)vent; import java.awt.event.:ction.istener; import java.awt.event.Be=:dapter; import java.awt.event.Be=)vent;
import tetris.S5ape.#etrominoes;
Created by dovari.sudheerkiran@gmail.com
#imer timer; boolean isFallingFinis5ed 2 &alse; boolean isStarted 2 &alse; boolean is<aused 2 &alse; int num.inesDemoved 2 int cur* 2 int curG 2 ; ; ;
statusbar 2
parent.getStatus;ar();
public void action<er&ormed(:ction)vent e) { i& (isFallingFinis5ed) { isFallingFinis5ed 2 &alse; new<iece(); / else { one.ine%own(); / /
int sHuare8idt5() { return (int) getSize().get8idt5() 6 ;oard8idt5; / int sHuare9eig5t() { return (int) getSize().get9eig5t() 6 ;oard9eig5t; / #etrominoes s5ape:t(int x! int =) { return board0(= F ;oard8idt5) J x1; /
Created by dovari.sudheerkiran@gmail.com
new<iece(); timer.start(); /
is<aused 2 Qis<aused;
&or (int i 2
&or (int j 2
Created by dovari.sudheerkiran@gmail.com
#etrominoes s5ape 2 s5ape:t(j! ;oard9eig5t 7 i 7 >); i& (s5ape Q2 #etrominoes.-oS5ape) drawSHuare(g! J j F sHuare8idt5()!
sHuare9eig5t()!
cur<iece.getS5ape()); / / /
board0i1 2 #etrominoes.-oS5ape; /
Created by dovari.sudheerkiran@gmail.com
removeFull.ines();
private void new<iece() { cur<iece.setDandomS5ape(); cur* 2 ;oard8idt5 6 " J >; curG 2 ;oard9eig5t 7 > J cur<iece.minG();
i& (Qtr=Cove(cur<iece! cur*! curG)) { cur<iece.setS5ape(#etrominoes.-oS5ape); timer.stop(); isStarted 2 &alse; statusbar.set#ext($game over$); / /
private boolean tr=Cove(S5ape new<iece! int new*! int newG) { &or (int i 2 ; i O L; JJi) {
Created by dovari.sudheerkiran@gmail.com
; 77i) {
&or (int j 2
; j O ;oard8idt5; JJj) {
i& (numFull.ines P
) {
private void drawSHuare(Krap5ics g! int x! int =! #etrominoes s5ape) { 'olor colors01 2 { new 'olor( ! ! )! new 'olor(" L! > "! > ")!
new 'olor(> "! " L! > ")! new 'olor(> "! > "! " L)! new 'olor(" L! " L! > ")! new 'olor(" L! > "! " L)!
Created by dovari.sudheerkiran@gmail.com
g.set'olor(color.dar4er()); g.draw.ine(x J >! = J sHuare9eig5t() 7 >! x J sHuare8idt5() 7 >! = J sHuare9eig5t() 7 >); g.draw.ine(x J sHuare8idt5() 7 >! = J sHuare9eig5t() 7 >! x J sHuare8idt5() 7 >! = J >);
Created by dovari.sudheerkiran@gmail.com
brea4; case Be=)vent.3B,D+K9#I tr=Cove(cur<iece! cur* J >! curG); brea4; case Be=)vent.3B,%(8-I tr=Cove(cur<iece.rotateDig5t()! cur*! curG); brea4; case Be=)vent.3B,E<I tr=Cove(cur<iece.rotate.e&t()! cur*! curG); brea4; case Be=)vent.3B,S<:')I drop%own(); brea4; case WdWI one.ine%own(); brea4; case W%WI one.ine%own(); brea4; /
/ / / $inally& we have the %oard.#ava file. This is where the ga!e logic is located.
...
isFallingFinis5ed 2 &alse;
isStarted 2 &alse;
is<aused 2 &alse;
num.inesDemoved 2
cur* 2
curG 2
... ,e initiali"e so!e i!portant variables. The is#alling#inished variable deter!ines& if the tetris shape has finished falling and we then need to create a new shape. The num!ines2emo0ed counts the nu!ber of lines& we have re!oved so far. The cur+ and cur9 variables deter!ine the actual position of the falling tetris shape.
setFocusable(true); ,e !ust explicitely call the set#ocusable,- !ethod. $ro! now& the board has the keyboard input.
! t5is);
timer.start();
Created by dovari.sudheerkiran@gmail.com
Timer ob#ect fires one or !ore action events after a specified delay. In our case& the ti!er calls theaction'erformed,- !ethod each L(( !s.
i& (isFallingFinis5ed) {
isFallingFinis5ed 2 &alse;
new<iece();
/ else {
one.ine%own();
/ The action'erformed,- !ethod checks if the falling has finished. If so& a new piece is created. If not& the falling tetris piece goes one line down. Inside the paint,- !ethod& we draw the all ob#ects on the board. The painting has two steps.
&or (int i 2
; i O ;oard9eig5t; JJi) {
&or (int j 2
; j O ;oard8idt5; JJj) {
drawSHuare(g!
J j F sHuare8idt5()!
/ In the first step we paint all the shapes& or re!ains of the shapes& that have been dropped to the botto! of the board. +ll the s;uares are re!e!berd in the board array. ,e access it using the shapeAt,- !ethod.
&or (int i 2
; i O L; JJi) {
drawSHuare(g!
J x F sHuare8idt5()!
cur<iece.getS5ape());
w5ile (newG P
) {
Created by dovari.sudheerkiran@gmail.com
brea4;
77newG;
piece%ropped();
/ If we press the space key& the piece is dropped to the botto!. ,e si!ply try to drop the piece one line down until it reaches the botto! or the top of another fallen tetris piece.
&or (int i 2
board0i1 2 #etrominoes.-oS5ape;
/ The clearBoard,- !ethod fills the board with e!pty 7oSpapes. This is later used at collision detection.
&or (int i 2
; i O L; JJi) {
removeFull.ines();
i& (QisFallingFinis5ed)
new<iece();
/ The piece/ropped,- !ethod puts the falling piece into the board array. 3nce again& the board holds all the s;uares of the pieces and re!ains of the pieces that has finished falling. ,hen the piece has finished falling& it is ti!e to check& if we can re!ove so!e lines off the board. This is the #ob of the remo0e#ull!ines,- !ethod. Then we create a new piece. precisely& we try to create a new piece. ore
cur<iece.setDandomS5ape();
Created by dovari.sudheerkiran@gmail.com
cur<iece.setS5ape(#etrominoes.-oS5ape);
timer.stop();
isStarted 2 &alse;
statusbar.set#ext($game over$);
/ The new'iece,- !ethod creates a new tetris piece. The piece gets a new rando! shape. Then we co!pute the initialcur+ and cur9 values. If we cannot !ove to the initial positions& the ga!e is over. ,e top out. The ti!er is stopped. ,e put ga!e over string on the statusbar.
&or (int i 2
; i O L; JJi) {
i& (x O
XX x P2 ;oard8idt5 XX = O
XX = P2 ;oard9eig5t)
return &alse;
return &alse;
cur<iece 2 new<iece;
cur* 2 new*;
curG 2 newG;
repaint();
return true;
/ The tryMo0e,- !ethod tries to !ove the tetris piece. The !ethod returns false& if it has reached the board boundaries or it is ad#acent to the already fallen tetris pieces.
; 77i) {
&or (int j 2
; j O ;oard8idt5; JJj) {
line+sFull 2 &alse;
brea4;
Created by dovari.sudheerkiran@gmail.com
i& (line+sFull) {
JJnumFull.ines;
&or (int j 2
; j O ;oard8idt5; JJj)
/ Inside the remo0e#ull!ines,- !ethod& we check if there is any full row a!ong all rows in the board. If there is at least one full line& it is re!oved. +fter finding a full line we increase the counter. ,e !ove all the lines above the full row one line down. This way we destroy the full line. 7otice& that in our Tetris ga!e& we use so called naive gravity. This !eans& that the s;uares !ay be left floating above e!pty gaps. =very tetris piece has four s;uares. =ach of the s;uares is drawn with the drawS:uare,- !ethod. Tetris pieces have different colors.
g.set'olor(color.brig5ter());
g.draw.ine(x! =! x J sHuare8idt5() 7 >! =); The left and top sides of a s;uare are drawn with a brighter color. Si!ilarly& the botto! and right sides are drawn with darker colors. This is to si!ulate a 8. edge. ,e control the ga!e with a keyboard. The control !echanis! is i!ple!ented with a ;eyAdapter. This is an inner class that overrides the $ey'ressed,- !ethod.
case Be=)vent.3B,D+K9#I
brea4; If we pressed the left arrow key& we try to !ove the falling piece one s;uare to the left.
$igure< Tetris