• No results found

abstract windows toolkit swing

N/A
N/A
Protected

Academic year: 2021

Share "abstract windows toolkit swing"

Copied!
43
0
0

Loading.... (view fulltext now)

Full text

(1)

©nabg

GUI

abstract windows toolkit

swing

©nabg

GUI

• Graphical User Interface

– let user enter data for application

– let user control processing steps

– display a view of data to user

©nabg

Graphical User Interface

• Mostly or entirely made up using instances of

concrete classes provided in a graphics library

– “Window” class (Frame, JFrame in Java packages) – subregions (Panel, JPanel in Java packages, positioning using

“layout managers”)

– controls (scrollbars, radio-buttons, check-boxes, action-buttons, popup-menus, …)

– input fields (textfield)

– rich display formats (e.g. javax.swing has styled text, html text, tables, views of tree structures, …)

• Limited use of an application defined subclass of

some system class, used to render picture of

application data

©nabg

GUIs:

the problems

• Windows and graphics had been a major problem for

developers of applications that ran on multiple

platforms.

• Some concepts are common to all systems, but

implementation mechanisms vary substantially.

• Typically graphics/windowing code got interwoven into

application; major rewrite needed for reimplementation

on alternative platform.

©nabg

Common concepts

• Window hierarchy

– “framewindow”communicates with OS’s window manager

– subwindows

• Specialised controls

– usually (but not always) “subwindows” – button, checkbox, radio cluster, scrollbar, ...

• Graphics environment

– associated with each window

• Menu-bar with drop down menus

©nabg

Different implementations

• Windows

– Mac only the main window was known to OS – PC subwindows within main frame window

– Unix even things like thumb and arrows of scroll bar can be separate windows

• Controls

– slightly different functionality, eg scroll bars with/without proportional “thumbs”

• Graphics

– PC “graphics context”, Unix-X Graphics, and Macintosh Port have similar roles but differ in properties and associated function libraries

(2)

1996 – Java AWT

Graphics that will run everywhere!

AWT

objectives

• Platform independent application code

write once, run anywhere™

• Support “look and feel” of each

platform

write once, debug everywhere?

©nabg

AWT

• Define “Java” window classes

– limited, “lowest common denominator” of

different target platforms

• Write applications that work in terms of these

classes

• Objects that are instances of these classes are

essentially “proxies” - they interface to actual

worker objects that are platform specific.

©nabg

AWT

“peer” classes

Button Radio Checkbox Java Button Radio Checkbox Button Radio Checkbox Button Radio Checkbox Mac PC Unix created and used in

your Java application in Java code

created and used by the C code of the JVM

©nabg

AWT

“peer” classes

• java.awt.peer

– defines a set of “interfaces”

public abstract interface ButtonPeer extends ComponentPeer { public abstract void setLabel(String label);

}

• Each platform’s run-time system defines a

set of component classes that implement the

appropriate interfaces

– Mac’s button uses Quickdraw button – PC’s button uses Window’s button – X’s button uses Motif or OpenLook button

©nabg

AWT

“peer” classes

• Instance of java.awt classes created along with

instances of peer classes with which to work

• Runtimes for individual platforms include a

“component factory object” (the Toolkit object)

that has

– createButton(...), createCanvas(...),

createCheckbox(...), ...

• This run-time object creates the local version of

button (

or whatever other element was needed

)

(3)

©nabg

AWT & peers

• Peer mechanism provides

– required “look and feel”

– platform independence for rest of code

• Imperfect

– variation of functionality for “standard” GUI

components on different platforms makes total

“work alike” very difficult to achieve

©nabg

Swing!

• Different approach, less reliant on underlying OS.

• Essentially

– Swing asks OS for single window area

– Swing then takes total responsibility for window (does not take advantage of any ability that OS may have for rendering and handling events for subwindows) – Swing

• Get low-level details of events on its single window, sort out which conceptual subwindow (button, scrollbar, whatever) was involved, create Java event for that subwindow

• Get full access to entire window when drawing, draw buttons and other controls in accord with user preferences

©nabg

Swing – visual styles

• Swing can draw controls in different styles

• Default styles mimic appearance of controls

on host platform

• Can set user preferences to specify desired

style

©nabg

Swing caution

Swing GUI elements should only be

accessed via the thread supplied by the GUI

package.

So?

©nabg

Swing – thread issue

Usually this is not a problem.

Mainline thread constructs interface.

Mainline thread shows interface.

Subsequently, swing GUI elements are

automatically accessed via GUI thread.

But, sometimes, …

©nabg

Dynamic swing interface

Sometimes things are more dynamic

construct part of interface,

display it,

add more elements later

(can happen in JApplets when building

interface in JApplet.init())

Then

(4)

Dynamic interface – thread collision

Sometimes (

not when you are testing your code, when the marker – or your boss – is trying it

) get situation where

GUI thread does update at same time as

other thread tries to add an element to GUI

Result

possibly chaos

possibly deadlock

Fix – SwingUtilities.invokeLater

Ugly bits of code

Code to build interface essentially defines a

little runnable object that will make the changes

that add (or remove) GUI elements.

Reference to this thing passed in “invokeLater”

request to GUI framework.

Code gets run by GUI thread; eliminating risk

of deadlocks etc

©nabg

Ignore Swing problem for now

Too convoluted to bother with in our simple

exercises.

See:

http://java.sun.com/products/jfc/tsc/articles/thr

eads/threads1.html

NetBeans will help you build a safe swing

interface

©nabg

Graphics object

When you really need to draw a

picture!

Drawing basics – class Graphics and friends

©nabg

Graphics object

• Graphics object encapsulates details of drawing

environment for a window

public abstract class Graphics extends Object {

public abstract void clearRect(int x, int y, int width, int height); ...

}

• Concrete “Graphics” subclasses defined on

individual platforms

Same for Swing and AWT

Drawing basics – class Graphics and friends ©nabg

Graphics

• Different platforms do share

– similar coordinate models

• use ‘pixel’ coordinates for drawing to screen (printer driver will deal with changes in resolution)

• (0,0) is top left corner, x increases to right, y increased down

– similar range of functions

• draw: lines, outlines of rectangles and ovals, filled rectangles and ovals, outline and solid arcs, text strings

– similar (r, g, b) colour space

(5)

©nabg

Graphics

• Functionality provided by Graphics object

is less than typically available in “native”

graphic APIs for various platforms

– eg can’t specify line thickness (even though all

platforms do support such a concept)

Drawing basics – class Graphics and friends ©nabg

Graphics

• Graphics class defines methods

– draw

• drawArc(), drawBytes(), drawChars(), drawImage(), drawLine(), drawOval(), drawPolygon(), drawString(), drawRect(), drawRoundRect()

– fill

• fillArc(), fillOval(), fillPolygon(), fillRect(), ...

