Download User Interface

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Graphical User Interface
ITI 1121
N. El Kadri
Plan - agenda
• Graphical components
• Model-View-Controller
• Observer/Observable
AWT
• The Abstract Window Toolkit (AWT) is
the oldest set of classes used to build
graphical user interfaces (GUI) in Java.
It has been part of all the Java releases.
• A more recent and improved toolkit is
called Swing.
• For this introduction, we will focus on
AWT.
Components/Containers
• A graphical element is called a
component. Accordingly, there is a
class called Component that defines the
characteristics that are common to all
components.
Components include: windows, buttons,
checkboxes, menus, text fields, scroll
bars, etc.
The components that contain other components
are called containers. Accordingly, there is a
class called Container that defines the
characteristics that are common to all the
containers.
• AWT is a rich source of examples of the use of
inheritance. A Component defines a collection of
methods that are common to all the graphical
objects, such as setBackground( Color c ) and
getX().
Components/Containers – Cont’d
• A Container will contain other graphical
components, and therefore declares a
method add( Component component )
and setLayout(LayoutManager mgr ).
• A Window is a Container that is not
contained in any other Container. It defines
the methods show() and
addWindowListener(WindowListener l ).
Hello World -1• A Frame is a top-level window with a title and a border.
import java.awt.*;
public class HelloWorld {
public static void main( String args[] ) {
Frame f = new Frame( "Hello World!" );
f.setSize( 200,300 );
f.setVisible( true );
}
}
 a top-level component is one that is not contained within
