Nota Bene This lecture presentation contains a number of "hidden" slides. Feel free to read, study...

77
Nota Bene Nota Bene This lecture presentation contains a number of "hidden" slides. Feel free to read, study and learn from them on your own! (I openned them all)

Transcript of Nota Bene This lecture presentation contains a number of "hidden" slides. Feel free to read, study...

Nota BeneNota Bene

This lecture presentation contains a number of "hidden" slides. Feel free to read, study and learn

from them on your own! (I openned them all)

Today's Plan for FunToday's Plan for Fun

• Events– What is an event?– Simple (?) Example

• Swing Components– JFrames– JComponents– An example– Swing Component Design (MVC/UI-Delegate)

EventsEvents

• Behind the scenes the Java runtime environment is monitoring lots of things

• When any of a number of different things happen an event is said to occur. Sometimes the terminology is "An event gets fired"

• Examples of the types of things that can "fire" events– Pressing a key on the keyboard– Clicking on a component (like a button)– Entering a component with the mouse pointer– Have a timer "time-out"

EventsEvents

• Moving the mouse around any reasonably complicated GUI can literally cause hundreds if not thousands of events to occur

• They will be ignored except for the ones that you tell Java that you are interested in doing something about

• Java maintains a data structure of all the events that you have decided to handle and looks up events and does what you tell it to do.

Remember this???Remember this???

import java.awt.*;

public class HelloGUI {

public static void main (String[ ] arg) {

System.out.println

("About to make GUI");

Frame f = new Frame ("Hello GUIs");

f.setSize( 200, 200 );

f.show();

System.out.println

("Finished making GUI");

}// main

}// class HelloGUI

What didn't work???What didn't work???

Making it workMaking it work

• Determine which event occurs when the "Close the Window" button is pressed– The API is your friend– The lecture notes are your friend– Hint: In this case it's an event called "Window Closing"

• Decide what class is going to handle this event– It might be the actual class which has the window– It can be any other class

• Write the method (and class?) that will handle the event. When this event occurs Java is going to go to the class that you identify as the event handler or ListenerListener. It will look for a method called:

public void windowClosing(WindowEvent e)• Jave will be sorely annoyed if this class doesn't have this method.

How might the designers of Java guaranteed that you will implement this method?

An Interface!!!An Interface!!!

// Note: found in java.awt.event

public abstract interface WindowListener

extends EventListener

{

void windowActivated(WindowEvent e);

void windowClosed(WindowEvent e);

void windowClosing(WindowEvent e);

void windowDeactivated(WindowEvent e);

void windowDeiconified(WindowEvent e);

void windowIconified(WindowEvent e);

void windowOpened(WindowEvent e);

}

So we could write a class like thisSo we could write a class like thisimport java.awt.*;import java.awt.event.*;