– set & get

• setColor(), getColor(), setFont(), getFont(), ...

– misc.

• clipRect(), clearRect(), copyArea(), setPaintMode(), ...

Check the package interface on line documentation for function prototypes and full list of properties Drawing basics – class Graphics and friends

©nabg

Graphics

• Related classes

– Font and FontMetrics

– Color

– Rectangle, Point, Polygon

– Image (and MediaTracker)

Drawing basics – class Graphics and friends ©nabg

Color, Font and Graphics

Text in selected font

Polygon, filled rectangle, oval, and arc, rect3D Outlines (rect, oval, round-cornered rect) and line Output to browser status bar Colours selected from “palette” Coord (0,0) Coord (400,450) ©nabg

Fonts

• Fonts are selected by name, size, and style

– create a new Font object as needed (

typical sloppy Java

programming, just forget about it when not needed; the garbage collector will tidy up for you

)

fFontName = fFontNames[n];

fFont = new Font(fFontName, Font.BOLD, 14);

Drawing basics – class Graphics and friends ©nabg

Fonts

• Java will have

-– Serif, SanSerif, Monospaced, Dialog, DialogInput

• Your system may have more, but if you are trying

to be portable then you had better not rely on there

being other Fonts.§

• Size is “point size”

• Styles defined by Font constants

FONT.BOLD, FONT.ITALIC, FONT.PLAIN §Java can use Windows fonts, and there are lots installed by Windows

(6)

Colors

• Colors (

Colours for those who spell in English

)

– several different approaches to specifying colours)

• “red”, “green”, “blue” • hue, saturation, brightness • luminance and two chrominance

– computer terminals usually employ rgb

• Create Color objects as needed, specify rgb

values (each in range 0...255)

-fColor = new Color(135, 206, 235); // sky blue

Drawing basics – class Graphics and friends

Colors

• Class Color has some predefined color

constants

– black, blue, cyan, darkGray, gray, green,

lightGray, magenta, orange, pink, red, white,

yellow

• SystemColor class has colors used by default for things like color of window frame, border color for caption text, ...

Drawing basics – class Graphics and friends

©nabg

Colors

• There are several hundred “standard colors” (

eg

palette defined for Xlib, but not provided as inherent part of Java libraries

)

• “Standard” colours, defined by rgb values (

see

/usr/openwin/lib/rgb.txt on Unix

)

255 235 205 blanched almond 255 228 196 bisque 255 218 185 peach puff 255 222 173 navajo white ...

Drawing basics – class Graphics and friends ©nabg

GraphicsDemo

• Trivial applet,

<HTML><TITLE>A Graphic Demo</TITLE> <BODY>

<APPLET ALIGN=MIDDLE CODE="GraphicDemo.class" WIDTH=400 HEIGHT=350>

</APPLET></BODY></HTML>

• GraphicDemo extends Applet impements Runnable

– this one has a “thread” that every second redraws the

image using a different colour and font

Drawing basics – class Graphics and friends

©nabg

GraphicsDemo

• Using a separate thread (locus of control)

• Main thread just sitting in code that handles

user interaction, updates of screen etc

• Second thread in loop with following form

– pick next colour

– pick next font

– force a repaint

– sleep for two seconds

Drawing basics – class Graphics and friends ©nabg

import java.awt.*; import java.applet.*;

public class GraphicDemoextends Applet implements Runnable