any other component.
DrJava
• Alternatively, use DrJava to create and experiment with
graphical objects. Use the interactions window and type
each of the following statements one by one.
> import java.awt.*;
> Frame f = new Frame( "Hello World!" );
> f.setSize( 100, 200 );
> f.setVisible( true );
> f.setVisible( false );
> f.setVisible( true );
> f.setVisible( false );
• You will see that a Frame of object is not visible unless
you make it visible.
Hello World -2• Let’s create instead a specialized Frame that has the required
characteristics for this application.
import java.awt.*;
public class MyFrame extends Frame {
public MyFrame( String title ) {
super( title );
setSize( 200,300 );
setVisible( true );
}
}
Which would be used as follows:
import java.awt.*;
public class Run {
public static void main( String args[] ) {
Frame f = new MyFrame( "Hello World" );
}
}
• MyFrame is a specialized Frame, which is a specialized
Container, therefore, it may contain other components.
import java.awt.*;
public class MyFrame extends Frame {
public MyFrame( String title ) {
super( title );
add( new Label( "Some text" ) );
setSize( 200,300 );
setVisible( true );
}
}
LayoutManager
• When adding new components, we would like to have control over
the placement of the objects (components).
• A layout manager is an object responsible for placing and sizing the
components in a container.
• LayoutManager is an interface and Java provides several
implementations: FlowLayout, BorderLayout and GridLayout
are the main ones.
• FlowLayout adds the components from left to right, from top to
bottom, this is the default layout manager for a Panel.
• BorderLayout is a layout that divides the container into zones: north,
south, east, west and center, this is the default layout manager for a
Frame.
• GridLayout divides the container into m×n zones (2 dimensional
grid).
The Java library has approximately 20 layout manager
implementations.
BorderLayout
import java.awt.*;
public class MyFrame extends Frame {
public MyFrame( String title ) {
super( title );
add(new Label( "North" ),BorderLayout.NORTH );
add(new Label( "South" ),BorderLayout.SOUTH );
add(new Label( "East" ),BorderLayout.EAST );
add(new Label( “West" ),BorderLayout.WEST );
add(new Label( "Center" ),BorderLayout.CENTER );
setSize( 200,300 );
setVisible( true );
}
}
FlowLayout
import java.awt.*;
public class MyFrame extends Frame {
public MyFrame( String title ) {
super( title );
setLayout( new FlowLayout() );
add( new Label( "-a-" ) );
add( new Label( "-b-" ) );
add( new Label( "-c-" ) );
add( new Label( "-d-" ) );
add( new Label( "-e-" ) );
setSize( 200,300 );
setVisible( true );
}
}
Panel
• A Panel is the simplest Container.
• It can be used to regroup several
components and may have a different
layout than the container that it is part of.
import java.awt.*;
public class MyFrame extends Frame {
public MyFrame( String title ) {
super( title );
setLayout( new BorderLayout() );
add( new Label( "Nord" ),BorderLayout.NORTH );
add( new Label( "Est" ),BorderLayout.EAST );
add( new Label( "Ouest" ),BorderLayout.WEST );
add( new Label( "Centre" ),BorderLayout.CENTER );
Panel p = new Panel();
p.setLayout( new FlowLayout() );
p.add( new Label( "-a-" ) );
p.add( new Label( "-b-" ) );
p.add( new Label( "-c-" ) );
p.add( new Label( "-d-" ) );
p.add( new Label( "-e-" ) );
add( p,BorderLayout.SOUTH );
setSize( 200,300 );
setVisible( true );
}
}
Event-driven programming
• Graphical user interfaces are programmed different from
most applications.
• In an event-driven application, the program waits for
something to occur, the user clicks a button or presses a
key.
• An event is an object that represents the action of the
user.
• In Java, the components are the source of the events.
• A component generates an event or is the source of an
event. For example,
– When a button is pressed and released, AWT sends an instance of
ActionEvent to the button, by calling processEvent on the button.
ActionListener
• To handle the events that will be generated
by the button, one needs to add (sometimes
we say register) an object that implements
the interface ActionListener.
import java.awt.*;
import java.awt.event.*;
public class Square extends Frame {
Button button = new Button( "Square" );
TextField input = new TextField();
public Square() {
super( "Square GUI" );
setLayout( new GridLayout( 1,2 ) );
add( button );
add( input );
button.addActionListener(
new SquareActionListener( this ) );
pack();
show();
}
protected void square() {
int v = Integer.parseInt( input.getText() );
input.setText( Integer.toString( v*v ) );
}
}
• The interface ActionListener lists only one method
actionPerformed(ActionEvent e).
• A SquareActionListener object must know which method
square to call, therefore, it has an instance variable that
designates the Square object, and this variable is
initialized by the constructor.
class SquareActionListener implements ActionListener {
private Square appl;
SquareActionListener( Square appl ) {
this.appl = appl;
}
public void actionPerformed( ActionEvent e ) {
appl.square();
}
}
Alternatively, the class Square could be handling the event, as
shown on the following slide.
import java.awt.*;
import java.awt.event.*;
public class Square extends Frame implements ActionListener {
Button button = new Button( "Square" );
IntField input = new IntField();
public Square() {
super(" Square GUI" );
setLayout( new GridLayout( 1,2 ) );
add( button );
add( input );
input.setValue( 2 );
addWindowListener( new SquareWindowAdapter( this ) );
button.addActionListener( this );
pack();
show();
}
protected void square() {
int v = input.getValue();
input.setValue( v*v );
}
public void actionPerformed( ActionEvent e ) {
square();
}
}
class SquareWindowAdapter extends WindowAdapter {
private Square appl;
SquareWindowAdapter( Square appl ) {
this.appl = appl;
}
public void windowClosing( WindowEvent e ) {
System.exit(0);
}
}
class IntField extends TextField {
public int getValue() {
return Integer.parseInt( getText() );
}
public void setValue( int v ) {
setText( Integer.toString( v ) );
}
}
• Let’s add a button to quit the application.
The class Square will be the eventhandler for both buttons. Therefore, the
method actionPerformed must be able to
distinguish between an event that
originated from pressing the button
square and one that originated from
pressing the button quit; fortunately, the
event encapsulates this information, see
method getSource().
import java.awt.*;
import java.awt.event.*;
public class Square extends Frame implements ActionListener {
Button bSquare = new Button( "Square" );
Button bQuit = new Button( "Quit" );
IntField input = new IntField();
public Square() {
super( "Square GUI" );
setLayout( new GridLayout( 1,3 ) );
add( bSquare );
bSquare.addActionListener( this );
add( input );
input.setValue( 2 );
add( bQuit );
bQuit.addActionListener( this );
addWindowListener( new SquareWindowAdapter( this ) );
pack();
show();
}
protected void square() {
int v = input.getValue();
input.setValue( v*v );
}
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == bSquare ) {
square();
} else if ( e.getSource() == bQuit ) {
System.exit(0);
}
}
}
class SquareWindowAdapter extends WindowAdapter {
private Square appl;
SquareWindowAdapter( Square appl ) {
this.appl = appl;
}
public void windowClosing( WindowEvent e ) {
System.exit( 0 );
}
}
class IntField extends TextField {
public int getValue() {
return Integer.parseInt( getText() );
}
public void setValue( int v ) {
setText( Integer.toString(v) );
}
}
•
To close the application when the closing button is clicked add the call
addWindowListener(. . . ).
import java.awt.*;
import java.awt.event.*;
public class Square extends Frame {
Button button = new Button( "Square" );
TextField input = new TextField();
public Square() {
super( "Square GUI" );
setLayout( new GridLayout( 1,2 ) );
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit(0);
}
}
add( button );
add( input );
button.addActionListener(
new SquareActionListener( this ) );
pack();
show();
}
protected void square() {
int v = Integer.parseInt( input.getText() );
input.setText( Integer.toString( v*v ) );
}
}
• The method square retrieves the user
input, converts it to an int and puts back the
square value in the text field.
private void square() {
int v = Integer.parseInt( input.getText() );
input.setText( Integer.toString( v*v ) );
}
• Instead, it might come handy to have a
specialized version of the text field that handles
the String to int and int to String conversions for
us. Let’s create a new subclass called IntField:
class IntField extends TextField {
public int getValue() {
return Integer.parseInt( getText() );
}
public void setValue( int v ) {
setText( Integer.toString( v ) );
}
}
which would replace the TextField in our application:
import java.awt.*;
import java.awt.event.*;
public class Square extends Frame {
Button button = new Button( "Square" );
IntField input = new IntField();
public Square() { ... }
private void square() {
int v = input.getValue();
input.setValue( v*v );
}
}
class IntField extends TextField {
public int getValue() {
return Integer.parseInt( getText() );
}
public void setValue( int v ) {
setText( Integer.toString( v ) );
}
}
Nested Components
• Fancier presentations often require nested
components.
• The following example illustrates the use
of a Panel to contain two buttons, the layout
of that Panel is GridLayout while the toplevel widow uses a BorderLayout
public class Square extends Frame {
private static final String newline =
System.getProperty( "line.separator" );
Button button = new Button( "Square" );
IntField input = new IntField();
TextArea output = new TextArea( 5, 40 );
public Square() {
// ...
setLayout( new BorderLayout() );
add( output, "Center" );
Panel bottom = new Panel();
bottom.setLayout( new GridLayout( 1,2 ) );
bottom.add( button );
bottom.add( input );
add( bottom, "South" );
pack();
show();
}
// ...
}
Next Time…
• Model-View-Controller (MVC) pattern
• Observer/Observable