public class Handler implements WindowListener{

public void windowActivated(WindowEvent e) {}public void windowClosed(WindowEvent e) {}public void windowClosing(WindowEvent e){

Window w = e.getWindow();w.setVisible(false);w.dispose();System.exit(0);

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

}

Making it work IIMaking it work II

• Register the listener with Java. That is, tell Java in which class the method will be located to run when the Window Closing Event occurs.

RegistrationRegistration

import java.awt.*;

public class HelloGUI

{

public static void main (String[ ] arg) {

Handler h = new Handler();

System.out.println ("About to make GUI");

Frame f = new Frame ("Hello GUIs");

f.setSize( 200, 200 );

f.addWindowListener(h);

f.show();

System.out.println("Finished making GUI");

} // main

} // class HelloGUI

DemonstrationDemonstration

DiagramaticallyDiagramatically

Class Pool

class HelloGUI main { Frame f Handler h }

class Frame

class Handler

FrameInstance

HandlerInstance

Interface WindowAdapter

Key IdeasKey Ideas

• Determine which event occurs

• Decide what class is going to handle this event

• Write the method (and class?) that will handle the event.

• Register the listener with Java.

Questions?Questions?

Very important that you understand this simple example to understand the concepts that follow.

Potential Points of PerplexionPotential Points of Perplexion• What exactly is the listener? Is it the component getting clicked

on?– No, the listener is the object that contains the method that Java

will call when the event happens.– You must tell the component getting clicked which object that

is by registering: addWindowListener...– As we will see it could be the same!!!

• How will I know what type of listener to use?– There are only so many– The API– Lecture/Instructor/Recitation/TA/etc.– Experience!

• What about all those other window things (e.g. windowActivated)– We actually did implement them– We said: Don't do anything!

Questions?Questions?

Today's Plan for FunToday's Plan for Fun

• Events– What is an event?– Simple (?) Example

• Swing Components– JFrames– JComponents– An example– Swing Component Design (MVC/UI-Delegate)

1.1.1.

2.2.2.

J ava’s GU I Capabilit iesJ ava’s GU I Capabilit ies

Java provides essentially two related toolkits formaking GUIs:

The Abstract Windowing Toolkit (“AWT”), and

The Java Foundation Classes (“Swing”)

Swing is merely a new, improved version of the AWT,and still uses some of AWT’s features.

1.1.1.

2.2.2.

J ava’s GU I Capabilit iesJ ava’s GU I Capabilit ies

Java provides essentially two related toolkits formaking GUIs:

The Abstract Windowing Toolkit (“AWT”), and

The Java Foundation Classes (“Swing”)

Swing is merely a new, improved version of the AWT,and still uses some of AWT’s features.

RecallRecall

Earlier, we cautioned aboutthe existence of two toolkitsin Java for creating GUIs:

AWTAWT

SwingSwing

Today, we examine a few Swing components.

The goal is to learn how Swing components in general are designed, so that you can make better use of the API.

That Which SwingsThat Which Swings

In 1997, Sun announced a new graphical toolkit for Java calledthe “Java Foundation Classes”, or “JFC”.

This term is usually pronounced “Swing”.

The JFC/Swing classes provide well designed, powerful widgets for GUI developers.

Let’s take a look . . .

JFC/SwingJFC/Swing

““Now it gets interesting . . . “Now it gets interesting . . . “

(De)Motivation(De)Motivation

0.0.

Historical Problems with AWTHistorical Problems with AWT• All AWT components required runtime peer resources

– slow on some platforms (notably Windows)– portability problems (slightly different look, some behaviors different)– least common denominator phenomenon: If one OS (e.g., Windows)

did not support a widget, the entire AWT had to suffer without it.• Limited AWT widget library

– addressed somewhat by JDK 1.1b3+, which allowed subclassing of components, or “lightweights”

java.awt.Button

WinNTButtonPeer

MacOSButtonPeer

MotifButtonPeer

ButtonPeer

AWT components requiredAWT components requirednative “peer” methods tonative “peer” methods torender and operate--many steps!render and operate--many steps!

CLICK ME

File Edit Help

Slow & Inflexible!

Stop-gap remedies for JDK 1.1b3+Stop-gap remedies for JDK 1.1b3+

• Developers avoided a few AWT limitations through:– Pervasive use of lightweights– e.g., tooltip simulation through threads/windows/components– extensive coding around rigid look– use of layered gifs

CLICK ME

File Edit Help

Tooltip

(Tooltips requiredthreads,window subclasses &extensive event handling)

(Image buttons requiredcomponent subclassing,methods to handle ‘click’look, as well as eventhandlers)

(Menu bars limited;no images possiblewithout *extensive*simulation throughcomponents)

(Layering of componentsrequires layoutsubclasses)Bottom line: Making stuff look cool

or satisfying a clients requestcould be a nightmare!

Bottom line: Making stuff look coolor satisfying a clients requestcould be a nightmare!

Introducing Swing/JFCIntroducing Swing/JFC• Sun addressed problems with Java Foundation Classes (JFC) a/k/a Swing

• Key elements:– No reliance on native peers; the JVM does the work, and is faster– Swing completely controls look and feel of all components:

• PLAF, or “pluggable look and feel”– Superior design:

javax.swing.JButton

Fast, flexib

le, extensib

le!F

ast, flexible, exten

sible!

CLICK ME

File Edit Help

javax.swing.*javax.swing.*

Swing PackagesSwing Packages• All the new Swing components and classes need a home. Where?• A subject of great debate!• For JDK 1.1, Sun used “com.sun.java.swing”; developers

revolted(başkaldırmak).• Problem: developers complained this “com” designation was not appropriate

for “core” class--something part of language.

Solution:Solution:

Denotes ‘extension’ package thatDenotes ‘extension’ package thathas migrated to core statushas migrated to core status

Why “javax”?

* logical grouping

* minimizes transitioncosts

* most developershappy with it

* helps maintainexisting JDK 1.1 code

(cf. MFC lib breaks)

Overview of JFC/Swing PackagesOverview of JFC/Swing Packages

• javax.swing.plaf

• javax.swing.plaf.basic

• javax.swing.plaf.metal

• javax.swing.plaf.multi

• javax.swing.text

• javax.swing.text.html

• javax.swing.text.html.parser

• javax.swing.text.rtf

• javax.swing

• javax.swing.table

• javax.swing.tree

• javax.swing.border

• javax.swing.colorchooser

• javax.swing.filechooser

• javax.swing.event

• javax.swing.undo

Overview of the OverviewOverview of the Overview

Overview of J FC/S w ing P ac kagesOverview of J FC/S w ing P ac kages

• javax.swing.plaf

• javax.swing.plaf.basic

• javax.swing.plaf.metal

• javax.swing.plaf.multi

• javax.swing.text

• javax.swing.text.html

• javax.swing.text.html.parser

• javax.swing.text.rtf

• javax.swing

• javax.swing.table

• javax.swing.tree

• javax.swing.border

• javax.swing.colorchooser

• javax.swing.filechooser

• javax.swing.event

• javax.swing.undo

Text-based widgets(including html/rtf display) New event packages

Components, including“aggregate” or complexcomponents

Packages tocontrol the“look and feel”of Swing

Getting into the SwingGetting into the Swing• Download from www.javasoft.com• Swing works with JDK 1.1 and JDK 1.2

– JDK 1.1 requires “swingall.jar” file in the CLASSPATH– For JDK 1.2, it’s in the soup (no CLASSPATH settings)– JDK 1.2 will also run all JDK 1.1 code (~ 20% faster!)

• Thus, even older JDKs can make use of Swing, with a CLASSPATH setting.

JDK 1.2

AWT

Swing ClassesJDK 1.1

swingall.jar

AWT

classpathclasspath

import com.sun.java.swing.*; import javax.swing.*;

Short ExamplesShort Examples

1.1.

import java.awt.*;

public class HelloWorld extends Frame {

public Button bOld;

//public Panel p;

public HelloWorld() {

bOld = new Button ("Good Bye");

//p = new Panel();

//p.add(bOld);

//this.add(p);

this.add(bOld);

/* note the addition directly to the Frame */

this.pack();

}

public static void main(String arg[]){

/* note lack of listener; this is a demo */

new HelloWorld().show();

}

}// class HelloWorld

Short Example: Old AWTShort Example: Old AWT

We comment most ofthis out for now; AWT lets us add directly to the Frame.

Hello Swing, Good Bye AWTHello Swing, Good Bye AWT

Note addition ofcomponents to

JPanel’s ‘contentpane’

Note Swingcomponents

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class HelloWorld extends JFrame {

Button bOld; public JButton bNew;

public JPanel p;

public HelloWorld() {

bNew = new JButton("Hello");

bOld = new Button ("Good Bye");

p = new JPanel();

p.add(bNew); p.add(bOld);

this.getContentPane().add(p);

this.pack();

}

public static void main(String arg[]){

new HelloWorld().show();

}

}// class HelloWorld

SEE CAUTIONARY NOTE RE: SEE CAUTIONARY NOTE RE: Mixing light and heavyweight Mixing light and heavyweight components!components!

What’s the Big Deal?What’s the Big Deal?• HelloWorld looks similar to AWT. Why switch to JFrame, JButton,

JPanel, etc?

• Benefits:

– speed

– lightweight flexibility (transparency, non-rectangular shape)

– pluggable look and feel

– automatic double buffering with many J- components.

– additional functionality (e.g., tooltips, etc.)

I need Windows™ to be visible and

‘toggle’. I’m slow.

I’m lightweight,pluggable, extensible

and fast. The VMdraws me.

Widget Example: JButtonsWidget Example: JButtons• The java.swing.JButton class implements a “state version” of

a java.swing.AbstractButton. Many methods come from the abstract class:

– A variety of constructors (Strings, Icons, etc.);

– setRolloverEnabled(boolean);

– setIcon(Icon);

– setRolloverIcon(Icon);

– setActionCommand(String); -- an extra String tacked onto

the event that gets fired!

– setContentAreaFilled(boolean) -- transparency for icons!

– setModel(ButtonModel); -- sets the ‘type’ of Button (you

can define your own Button behaviors!)

– setMnemonic(char/int); -- set mnemonics for button

Lesson: Check the APIfor useful behaviors.

import javax.swing.*;

public class HelloWorld2 extends JFrame {

public JButton bNew;

public JPanel p;

public HelloWorld2() {

bNew = new JButton("New Document", new

ImageIcon("Document.gif"));

bNew.setRolloverEnabled(true);

bNew.setRolloverIcon

(new ImageIcon ("New.gif"));

p = new JPanel();

p.add(bNew);

getContentPane().add(p);

this.pack();

}

public static void main(String arg[ ]) {

new HelloWorld2().show(); }

}// class HelloWorld2

Cool ButtonsCool Buttons

Sets icon androllover Icon.

Note: Icon constructortook String argument,and automaticallyloaded image

Images from disk:

DemonstrationDemonstration

Why Why getContentPane()getContentPane() ? ?

• The HelloWorld example required us to call getContentPane() before “add()”ing an object to the JFrame:

Usually“this” E.g.,

“myJButton”

• This differs from traditional AWT container additions, were we simply call “add”, passing in the component.

• Let’s cut a JFrame open to find out why . . .

Required ofJFrame, JDialogand JInternalFrameinstances

myFrameInstance.getContentPane().add(myComponent);

A JFrame AutopsyA JFrame Autopsy

click

A java.awt.Frame is composed of a single container--the Frame object itself. It is flat as a pop tart.

click

JLayeredPane

JPanelContentPane

Menu

A javax.swing.JFrame is composed of a transparent “glassPane” surface, and an inner Jpanel with Contents and Menu

“The Pop Tart / Sandwich Duality”

JFrame Class ViewJFrame Class View

JRootPane JMenuBar

JLayeredPane

JFrame

Container

Component

ContentPane

GlassPane

manages

manages

contains

con

tain

s

con

tain

s

JComponent

Frame

The JRootPane is a container with The JRootPane is a container with a JLayeredPane (holding the Menu a JLayeredPane (holding the Menu and ContentPane) and a and ContentPane) and a Component GlassPane. It serves Component GlassPane. It serves as base for numerous classes.as base for numerous classes.

con

tain

s

con

tain

s

AWTAWT

JFCJFC

JRootPane: The Content PaneJRootPane: The Content Pane

The JRootPane contains only two components:

the JLayeredPane and

the Component GlassPane

Its layout manager ignores all attempts to add new components.

Instead, one must add to the JRootPane’s ContentPane, found inside the JLayeredPane.

A call to getContentPane() returns an instance of the ContentPane.

JFrame Blue PrintWe can use the top “glassPane”as a drawing area. Since it spans the entire JFrame, we can draw on top of menu bars, and every component.

The JPanel has a remarkable layering feature, allowing us to stack and shuffle components.

public Component getGlassPane();public Component getGlassPane();public void setGlassPane(Component);public void setGlassPane(Component);

public JPanel getContentPane();public JPanel getContentPane();

JRootPane: The Glass PaneJRootPane: The Glass Pane

JFrame DisposalJFrame Disposal

• JFrame allows you to configure how it responds to closure.

– Default: hides JFrame on closure attempt.

– To modify: invoke setDefaultCloseOperation().

– E.g.,:

MyJFrameInstance.setDefaultCloseOperation

(WindowConstants.DO_NOTHING_ON_CLOSE);

/* behaves just like java.awt.Frame */

– other constants in javax.swing.WindowConstants:– HIDE_ON_CLOSE - invokes any registered WindowListener

objects, then hides. This is default behavior.– DISPOSE_ON_CLOSE - invokes any registered WindowListener

objects, and then disposes.

Questions?

Questions?

Questions?Questions?

JComponent: The Generic WidgetJComponent: The Generic Widget

• The JComponent provides the basis for all Swing components.

• JComponent extends java.awt.Container, making all Swing components large, powerful widgets. (Also, all Swing components are also containers--even if you wouldn’t normally place things in them. E.g., JButton)

• In turn, JComponent is subclassed by numerous widgets. Thus, composition is favored or inheritance for widget manipulation.

JComponentJComponent

Since JComponent is the basis for most Swing components, all Swing widgets have the following general features:

Borders-- JComponent derived classes can have borders

Accessibility -- JComponents use Swing’s accessibility features to provide additional information about the widget.

Tooltips -- JComponents can have time sensitive tooltips.

Double Buffering -- By default, Swing components have double buffering built in

Serialization -- Ability to save state to a file.

Demo: A GlassPane ExampleDemo: A GlassPane Exampleimport java.awt.*;import java.awt.event.*;import javax.swing.*;public class GlassDemo extends JFrame implements ActionListener {

private boolean bGlassVisible; private GlassPanel glass; private JButton button;

Here’s a simple example thatshows how to use aspects of JFrames.

Frist, we make a JFrame subclass.We declare some instance

variables: a GlassPanel (described later), a boolean flag for the glass panel’s

visibility, and a JButton to toggle

This demo will notbe covered in class;it is provided as anexample of how to

work with JFrames.

Glass Panel ExampleGlass Panel Exampleimport java.awt.*;import java.awt.event.*;import javax.swing.*;public class GlassDemo extends JFrame implements ActionListener {

private boolean bGlassVisible; private GlassPanel glass; private JButton button;

public void actionPerformedactionPerformed (ActionEvent e){bGlassVisible = !bGlassVisible;glass.setVisible(bGlassVisible);

}

The actionPerformed methodmerely toggles the

visibility of the glass pane

Glass Panel ExampleGlass Panel Exampleimport java.awt.*;import java.awt.event.*;import javax.swing.*;public class GlassDemo extends JFrame implements ActionListener {

private boolean bGlassVisible; private GlassPanel glass; private JButton button;

public void actionPerformed (ActionEvent e){bGlassVisible = !bGlassVisible;glass.setVisible(bGlassVisible);

} public void centerInScreencenterInScreen(){

Toolkit tk = Toolkit.getDefaultToolkit();Dimension d = tk.getScreenSize();this.setLocation((d.width-getSize().width)/2,

(d.height-getSize().height)/2); } ... A little magic.

(It merely centers the framein the screen.)

Glass Panel ExampleGlass Panel Exampleimport java.awt.*;import java.awt.event.*;import javax.swing.*;public class GlassDemo extends JFrame implements ActionListener {

private boolean bGlassVisible; private GlassPanel glass; private JButton button;

public void actionPerformed (ActionEvent e){bGlassVisible = !bGlassVisible;glass.setVisible(bGlassVisible);

} public void centerInScreen(){

Toolkit tk = Toolkit.getDefaultToolkit();Dimension d = tk.getScreenSize();this.setLocation((d.width-getSize().width)/2,

(d.height-getSize().height)/2); } public static void mainmain(String[] args) {

new GlassDemo().show(); }

A simpletest main

public GlassDemo () {this.setSize(400,400);this.getContentPane().setBackground(Color.white);this.getContentPane().setLayout(new BorderLayout());this.addWindowListener (new WindowAdapter(){

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

Our constructor has poor abstraction, butis sufficient for a demonstration.

We start by setting a size, background,layout, and a simple WindowListener

public GlassDemo () {this.setSize(400,400);this.getContentPane().setBackground(Color.white);this.getContentPane().setLayout(new BorderLayout());this.addWindowListener (new WindowAdapter(){

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

JPanel p = new JPanel();p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));button = new JButton ("Toggle");button.addActionListener(this);p.add(Box.createHorizontalGlue());p.add(button);p.add(Box.createHorizontalGlue());

We add a JButton to a containing JPanel. We make

sure it will center in the JPanel, using ‘glue’ objects. Thesame effect can be obtained with

more complicated layerings ofpanels and layout managers.

public GlassDemo () {this.setSize(400,400);this.getContentPane().setBackground(Color.white);this.getContentPane().setLayout(new BorderLayout());this.addWindowListener (new WindowAdapter(){

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

JPanel p = new JPanel();p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));button = new JButton ("Toggle");button.addActionListener(this);p.add(Box.createHorizontalGlue());p.add(button);p.add(Box.createHorizontalGlue());this.getContentPane().add(p, BorderLayout.CENTER);this.getContentPane() .add(new JLabel("Press Button to Toggle Glass Pane"),

BorderLayout.SOUTH);

We add the panel to ourJFrame’s content pane,

along with a simple label. . .

public GlassDemo () {this.setSize(400,400);this.getContentPane().setBackground(Color.white);this.getContentPane().setLayout(new BorderLayout());this.addWindowListener (new WindowAdapter(){

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

JPanel p = new JPanel();p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));button = new JButton ("Toggle");button.addActionListener(this);p.add(Box.createHorizontalGlue());p.add(button);p.add(Box.createHorizontalGlue());this.getContentPane().add(p, BorderLayout.CENTER);this.getContentPane() .add(new JLabel("Press Button to Toggle Glass Pane"),

BorderLayout.SOUTH);centerInScreen();glass = new GlassPanel();this.setGlassPane(glass);bGlassVisible = false;

} } // end of class GlassDemo

We then make and seta new glass panel for

the JFrame.

import java.awt.*;import javax.swing.*;public class GlassPanel extends JComponent {

final Color trans;

public GlassPanel () {this.setOpaque(false);// create nearly black color with transparencytrans = new Color(150,25,25,125);

}

public Dimension getPreferredSize(){return getParent().getPreferredSize();

}

public void paintComponent(Graphics g){g.setColor(trans);g.fillRect(0,0,getSize().width, getSize().height);

}

} // GlassPanel

import java.awt.*;import javax.swing.*;public class GlassPanel extends JComponent {

final Color trans;

public GlassPanel () {this.setOpaque(false);// create nearly black color with transparencytrans = new Color(150,25,25,125);

}

Our GlassPanel object is merely a JComponent subclass. It first sets

itself to be transparent, and then creates a color with a high transparency

value, 125. (A later lecture will touch on the Java color model. For now, theAPI shows us the arguments are Red,Blue, Green, and Alpha transparency.)

import java.awt.*;import javax.swing.*;public class GlassPanel extends JComponent {

final Color trans;

public GlassPanel () {this.setOpaque(false);// create nearly black color with transparencytrans = new Color(150,25,25,125);

}

public Dimension getPreferredSize(){return getParent().getPreferredSize();

}

Since we’re making our own home-grown widget, and not one found in the API, we have to let the

layout managers know how large this componentwishes to be. We simply return the size of the

parent container--meaning the GlassPanel have thesame size as its parent container.

import java.awt.*;import javax.swing.*;public class GlassPanel extends JComponent {

final Color trans;

public GlassPanel () {this.setOpaque(false);// create nearly black color with transparencytrans = new Color(150,25,25,125);

}

public Dimension getPreferredSize(){return getParent().getPreferredSize();

}

public void paintComponent(Graphics g){g.setColor(trans);g.fillRect(0,0,getSize().width, getSize().height);

}

} // GlassPanelThis method defines how the component will look. Another lecture will explore the details

of drawing in Java. For now, know that this floods the component with colored pixels.

GlassDemo (A JFramesubclass )

Overview of GlassDemoOverview of GlassDemo

GlassPanel class

content pane (with JButton)

(Demo)(Demo)

After a press, the glass pane becomesvisible, giving a hazy(bulanık)

gauze(tül) to the GUI.

DesignDesign

3.3.

Button DesignButton Design• JButtons are a good example of the Model, View Control structure Java,

*ahem*, borrowed and modified from Smalltalk.• Let’s examine the inheritance structure of a JButton . . .

AbstractButton implements ItemSelectable, SwingConstants

Defines the common behaviors for the JButton, JToggleButton, JCheckbox, and the JRadioButton classes.

java.lang.Object | +--java.awt.Component | +--java.awt.Container | +--javax.swing.JComponent | +--javax.swing.AbstractButton | +--javax.swing.JButton

public abstract interface javax.swing.ButtonModelextends ItemSelectable

hasA

The ButtonModel provides thestate machine for Button behavior

MModel, odel, VView, iew, CControlontrol

• Let's say you decide to write a program that will implement a timer• You want to be able to set the time, start and stop the timer• You want the timer to show the time counting down plus have

something exciting happen when time is up.

• You might write a big monlithic program that would do all this and be swell...

• Until someone wanted a version with a different display...perhaps some LED's, perhaps a graphical widget.

• Until someone wanted a version with a different control scheme like JButtons

MVCMVC

• Design this timer in three distinct parts (e.g. classes!)– Model: This is the heart of the calculation part of the timer and

is where the data is stored. The model might not know anything about the View or the Control

– View: The view controls what the user sees (and hears). It might run autonomously or be controlled by the Control. It might have a reference to the Control

– Control: This is what the user interacts with to control the timer. It may be a set of keyboard commands or a GUI or mechanical pushbuttons. The control has references to model and the view.

MVC RelationshipsMVC Relationships

Model (data)

View Model m Control c

Controller Model m View v Clear

Interfaces

MVC ParadigmMVC Paradigm• The MVC paradigm breaks applications or interfaces into three parts: the

model, the view, and the controller.

Users interact with a controller (e.g., buttons), and make changes to the model (e.g., data), which is then reflected in the view (e.g., graph).

A --> 25 %B --> 60 %C --> 15 %

Model

Bar

Control

PieA

B

B

View2

0

10

20

30

40

50

60

A B B

Percentage

View1

MVC Paradigm, MVC Paradigm, à la Swingà la Swing

• Swing uses a simplified version of the MVC structure, called the model-delegate

Model

View

ControllerUI-delegate

SwingComponent

MVC: Who Cares?MVC: Who Cares?

?Why does it matter?

Helps us Helps us understand understand complex complex Swing Swing packagespackages

Allows user customization of model or view, without rewriting both

Guides futurepackage

development

(Think ofsomethingelse; need

four points)

MVC: Why You CareMVC: Why You Care

The formal benefits of MVC will be exposed in subsequent CS classes focused on design and OO theory.

But you should be familiar with MVC now because Swing widgets use the UI-Delegate variation of MVC.

If you need to change something about a Swing widget, consider whether your proposed change affects:

* The model of a widget (its state, value)

* The look of a widget (its UI delegate)

Knowing what you are changing will help you find where in the API you must look for useful methods.

QuestionsQuestions

DangerDanger

4.4.

• An artifact of the MVC (or model-delegate) structure of Swing is the need to avoid separate threads updating the model state

• To avoid a race condition, one should ONLY use the event-dispatching queue.

Cautionary Notes: MVC & ThreadsCautionary Notes: MVC & Threads

myThread

Event Dispatcher

Model

View

Controller

Which threadfinishes last?

The event-dispatching queue handles repaints, and dispatches events to GUI component listeners.

Confused by this? The lesson is: Don’t mix Threads and Swingunless you know what you’re doing.

Cautionary Note: Mixing TypesCautionary Note: Mixing Types

• Avoid mixing light and heavy weight components.

• Heavy weights are “opaque” -- solid & rectangular

• Light weights are transparent, and draw themselves on top of the

heavyweight container they occupy (Frame, Jframe, Panel, etc.)

• This can frustrate Z-order layering

• (The slides will violate this principle only to make a point.)

CLICK ME

As designed,and as we coded it

CLICK ME

What shows up

Heavy weightjava.awt.Button

Lightweightjava.awt.Component

We normally think of events as user-driven actions. But the mere passage of time is an event that Swing components can observe--all without the use of additional threads.

Java provides the javax.swing.Timer object--something of an ‘egg timer’ that allows one to have an event fired periodically without user interaction:

Possible Solution: Use TimersPossible Solution: Use Timers

delayEvent handler

Timer t = new Timer(500, this);t.start();

import javax.swing.*; import java.awt.event.*;import java.awt.*;public class StopWatch extends JLabel implements ActionListener{ int count = 0; public StopWatch(){ super("Elapsed Time: 0 secs", JLabel.CENTER); Timer t = new Timer(1000, this); t.start(); } public void actionPerformed(ActionEvent e){ this.setText("Elapsed Time: " + count++ + " secs"); } public static void main (String arg[]){ JFrame f = new JFrame(); f.setSize(300,100); f.addWindowListener (new WindowAdapter() { public void windowClosing(WindowEvent e){ System.exit(0);}}); StopWatch c = new StopWatch(); f.getContentPane() .setLayout(new BorderLayout()); f.getContentPane() .add(c, BorderLayout.CENTER); f.show(); } }

Questions?Questions?