{

public void paint(Graphics g) { ... }

public void run() { ... } public void start() { ... } public void stop() { ... } public void init() { ... }

private String[] fMessageList = { "Hello World", "Hi mom", "Buy now",

"Fresh Java", "Write once, run everywhere", "Hype", "WWW rules OK" };

private String[] fFontNames = { "SansSerif", "Serif", "Monospaced",

"Dialog" };

// Color palette names and matching r, g, b values

(7)

©nabg

public class GraphicDemo extends Applet implements Runnable {

...

// Color palette names and matching r, g, b values private String[] fColorPalette = {

"lemon chiffon",..., "rosy brown", };

private int fR[] = { 255, ..., 188, };

private int fG[] = { 250, ..., 143, };

private int fB[] = { 205, ..., 143, };

// private data members ...

Drawing basics – class Graphics and friends ©nabg

public class GraphicDemo extends Applet implements Runnable {

...

// private data members private String fMessage; private Color fColor; private String fColorName; private Font fFont; private String fFontName; private Thread fThread; private boolean fRunning; private Polygon fPoly; }

Drawing basics – class Graphics and friends

©nabg

public void paint(Graphics g) {

if(!fRunning) return; // watch out for initial drawing

g.setFont(fFont); g.setColor(fColor); g.drawString(fMessage, 40, 50); g.drawString(fFontName, 40, 80); g.drawString(fColorName, 40, 110); g.setColor(Color.black); g.drawRect(10, 5, 25, 30); g.drawRoundRect(20, 130, 100, 40, 8, 8); g.drawRoundRect(20, 180, 100, 40, 16, 16); g.drawOval(150, 130, 40, 40); g.setColor(fColor); g.fillRect(210, 130, 25, 19); g.fillOval(210, 150, 30, 80); Parameters control curvature of corners

Drawing basics – class Graphics and friends ©nabg

public void paint(Graphics g) { ...

g.fillOval(210, 150, 30, 80);

g.drawLine(5, 190, 300, 100); g.fillArc(160, 210, 50, 50, 15, 170);

if(Math.random()>0.5) g.drawPolygon(fPoly);

else g.fillPolygon(fPoly);

if(Math.random()<0.5) g.draw3DRect(260, 260, 40, 30, Math.random() > 0.5); else g.fill3DRect(260, 260, 40, 30, Math.random() > 0.5); } Bounding box

Initial & size arc angles

Drawing basics – class Graphics and friends

©nabg

Color, Font and Graphics

Text in selected font

Polygon, filled rectangle, oval, and arc, rect3D Outlines (rect, oval, round-cornered rect) and line Output to browser status bar Colours selected from “palette” Drawing basics – class Graphics and friends

©nabg

public void start() {

fThread = new Thread(this); fThread.start();

}

public void stop() {

fThread.stop(); }

public void init() { fRunning = false;

fPoly = new Polygon();

fPoly.addPoint(210,10);

...

fPoly.addPoint(208, 72); }

(8)

public void run() {

for(int i=0;i<50;i++) { int n;

showStatus("loop " + i);

n = i % fMessageList.length; fMessage = fMessageList[n]; n = i % fFontNames.length; fFontName = fFontNames[n]; fFont = new Font(fFontName, Font.BOLD, 14);

n = i % fColorPalette.length; fColorName = fColorPalette[n]; fColor = new Color(fR[n], fG[n], fB[n]);

fRunning = true;

repaint();

try { Thread.sleep(2000); } catch (InterruptedException ie) { }

} }

Drawing basics – class Graphics and friends

FontMetrics

• Unlikely to need to use this class in routine

graphics displays.

• Use Font.getFontMetrics() to get FontMetrics

object for chosen font.

• FontMetrics object can then provide detailed

information relating to

– length of a String (displayed in that Font) – height of a character

– position (to text base-line) of top/bottom of character – ...

Drawing basics – class Graphics and friends

©nabg

FontMetrics

• Used mainly with relatively complex text

passages

where

you need text in different

fonts

,

sizes

, and styles

styles.

• Such text gets output as several strings,

each with specified font settings.

• Need to know position of end of one piece

of text before can position next piece.

Drawing basics – class Graphics and friends ©nabg

FontMetrics

Font myFont = new Font(“Serif”, Font.BOLD, 32); FontMetrics measure = new FontMetrics(myFont); int spacewidth = measure.stringWidth(“ ”); ...

int height = 50; int pos = left;

g.drawString(s1, pos, height);

pos = pos + spacewidth + measure.stringWidth(s1); int len2 = measure.stringWidth(s2);

if(pos + len2 > limit) { pos = left; height+= vspace; } g.drawString(s2, pos, height);

Drawing basics – class Graphics and friends

©nabg

FontMetrics

• Positioning of text can be more elaborate

– varying line spacing to suit text etc.

This is text with some odd characters

like ∫

and

fi

fi

fl

§, ¢, Ç, T, g,™, ¿, pq

Â

And more

ζ

ξ

p

⎟⎟ ⎞ ⎞⎞

A

baseline, height, ascent, descent, leading, ...

Drawing basics – class Graphics and friends ©nabg

Use swing if you need fancy text

You can do your own fancy text output

using FontMetrics

but, if you are just displaying text (and not

some complex mixture of text and other

graphics), you will find it much easier to

use a styled text output class from the swing

libraries

(9)

©nabg

Images

• Images

– gif or jpeg pictures

– loaded from file (local, or accessed via network)

• Image can be drawn in original size, or you can

specify size and system will scale image for

you

Graphics.drawImage(Image, int x, int y, ImageObserver)

Graphics.drawImage(Image, int x, int y, int width, int height, ImageObserver)

Drawing basics – class Graphics and friends ©nabg

Images

• Oddity

– getImage()

doesn’t get an Image!

It starts the process of fetching image then

returns (bytes for image may take some time to

arrive across net)

• Code has to deal with this behaviour

– “ImageObserver” gets called regularly as data

arrive, can then repaint a bit at a time

– “MediaTracker” can be set to delay main

thread until data are complete

Drawing basics – class Graphics and friends

©nabg

Watching images load

• Originally, I had a little demonstration at this point that showed a picture being loaded

• You could actually see successive lines of the image being drawn

• Networks and computers are so fast these days that the demo no longer works!

The picture appears “instantaneously”.

• Still have to use ImageObservers

• Still have to use MediaTrackers

– Often best approach is to load all images during program initialization, using a MediaTracker to make program wait until all are loaded

Drawing basics – class Graphics and friends ©nabg

MediaTracker

• Create a MediaTracker to work with the

ImageObserver object that is loading.

• Give MediaTracker a reference to each of

the images that it is to monitor

– associate an ID with each

– ID can act as a priority (lower numbered IDs should get dealt with first)

• Tell MediaTracker to delay until specified

Image has arrived (or delay until all arrived)

Drawing basics – class Graphics and friends

©nabg

MediaTracker

public void init(){

String picture = getParameter("picture"); if(picture == null) return;

fImage = getImage(getDocumentBase(), picture);

MediaTracker waitForIt = new MediaTracker(this); waitForIt.addImage(fImage, 1);

try { waitForIt.waitForID(1); } catch (InterruptedException ie) { }

}

Drawing basics – class Graphics and friends

Code fragment from an Applet – “this” references the Applet, which is an ImageObserver

©nabg

Superimposing images

---animations etc

• Typically, an animation (e.g. a computer

game) will have irregularly shaped objects

moving across a fixed background.

• Images typically are defined by rectangles.

• Don’t want a blacked out rectangle

surrounding each game piece.

(10)

Superimposing images

---animations etc

• Graphics systems allow you to avoid this by

defining

– not just red, green, blue values of each pixel

– but also “transparency”

• If a pixel is completely transparent, you see the

colour of any background pixel.

• If pixel is completely opaque, you see its r,g,b

colour

• Otherwise you see some mixture of colours

Drawing basics – class Graphics and friends

Superimposing images

---animations etc

• The “transparency” is the “alpha channel” of a

pixel

– red, green, blue, alpha

• It is possible to adjust an Image in your Java

code

– create a PixelGrabber from your Image

– make vectors of r,g,b and a values (each horizontal scanline appends to vector), fill using PixelGrabber

– you adjust ‘alpha’ values of chosen pixels – you create a new Image using modified array

Drawing basics – class Graphics and friends

©nabg

Superimposing images

---animations etc

• Often easier to use one of tools that works

with “gif” files and defines a (single)

chosen colour as being transparent.

Picture supposedly represents leaping frog

(it is a 32x32 block, blacked out, then picture drawn in a paint program)

Define “black” as transparent (this will be an option in a “gif” manipulation program)

This demo doesn’t work in all browsers (it should though).

Drawing basics – class Graphics and friends ©nabg

Superimposing images

---animations etc

• “Frog” can now be imposed on any

background picture

+

=

Drawing basics – class Graphics and friends

©nabg

HTML for Animation

<HTML>

<TITLE>A simple animation/transparent gif demo</TITLE> <BODY>

<APPLET ALIGN=MIDDLE CODE="AnimDemo.class" WIDTH=400 HEIGHT=350>

<PARAM NAME="actor" VALUE="./images/frog.GIF"> <PARAM NAME="bkgd" VALUE=

"./images/background.GIF"> </APPLET>

</BODY></HTML>

Drawing basics – class Graphics and friends ©nabg

Animation

• Load background and moving image(s) (sprite)

• Wait till both loaded

• Create thread

• Run thread

– move sprite (here just has approximate sine wave to define motion)

– force repaint – sleep

(11)

©nabg

Animation

• Need to do own “clipping”

- don’t want sprite

to appear outside of background image

• Flicker?

– use double buffering scheme if do have flicker

problems

• “Continuous motion”?

– aim for about 24 repaints per second and small motions

Drawing basics – class Graphics and friends ©nabg

import java.awt.*; import java.applet.*;

public class AnimDemo extends Applet implements Runnable{

public void paint(Graphics g) { ... } public void start() { ... }

public void stop() { ... } public void run() { ...} public void init() { ... }

// private data ... }

Drawing basics – class Graphics and friends

©nabg

public void start() { fThread = new Thread(this); fThread.start(); } public void stop() { fThread.stop(); }

public void run(){

for(;;) {

dX += deltaX; if(fX+dX > getSize().width) dX = 0; dY += deltaY;

if(dY <= -32) deltaY = 8; else if(dY >= 16) deltaY =- 8; repaint();

try { Thread.sleep(500); } catch (InterruptedException ie) { } }

}

Move “frog” across full width of Applet’s window (maybe wider than background).

Position defined by dX, dY offsets to start point; limited ranges defined.

Two frames per second. Drawing basics – class Graphics and friends ©nabg

public void init() {

String picfilename = getParameter("actor"); fActor = getImage(getDocumentBase(), picfilename); picfilename = getParameter("bkgd");

fBackground = getImage(getDocumentBase(), picfilename);

MediaTracker waiter = new MediaTracker(this); waiter.addImage(fActor,1);

waiter.addImage(fBackground, 2); try { waiter.waitForAll(); } catch (InterruptedException ie) { }

fX = -32; fY = 48; dX = dY = 0; deltaX = 8; deltaY = -8; }

Drawing basics – class Graphics and friends

©nabg

public void paint(Graphics g){

g.clipRect(0, 0, fBackground.getWidth(this), fBackground.getHeight(this));

g.drawImage(fBackground, 0, 0, this); g.drawImage(fActor, fX+dX, fY+dY, this); }

Drawing basics – class Graphics and friends ©nabg

Animations

• Typical animation would use set of slightly

different images

• Each repaint operation would change to next

image from sequence

• Synchronisation mechanisms may be needed

– one thread will be updating record of where program has reached in sequence

– other thread may be trying to use image

(12)

Animations

• Part of new “Media” API

– sprites

• images that move across the background

– scripting

• specify how sprites

– get created/removed – move

– change through sequence of images – interact

– ...

Drawing basics – class Graphics and friends

Subwindow for drawing …

©nabg

Where to draw?

• Those examples simply output to the applet’s main

window (

equivalent for an application would be drawing on

“Frame”

)

• Generally, main window or frame has to hold many

different controls, output regions etc.

• Most programs will use a “Canvas” subclass for

graphic output

-– Canvas simply defines a drawing area occupying some part of enclosing window

– you subclass Canvas to provide an effective paint() function

©nabg

MyCanvas extends Canvas

• MyCanvas

– owns connection to data object (model in

model-view-control); data object has reciprocal

link back to MyCanvas

– has size set

– gets told to paint(), relays request to data object

• Associated data object

– when changed, invokes repaint() on associated

MyCanvas

©nabg

awt and swing again

• AWT –

– designers thinking of • frame

• some standard controls

• Canvas where draw application specific data

• Swing

– different view, most Java is used in “enterprise” (business) computing, need is for lots of displays of text in tables etc

• frame • standard control • fancy text outputs

• No provision for drawing application specific data

©nabg

No Canvas in swing

Swing omits canvas

Can use JPanel

some issues about setting size

•(a Panel, or JPanel, is a container for other components; it recomputes its size when overall window size changed; it recomputes its size by asking the components it contains for their sizes; JPanels with no components can get zero size!)

(13)

©nabg

User interface

©nabg

User interface

• Most of user interface made up from library

supplied classes

– controls – input fields

• Canvas (or javax.swing.JPanel) displaying

application data would only be a limited part (

and may not be needed at all if application is conventional business data processing one with form entry and tabular results displays

)

©nabg

User interface

• Typical user interface has main window

with multiple subwindows

– output subwindows

• scrollable text, canvas for graphics, ...

– data input

• text input field, canvas again (can pick up mouse clicks and have program interpret as drawing action)

– control

• checkboxes, action buttons, radio selection, scroll bars, menus, ...

©nabg

Interface design

placing elements within window

©nabg

“Layout managers”

How can you arrange subwindows?

• Traditionally, programmers used absolute coordinates

and sizes.

• This did not suit AWT

– size of a “checkbox” (and almost every other control) would differ from one platform to another

– area occupied by text strings, bounding boxes etc vary

• An arrangement that looked fine on one platform

might be unusable on another.

©nabg

Layout managers

• Somewhat similar problems had been encountered

earlier with the Xlib- libraries for graphics outputs

on Unix systems.

• There solution had been for programmers to

surrender (to code provided with the library) some

the fine control of arrangement of components.

• AWT adopted this approach (swing follows, adds

(14)

Layout managers

• When building interface (awt or swing)

– you choose one of a small number of standard

arrangements for subwindows

– you create a “layout manager” object - an instance

of a class that

• keeps track of subwindows and their (minimum) sizes • chooses how to position them in the enclosing window

– you associate this layout manager with the window

It is possible to specify that you do not want to employ a layout manager, and position subwindows yourself. Generally regarded as hacking.

Layout managers

• The different “Window” classes (Frame,

Panel/Applet etc) have default layout

managers.

– layout manager actually associated with “container” level in class hierarchy (superclass to window)

• Container has

– setLayout(LayoutManager m)

– add(Component c)

– add(Component c, constraints)

©nabg

Flowlayout

Frame with a FlowLayout manager components rearrange if user resizes Frame

Canvas No Yes Maybe Canvas No Yes Maybe ©nabg

BorderLayout

• Add components specifying region names

as “constraints” (

forgot the name? put in center

)

North South Center E a s t W e s t ©nabg

Advanced Layouts

• GridLayout

(

illustrated later in calculator example

)

n x m

array of slots for components

– successive add() operations fill out rows

• CardLayout (

not illustrated

)

– displays one component from a set,

– functions like first(), next(), previous(), last(), to

cycle through components

©nabg

Advanced Layouts

• GridBagLayout (

illustrated later in dialog example

)

– complicated layouts,

best used in conjunction

with an interface builder tool

– grid of cells, but individual components can

occupy different number of cells

(15)

©nabg

GridBagLayout

• Component is added to container along with a

“GridBagConstraints” object

• GridBagConstraints specifies

– number of grid cells allocated to component (gridwidth,

gridheight constraint properties)

– position of component within its area defined (achor

property)

– fill property (does component resize to fit display area

horizontally, vertically, or both)

– padding around components (insets and ipadx, ipady)

– how display areas resize if enclosing window changes

©nabg GridBagConstraint x =0, y =0 width = 1, height =2 GridBagConstraint x =0, y =2 width = 3, height =1 GridBagConstraint x =3, y =0 width = 2, height =3 ©nabg

Swing and layouts

• Swing shares all AWT’s standard layouts

• Swing defines a few additional ones

– e.g. BoxLayout

• Better than JPanel (or AWT Panel) for grouping several components and arranging them (vertically or horizontally)

– others like SpringLayout, ViewPortLayout –

see Sun’s examples for use

©nabg

Create your user interface

©nabg

Creating your user interface

• Development environment (

eg NetBeans

) may

provide an editing tool that helps you arrange

parts of your interface

• If you don’t have an editing tool, or you want

more control, you will need to compose the

code that builds your interface

– create components, place within layout managers ...

Create your user interface ©nabg

Be aware of restrictions

• Container may only allow one component

North South Center E a s t W e s t Each of areas, North …

Center can be empty or hold one nested component

(16)

Use nested containers

North South Center E a s t W e s t

You want two labelled buttons here (4 components)? Have to add a nested Panel (JPanel) container

Create your user interface

Use nested containers

North South Center E a s t W e s t

Overall frame with BorderLayout

Added Panel (JPanel)

(J)Label (J)Button (J)Label (J)Button

Controls added to Panel (which has FlowLayout)

Create your user interface

©nabg

Creating your user interface

• There is a nesting hierarchy

– you choose a layout for top-level frame

• you place a “Panel” as one of components in this frame, (occupying one of positions in its ‘slots’ as defined by chosen layout manager)

– you select a layout for the Panel

• you place other components inside Panel

• This allows complex interfaces with large

output areas, arrays (palettes) of controls,

status information lines etc

Create your user interface ©nabg

Creating your user interface

• Events from controls

– you handle your controls by attaching

“listeners” to them when you create them

Create your user interface

©nabg

Only listener for events you want to

handle

• Things like textboxes, scrollbars, checkboxes etc

generate events for every change.

• Rare for your application to need to be aware of

these changes –

– A text box will look after all editing operations without your intervention.

• Typically you only want final values

• Listen only to the ActionButtons

– when user clicks “Do It Now” button, your application interrogates text boxes, checkboxes, scrollbars etc for chosen values

Create your user interface ©nabg

So, creating an interface

(17)

©nabg

Two issues to consider

Needs of your application

– GUI’s role

• Input of data • Controls on processing • Output of results

– What are you inputs?

– What processing controls do you need? – What output data must you display?

Building blocks available in GUI library

Create your user interface ©nabg

GUI library

• Containers and simple components

• You start with one container

– The Window (Frameor JFrameclass)

• You divide up area of window

– Area for input fields and controls – Area for outputs

• Each such area has many components, so it must

be represented by another container (Panel,

JPanel, Box

or other container used for

sub-window)

Create your user interface

©nabg

GUI interface – first decisions

• Frame’s area is split in areas

– Each area usually occupied by another

container (Panel, whatever)

– Arrangement of areas in main Frame dictated

by a layout manger

Create your user interface ©nabg

GUI interface - next

• Your needs for input data and controls

– Select some processing option?

• Select from pop-up list? • Select using check boxes?

– Text data input?

• Simple text input? • Large area of text?

– Select file?

• Action button displays file dialog

– Start processing

• Action button

Create your user interface

©nabg

Compose input & control elements

• Many input elements?

– “Container” (Panel) used for input elements

must be given some layout manager

– Different input components must be selected to

handle inputs required by application

– Input components must be added to container,

layout manager given “hints” on layout

Create your user interface ©nabg

Outputs

• What are the output data?

• Do you really have one output field or many?

• For each output field

– Can you use one of standard data display classes

• TextArea (possibly scrolling if a lot of text) • Table

• Tree

• How can you arrange outputs

– Container again (Panel) – Layout manager

(18)

Building blocks for interfaces

Containers

Containers

• Container

– Panel

• Applet

– ScrollPane

– Window

• Dialog

– FileDialog

• Frame

AWT,

javax.swing has JPanel, etc

©nabg

Containers

• Window

– A Window object is a top-level window with no borders and no menubar.

• Frame

– A Frame is a top-level window with title and border; default layout is BorderLayout.

• Dialog

– A window that takes input from the user. – FileDialog

• Mimics “standard” modal file selection dialog as commonly used on platform.

• Panel

– Panel is the simplest container class. A panel provides space in which an application can attach any other component. The default layout manager for a Panel is FlowLayout.

©nabg

Components

• Component

– Button

– Canvas

– Checkbox

– Choice

– Label

– List

– Scrollbar

– TextComponent

• TextArea • TextField AWT,

javax.swing has JLabel, etc

©nabg

Components - Button

• Button

– owns two strings (

label, action name; same by default

)

• set/get ... …Label(), …ActionCommand() • normal constructor sets both: Button(String s)

– addActionListener(...)

– simple request for action by program (

like earlier example where had North, East, ... buttons that moved

figure that was displayed in Canvas

)

(19)

©nabg

class DataObject implements ActionListener { }

class MyCanvas extends Canvas { ... }

class Display implements WindowListener { ...} public class EventDemo1 {

public static void main(String args[]) { ... } } ©nabg

class DataObject {

public void actionPerformed(ActionEvent e) {

String s = e.getActionCommand();

if(s.equals("North")) { fY0 -= 5; fCanvas.repaint(); } ... else if(s.equals("West")) { fX0 -= 5; fCanvas.repaint(); } } ©nabg

class Display

public Display(DataObject d) {

fFrame = new Frame();

fFrame.setLayout(new FlowLayout()); fCanvas = new MyCanvas(d);

d.LinkToCanvas(fCanvas); fFrame.add(fCanvas); Button b;

b = new Button("North");

b.addActionListener(d); ... ©nabg

• Component

Button

– Canvas

– Checkbox

– Choice

– Label

– List

– Scrollbar

– TextComponent

• TextArea • TextField ©nabg

Components – Canvas

• Canvas (

must be subclassed!

)

– just a blank rectangular drawing area

• paint data objects • trap mouse actions

– typically MyCanvas extends Canvas will add a

pointer to some data object(s) that is(are) to be

displayed, and will override paint()

class MyCanvas extends Canvas {

public MyCanvas(DataObject d) { fData = d; setSize(400, 400); } public void paint(Graphics g) { fData.paint(g); }

private DataObject fData; }

©nabg

Components – Canvas

• Canvas used directly in program?

– You will see textbook examples where programmer

• creates Canvas

• gets Graphics object associated with Canvas • arranges for data structure to draw on Graphics

– I don’t think this is really correct

• it probably won’t handle updates properly (eg when window hidden then re-exposed) - as simply get call to Canvas.paint() { } • violates normal convention of not drawing directly, instead notifying

display of need for update then being asked to draw when display ready

(20)

No JCanvas?

Swing doesn’t include anything directly

equivalent to Canvas

have to subclass JPanel

•provide link to data object

•overwrite paint function

•mess around with setSize, setPreferredSize, and setMinimumSize (JPanels aren’t like Canvases, they try to recompute their sizes based on what they contain and have a habit of shrinking!)

• Component

Button

Canvas

– Checkbox

– Choice

– Label

– List

– Scrollbar

– TextComponent

• TextArea • TextField ©nabg

Components - Checkbox

• Checkbox handles two roles:

– ordinary check box (a choice that is either

selected or not selected; selection independent of

other choices)

– “radio button” (an instance of a mutually

exclusive set of choices)

• Differentiate roles according to whether

Checkbox has an associated CheckboxGroup

©nabg “Stopwatch” example ©nabg Frame BorderLayout ©nabg FlowLayout South – a Panel Frame East – a Panel FlowLayout BorderLayout

(21)

©nabg FlowLayout South – a Panel Frame East – a Panel FlowLayout Canvas BorderLayout ©nabg FlowLayout South – a Panel Frame East – a Panel FlowLayout Canvas Two checkboxes Three buttons BorderLayout ©nabg

Stopwatch

(“ComponentsDemo1”)

• Illustrating

– border layout

• panels (with default flow layout) as subcomponents

– action buttons

– canvas

– mutual exclusion “radio buttons” in a

CheckboxGroup

– also more “Threads” (

to be explained in detail later

)

©nabg

import java.awt.*; import java.awt.event.*;

class StopWatch implements ActionListener, ItemListener, Runnable { … }

class MyCanvas extends Canvas { … }

class GUI implements WindowListener { … } public class ComponentsDemo1 {

public static void main(String[] args) { StopWatch c = new StopWatch(); GUI g = new GUI(c);

g.show(); } } ©nabg

ComponentsDemo1 : Application

• ComponentsDemo1

– simply provides main()

• create principal objects • get things run

• MyCanvas

– the usual, subclass Canvas to get something

with effective paint()

– uses double buffered update()

©nabg

ComponentsDemo1 : Application

• GUI

– builds the interface

• create Frame (with default BorderLayout) • create

– MyCanvas, places MyCanvas in center

– three action buttons, panel to hold buttons, places panel in “south”

– two Checkboxes, with CheckboxGroup, another panel to hold them, places panel in “east”

– and handles closing of window by termination

application

(22)

ComponentsDemo1 : Application

• StopWatch

– handles

• actions involving stop, start, reset buttons • changes to “Analog” / “Digital” choice items

– has internal thread

• suspended and resumed as needed

• while running does (sleep (1000/60), update ticks

etc, maybe force repaint)

– draws clock in analog or digital form

1000/60 16, don’t expect it to keep perfect time

ComponentsDemo1 : Application

• StopWatch

– 60 ticks per second, 60 seconds per minute

– digital display

• as string, • minutes:seconds, • only updated every second

– analog display

• three hands • updated at each tick

©nabg

“Stopwatch” example

©nabg

import java.awt.*; import java.awt.event.*;

class StopWatch implements ActionListener, ItemListener, Runnable { … }

class MyCanvas extends Canvas { … }

class GUI implements WindowListener { … } public class ComponentsDemo1 {

public static void main(String[] args) { StopWatch c = new StopWatch(); GUI g = new GUI(c);

g.show(); }

}

©nabg

class MyCanvas extends Canvas {

public MyCanvas(StopWatch c) { fStopWatch = c; setSize(400, 400); }

public void paint(Graphics g) { fStopWatch.paint(g); }

public void update(Graphics g) {

Graphics gr; if (fOffScreenBuffer==null || (! (fOffScreenBuffer.getWidth(this) == this.getSize().width && fOffScreenBuffer.getHeight(this) == this.getSize().height))){ fOffScreenBuffer = this.createImage( getSize().width,getSize().height); } gr = fOffScreenBuffer.getGraphics();

gr.clearRect(0,0, getSize().width, getSize().height); paint(gr);

g.drawImage(fOffScreenBuffer, 0, 0, this); }

private Image fOffScreenBuffer; private StopWatch fStopWatch; }

uses “double buffering”

Make sure have buffer Use it copy ©nabg

Offscreen buffer code

• Check whether have an offscreen buffer

with the same dimensions as drawing area,

if don’t have one at all (or its size is wrong)

then create offscreen buffer.

• Get a Graphics object associated with the

offscreen buffer.

• “Draw” data using that Graphics.

• Copy completed image to screen

(23)

©nabg

Double buffering – why?

Problem

Your data is changed

You must erase the existing display

You must draw the new data

The screen flickers irritating users.

• Only really an issue if you are composing a picture of your own data and you update this frequently; very rare to have to worry about it if your interface is entirely made up of standard awt/swing classes.

©nabg

Double buffering – how?

Create an “image” in memory – one pixel (4

bytes in memory) for each pixel on screen

“Erase” the in-memory image

Draw into the in-memory image

Paint to screen

Result – no flicker

©nabg

class GUIimplements WindowListener {

public void windowClosing(WindowEvent e) { System.exit(0); }

public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowOpened(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { }

public GUI(StopWatch c) { … } public void show() { fFrame.show(); } private Frame fFrame;

private MyCanvas fCanvas; private StopWatch fStopWatch; }

WindowListener stuff as previously illustrated

©nabg

public GUI(StopWatch c) {

fStopWatch = c;

fFrame = new Frame();

fFrame.setLayout(new BorderLayout()); fCanvas = new MyCanvas(c);

c.LinkToCanvas(fCanvas);

fFrame.add(fCanvas, "Center"); Panel p = new Panel();

fFrame.add(p,"South"); Button b; b = new Button("Start"); b.addActionListener(c); p.add(b); b = new Button("Stop"); b.addActionListener(c); p.add(b); b = new Button("Reset"); b.addActionListener(c); p.add(b); …

Setting layout manager explicitly; didn’t need to, BorderLayout is default for Frame

©nabg South – a Panel Frame Canvas fFrame.setLayout(new BorderLayout());ut fCanvas = new MyCanvas(c); c.LinkToCanvas(fCanvas); fFrame.add(fCanvas, "Center");

Panel p = new Panel();

fFrame.add(p,"South"); Button b; b = new Button("Start"); b.addActionListener(c); p.add(b); … ©nabg

GUI building code

• Start with a Frame (a Window with all the

trimmings!)

• Set your layout manager

• Create the canvas class

• Add to the frame – hint to layout manager, this

goes in center

• Two Buttons each with Labels,

– need a Panel to group them

– Create labels and buttons, add to panel, listen to buttons

(24)

public GUI(StopWatch c) {

b = new Button("Reset"); b.addActionListener(c); p.add(b);

p = new Panel(); fFrame.add(p,"East");

CheckboxGroup grp = new CheckboxGroup();

Checkbox analog = new Checkbox("Analog",

grp, false);false

Checkbox digital = new

Checkbox("Digital", grp, truetrue); p.add(analog); p.add(digital); analog.addItemListener(c); digital.addItemListener(c); fFrame.pack(); fFrame.addWindowListener(this); } South – a Panel Frame East – a Panel Canvas

CheckboxGroup grp = new CheckboxGroup(); Checkbox analog = new Checkbox("Analog",

grp, falsefalse);

Checkbox digital = new Checkbox("Digital",

grp, truetrue);

p.add(analog); p.add(digital);

fFrame.add(p,"East");

©nabg

class StopWatchimplements ActionListener,

ItemListener, Runnable{ public StopWatch() { … }

public void LinkToCanvas(Canvas c) { fCanvas = c; } private void DoStart() {… }

private void DoStop() { … } private void DoReset() { … } public void paint(Graphics g) { … } public void run() { … }

public void itemStateChanged(ItemEvent e) {… } public void actionPerformed(ActionEvent e) { … } Thread fThread;

Canvas fCanvas;

boolean fAnalogStopWatch = false; boolean fRunning = false; int fMinutes, fSeconds, fTicks; }

©nabg

public StopWatch(){

fCanvas = null; DoReset();

fThread = new Thread(this); fThread.start(); }

public void LinkToCanvas(Canvas c) { fCanvas = c; } private void DoStart() {

if(fRunning) return;

fRunning = true; fThread.resume(); }

private void DoStop(){ if(!fRunning) return;

fRunning = false; fThread.suspend(); }

private void DoReset(){ if(fRunning) return;

fMinutes = fSeconds = fTicks = 0; if(fCanvas != null) fCanvas.repaint(); }

©nabg

public void paint(Graphics g) { if(!fAnalogStopWatch) {

String time = "" + fMinutes + ":" + fSeconds; g.drawString(time,40,40); }

else {

g.drawOval(20,20, 181, 181); double angle, armlength, x, y; armlength = 90;

angle = 6.0*fTicks; angle = angle*Math.PI/180.0; x = armlength*Math.sin(angle); y = armlength*Math.cos(angle); g.drawLine(111,111, 111+(int)Math.round(x),111-(int)Math.round(y)); g.setColor(Color.blue); armlength = 70; angle = 6.0*fSeconds; ... g.setColor(Color.red); armlength = 50; angle = 6.0*fMinutes; ... g.setColor(Color.black); } } ©nabg

paint

• Either

– output string with digits

– Draw a “clock face” working out where the

clock-hands should be for minutes, seconds etc

(25)

©nabg

public void run() { fThread.suspend(); for(;;) {

try { Thread.sleep(16); }

catch (InterruptedException ie) { } fTicks++; if(fTicks == 60) { fTicks = 0; fSeconds++; if(fSeconds == 60) { fSeconds = 0; fMinutes++; } } if(fAnalogStopWatch) fCanvas.repaint(); else if(fTicks == 0) fCanvas.repaint(); } } ©nabg

Thread

• (More on threads soon)

• Here

– Forever

• Sleep a bit • Update time

• Request repaint of display

©nabg

public void actionPerformed(ActionEvent e) { String s = e.getActionCommand(); if(s.equals("Start")) DoStart(); else if(s.equals("Stop")) DoStop(); else if(s.equals("Reset")) DoReset(); } ©nabg

public void itemStateChanged(ItemEvent e) {

if(e.getStateChange() == ItemEvent.DESELECTED) return;

String s =

(String) e.getItem();

if(s.equals("Analog")) fAnalogStopWatch = true; else fAnalogStopWatch = false;

if(!fRunning) fCanvas.repaint(); }

Will get double notification on change: deselect old, select new. Here only need to bother with the select new.

©nabg

Components - Checkbox;

continued!

• Independent choice Checkboxes used in

much the same way - just don’t provide a

CheckboxGroup.

• Arrange for an ItemListener that will deal

with ItemEvents as these are generated by

changes to individual Checkboxes.

©nabg

Component

Button

Canvas

Checkbox

– Choice

– Label

– List

– Scrollbar

– TextComponent

• TextArea • TextField

(26)

Components - Choice

• “Choice” is an alternative to having an interface

involving a large set of “radio buttons”.

• Choice

– holds a set of items (Strings)

– displays as a form of pop-up menu

– only allows one item to be selected

– sends itemEvents to ItemListener when selection

changed (

though usually easier to handle differently

)

– can be asked for current selection

©nabg ©nabg

Components - List

• List is a variation on Choice

– has a little scrolling subwindow showing some of

possible choices (you select how many)

– permits multiple selections (

mechanism depends on

platform – “shift-click”, “control-click”

)

– if single selection, can be asked for current

selection

– if multiple selections permitted, can be asked to

return array with Strings identifying items selected

©nabg

Components - Label

• Lists and Choices do not inherently possess

any identifying information in display.

• Usual to employ Labels to identify them.

• Place Label and Choice (List) in a Panel.

• Label

– displays a non-editable string (can be changed

by program)

©nabg

Example with labels, choices, lists

• “Breakfast order” dialog (

like those printed lists you find in

hotel rooms where you tick the items you want for breakfast

)

• No real layout – just a series of choices, lists, text

inputs in a window with FlowLayout

– But trying to keep Label/Choice, Label/List etc together – So do have extra Panel components to hold such pairs

(27)

©nabg

Swing

• List => JList

• Choice => JComboBox

(Some Microsofty person – combo-box was the VisualBasic equivalent)

©nabg

(action) Button Choicefrom pop-up menus (single item)

List(multiple selection enabled, showing 3 items from range of ≈9) Applet using “FlowLayout”

TextAreaused for output (set to ‘non-editable’) Labels ©nabg import java.awt.*; import java.awt.event.*; import java.applet.*;

public class ComponentsDemo2 extends Applet

implements ActionListener

{

public ComponentsDemo2() { ... }

public void actionPerformed(ActionEvent e) {... }

private Choice fChoice1; private Choice fChoice2; private List fList;

private TextArea fTextOutput; }

©nabg

public ComponentsDemo2() {

add(new Label("Pick one item in choices, many in list"));

Button b = new Button("Serve my meal");

add(b); b.addActionListener(this);

Panel p; p = new Panel(); add(p); p.add(new

Label("First course"));

Choice c; c = new Choice();

c.add("Grapefruit"); c.add("Orange juice"); c.add("Melon");

c.add("Corn flakes");

c.select("Corn flakes");

fChoice1 = c; p.add(c);

Can define a default selection

©nabg

Panel p; p = new Panel();

add(p); p.add(new Label("First course"));

Choice c; c = new Choice();

… p.add(c);

©nabg

Creating the elements

• Button

– Give it a label – Add a listener

• Group : Label – “First course”, Choice – with

options

– Create Panel to keep the two together – Create Label with string, add to Panel

– Create choice, create string options in choice, add choice to Panel, add Panel to Applet

(28)

...

p = new Panel(); add(p); p.add(new Label("Cooked course"));

List ll = new List(3, true);

ll.add("Boiled egg"); ... ll.add("Toast"); ll.select(0); ll.select(8); fList = ll; p.add(ll);

p = new Panel(); add(p); p.add(new Label("Beverage"));

c = new Choice(); c.add("Tea with lemon"); ... c.add("Coffee");

c.select("Coffee"); fChoice2 = c; p.add(c);

fTextOutput =

new TextArea("Breakfast: ",2, 60); fTextOutput.setEditable(false); add(fTextOutput);

}

Specify number of choices displayed, & whether multi-selections allowed

List & choice

• Generally similar in use

– Different appearance

– List has option of multiple selections

• Here

– Create List object (java.awt.List – a GUI component, not “List” as in datastructures!)

– Add elements (strings for choices offered by list) – Some can be marked as pre-selected

– Add to Panel etc

©nabg

public void actionPerformed(ActionEvent e){ String s = e.getActionCommand();

if(!s.equals("Serve my meal")) return; fTextOutput.append(

fChoice1.getSelectedItem()); fTextOutput.append(", ");

String[] mains = fList.getSelectedItems();

for(int i=0; i<mains.length;i++) { fTextOutput.append(mains[i]); fTextOutput.append(", "); } fTextOutput.append( fChoice2.getSelectedItem()); } ©nabg

actionPerformed

• Only one action button, so don’t need to see

what action requested.

• Read data from input fields.

• Use data to compose output.

• Display output text in TextArea

©nabg

ComponentsDemo2 example

• Approach illustrated is usually easiest

– have an action button to act when user has

made choices

– have references to Choice & List components,

ask for selections when needed

• Alternative implementation implements

ItemListener - get events for each selection

(and deselection)

©nabg

(29)

©nabg

NetBeans - awt

private void initComponents() { label1 = new java.awt.Label(); b = new java.awt.Button(); panel1 = new java.awt.Panel(); label2 = new java.awt.Label(); c = new java.awt.Choice(); c.add("Grapefruit"); …

©nabg

NetBeans GUI editor - swing

©nabg

NetBeans swing

• Has extra component editors for things like

tables, combo-boxes, lists

– Let you populate the control with a set of data

• Useful if set of options is fixed

• If generating content of control

dynamically, tell NetBeans to “Reset to

default” and use custom coding

©nabg

Component

Button

Canvas

Checkbox

Choice

List

– Scrollbar

– TextComponent

• TextArea • TextField ©nabg

Components - ScrollPane

• ScrollPane

– A container which implements automatic

horizontal and/or vertical scrolling of a single

child component.

– use

• create a ScrollPane • create a canvas • put canvas in ScrollPane

©nabg

Components - Scrollbar

• Scrollbar

– Allows user to select from a range of values

– Define as “HORIZONTAL” or “VERTICAL”

– Provide minimum, maximum (and initial value)

– Need an AdjustmentListener that will pick up

(30)

ComponentsDemo3

• Applet to display a large image such as a

map.

• Image displayed in a ScrollPane.

• Scrollbar used to provide zoom effect

– can scale basic image up or down

– ScrollPane adjusts to resized image

Scrollbars belonging to

ScrollPane (select position in map)

Scrollbar used to

change map’s own scale

©nabg

Effects of scaling the map –

©nabg

ComponentsDemo3

• Simple Applet (implements AdjustmentListener)

– init()

• select BorderLayout, add a label

• load the image (wait for loading to complete, can be slow for large map)

• create “MyCanvas”, ScrollPane, and Scrollbar • establish links amongst items

– adjustmentValueChanged()

• get user selected value (range [1...9], 5=>standard size, 4 is half size, 3 is quarter size, 6 is double size etc) • get “MyCanvas” to rescale

©nabg

import java.awt.*; import java.awt.event.*; import java.applet.*;

class MyCanvas extends Canvas {

public MyCanvas(Image i, ScrollPane s) { ... } public void paint(Graphics g) { ... }

public void setScale(int scl) { ... } // private data

... }

public class ComponentsDemo3 extends Applet implements AdjustmentListener

{

public void init() { ... }}

public void adjustmentValueChanged(AdjustmentEvent e)

{ ... }

private MyCanvas fCanvas; }

©nabg

public class ComponentsDemo3 extends Applet implements AdjustmentListener {

public void init() {

setLayout(new BorderLayout());

add(new Label("Map display", Label.CENTER), "North"); String picture = getParameter("picture");

if(picture == null) return;

Image i = getImage(getDocumentBase(), picture); MediaTracker waitForIt = new MediaTracker(this); waitForIt.addImage(i, 1);

try { waitForIt.waitForID(1); } catch (InterruptedException ie) { } ScrollPane s = new ScrollPane(

ScrollPane.SCROLLBARS_AS_NEEDED); fCanvas = new MyCanvas(i, s);

s.add(fCanvas); s.setSize(400,400); add(s, "Center");

Scrollbar b = new Scrollbar(

Scrollbar.HORIZONTAL, 5, 1, 1, 10); add(b, "South"); b.addAdjustmentListener(this); }

(31)

©nabg

Creating the scrollable canvas

• Create scroll pane, specifying it is to use scrollbars

only when needed

• Add canvas

• Set size for display in applet

ScrollPane s = new ScrollPane(

ScrollPane.SCROLLBARS_AS_NEEDED);

fCanvas = new MyCanvas(i, s);

s.add(fCanvas); s.setSize(400,400);

©nabg

public void adjustmentValueChanged(AdjustmentEvent e) {

int val = e.getValue(); fCanvas.setScale(val); }

©nabg

class MyCanvas extends Canvas {

public MyCanvas(Image i, ScrollPane s) { fImage = i; fSPane = s;

fEX= fX = i.getWidth(this); fEY = fY = i.getHeight(this);

setSize(fX, fY); }

public void paint(Graphics g) {

g.drawImage(fImage, 0, 0, fEX, fEY, this); } public void setScale(int scl) {... } private ScrollPane fSPane;

private int fScale = 5; private int fX, fY; private int fEX, fEY; private Image fImage; }

©nabg

public void setScale(int scl) { fScale = scl;

int posX = fSPane.getScrollPosition().x; int posY = fSPane.getScrollPosition().y; int oldfEX = fEX; int oldfEY = fEY; switch(scl) {

case 1: fEX = fX/16 ; fEY = fY/16 ; break; ...

case 9: fEX = fX*16; fEY = fY*16 ; break; }

setSize(fEX, fEY); fSPane.doLayout();

posX = (posX*fEX) / oldfEX; posY = (posY*fEY) / oldfEY;

fSPane.setScrollPosition(posX, posY); repaint(); } ©nabg

Component

Button

Canvas

Checkbox

Choice

List

Scrollbar

– TextComponent

• TextArea • TextField ©nabg

TextComponents

• TextComponent

– owns text, by default is editable

– does

• return current text as String • set insertion point

• select subset of text (by program) • get current selection (as made by user) • can pass on details of changes to text to a

References

Related documents