Download Lecture notes 2

Document related concepts
no text concepts found
Transcript
CE203 - Application Programming
Part 2
Dr Ian Daly
Autumn 2016
CE203 Part 2
1
General notices
• Please do attend the labs, this is your opportunity to
practice coding with assistance.
• Please come to lab1 first (we can overflow into the other
labs if we need to).
• Test on week 6.
– 10% of mark
– Multi-choice
– Quizzes in the lectures are good practice
• Guest lecture: “Databases in the wild” by Wesley Hall,
week 7.
Autumn 2016
CE203 Part 2
2
Labs this week
• The best way to learn to program is to practice.
• Labs are your opportunity to get feedback on your
progress and help with your programming.
• This weeks lab will include a recorded feedback session.
– GLAs will give you feedback on your work during the
lab
– We will record who has met with the GLAs during the
lab.
– Make sure one of the GLAs notes your attendance.
Autumn 2016
CE203 Part 2
3
Learning objectives today
• Java applications and graphical user interfaces (GUIs)
• Event driven programming
• User interfaces – Buttons
Autumn 2016
CE203 Part 2
4
Lectures
• Lecture notes will be post to orb before the lecture so you
can download and follow along.
• The lectures include a fair amount of worked code
examples.
• Feel free to work along on your laptops if you have one.
• However, the code is incomplete, I only show the
minimum to introduce the concepts, no complete
programs.
• I can’t help you with code errors during the lectures, this is
what the labs are for 
Autumn 2016
CE203 Part 2
5
Types of Application
•
•
•
•
•
Desktop / Laptop (“traditional”) applications
Mobile (Android) applications
Console applications
Java Applet (being phased out)
etc.
Autumn 2016
CE203 Part 2
6
Java Graphical User Interfaces 1
Java programs can show graphical user interfaces by using
frames.
Any application that presents a graphical user interface (GUI)
must instantiate a JFrame.:
import javax.swing.JFrame;
public class Greeting
{ ...
}
Autumn 2016
CE203 Part 2
// for JFrame
7
Java Graphical User Interfaces 1
• JFrame: Contains graphical objects
– JPanel
– Components
– Both can hold buttons, labels, text fields etc.
Autumn 2016
CE203 Part 2
8
Java Graphical Interfaces 3
An alternative: Java Applets
In the process of being phased out.
When an HTML browser visits a page containing the applet the
applet container (a program running in the browser) will create an
applet object and display it on the page. An applet class does not
have a main method since the container effectively plays this role.
When the applet is displayed its paint method will be called – a
default one inherited from the JApplet class will be used if the
class has no such method.
The paint method takes an argument of type Graphics – we can
apply methods to this argument to draw items on the applet.
Autumn 2016
CE203 Part 2
9
Java Graphical Interfaces 4
Since applets do not have a main method, we cannot run them
using the java command; they must be embedded into an
HTML page. The simplest page we could use is
<HTML>
<APPLET CODE="Greeting.class">
</APPLET>
</HTML>
The page may be viewed using most browsers but during
development it is more convenient to use the JDK tool
appletviewer. Assuming the above HTML is in a file called
myapplet.html we would simply type
appletviewer myapplet.html
(in fact, IDEs like IntelliJ incorporate all this)
Autumn 2016
CE203 Part 2
10
Java Graphical Interfaces 5
The size of the applet may be specified in the HTML file (if it
is not specified the browser will use a default size):
<HTML>
<APPLET CODE="Greeting.class"
WIDTH=200 HEIGHT=150>
</APPLET>
</HTML>
(apart from the applet tag there are object and embed tags but on
the Java API Oracle recommends “to use the applet tag as a consistent
way to deploy Java applets across browsers on all platforms”)
Autumn 2016
CE203 Part 2
11
Java Graphical Interfaces 6
Desktop applications (unlike applets) require a main
method.
This serves as the entry point for the application.
The main method takes a string array of variable length,
which allows command line variables to be sent to the
application.
The following slide contains a simple ‘hello world’ Java
desktop application.
Autumn 2016
CE203 Part 2
12
Java Graphical Interfaces 7
Applications
import javax.swing.*;
// for JFrame
public class Greeting
{ public static void main(String[] args)
{
JFrame frame = new JFrame();
JLabel label = new JLabel( “Hello world” );
frame.add( label );
frame.setSize( 200, 200 );
frame.setTitle( “Hello” );
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
Autumn 2016
CE203 Part 2
13
Java Graphical Interfaces 8
Elements can be arranged on a frame via JPanels
Interface elements can be added directly to the frame or to a
JPanel.
JButton
Jlabel
JTextBox
JTextArea
JToggleButton
JRadioButton
etc.
Autumn 2016
CE203 Part 2
14
Java Graphical Interfaces 9
• Images, shapes etc. can be added to a component via the
Graphics object. Coordinates are measured in pixels with
(0,0) being the top left corner.
• The setColor method specifies the colour for all
subsequent items to be drawn.
• The paintComponent method can be used to paint shapes
and receives an object of type Graphics.
• This can be placed in a JFrame by instantiating a
Component or a JPanel
Autumn 2016
CE203 Part 2
15
Java Graphical Interfaces 10
import javax.swing.*;
import java.awt.*;
// for Jframe
public class Greeting
{
public static void draw( Graphics g )
{
g.setColor( Color.BLUE );
g.fillRect( 10, 10, 50, 50 );
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel component = new JPanel()
{
public void paintComponent( Graphics graph )
{
draw( graph );
}
}
frame.add( component );
frame.setSize( 200, 200 );
frame.setTitle( “Hello” );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}
Autumn 2016
CE203 Part 2
16
Java Graphical Interfaces 11
An applications paint or draw methods can be called more
than once since it may be necessary to update or refresh the
display later in the application’s lifetime.
Hence any initialisation tasks that are to be performed only
once should not be placed in these methods.
For example, if we wished to allow our applications to be
capable of displaying multiple strings (not just “Hello
world”) we should store the string in a variable initialised as
on the next slide.
Autumn 2016
CE203 Part 2
17
Java Graphical Interfaces 12
import javax.swing.*;
import java.awt.*;
public class Greeting
{
private String s;
public static void main(String[] args)
{
s = "Hello";
.
.
.
Autumn 2016
CE203 Part 2
18
Java Graphical Interfaces 13
Graphical items can be drawn by applying methods to a Graphics
object.
An application may also contain components such as text fields,
labels, buttons and menus.
If we wish to combine graphical items and components we should
ensure that the graphical items do not interfere with the
components. Careful positioning using coordinates will not be
sufficient since components may move if the window is resized.
Hence, instead of drawing the graphical items directly onto the
application using a paint method, we should add a component
called a JComponent and draw them on that.
We can also position components within a panel.
Autumn 2016
CE203 Part 2
19
Java Graphical Interfaces 14
Components to be placed on an application must be added to
its content pane, their positions being determined by a layout
manager.
The default manager for applications is BorderLayout in
which the application may have a central component and one
on each of the four borders, with each component being
placed in a chosen position. Any components placed on the
borders will occupy as much space as is needed for its
contents; the central component will occupy all remaining
space.
Autumn 2016
CE203 Part 2
20
Java Graphical Interfaces 15
If the BorderLayout manager is being used we must supply
the position as a second argument to this method using one of
the constant static variables NORTH, SOUTH, EAST, WEST and
CENTER from the BorderLayout class.
http://coding365.blogspot.co.uk/2012/11/java-exercise-53-demonstrate-border.html
Autumn 2016
CE203 Part 2
21
Java Graphical Interfaces 16
Other Layout managers:
BoxLayout
Components go
in a single row /
column.
FlowLayout
Components go in a single
row. A new row is started if
the container is not wide
enough.
Default layout manager for
Jpanels.
(pics from https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)
Autumn 2016
CE203 Part 2
GridLayout
Components are
equal in size and go
in requested rows
and columns.
22
Java Graphical Interfaces 17
Many more layout managers available…
Check
https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.
html for details.
Autumn 2016
CE203 Part 2
23
Java Graphical Interfaces 18
We shall demonstrate the addition of components to an
application by modifying our original application so that the
string is displayed as a label at the top of the application and
the drawing is performed on a panel which will occupy the
rest of the space.
The addition of components to the application should be done
once only and hence should be placed in the main method.
The panel must be an object of the class JPanel
Autumn 2016
CE203 Part 2
24
Java Graphical Interfaces 19
import javax.swing.*;
import java.awt.*;
public class Greeting3
{
public void main( String[] args )
{
JFrame frame = new JFrame();
JLabel label = new JLabel("Hello world");
JPanel panel = new JPanel();
panel.add( label, BorderLayout.NORTH );
frame.add( panel, BorderLayout.SOUTH );
frame.setSize( 200, 200 );
frame.setTitle( “Hello” );
}
}
Autumn 2016
// etc.
CE203 Part 2
25
Java Graphical Interfaces 20
Label added at
north (top) of
panel.
Panel added at
south (bottom)
of frame.
Autumn 2016
CE203 Part 2
26
Java Graphical Interfaces 21
Use inheritance to create custom frames.
Design a sub-class of JFrame
Store components as instance variables
Initialise in constructor
Example on next slide…
Autumn 2016
CE203 Part 2
27
Java Graphical Interfaces 22
// Greeting3.java continued
public class FilledFrame extends JFrame
{
private JButton button;
private JLabel label;
private static final int FRAME_WIDTH = 300;
private static final int FRAME_HEIGHT = 300;
public FilledFrame()
{
createComponents(); // Helper method.
setSize( FRAME_WIDTH, FRAME_HEIGHT );
}
private void createComponents()
{
button = new JButton( “Click me” );
label = new JLabel( “Hellow world” );
Jpanel panel = new Jpanel();
panel.add( button );
panel.add( label );
add( panel );
}
Autumn 2016
CE203 Part 2
28
Java Graphical Interfaces 23
• We can then call this new frame class from main
.
.
public void main( String[] args )
{
FilledFrane frame = new FilledFrame();
frame.setTitle( “A frame with two components” );
.
.
Autumn 2016
CE203 Part 2
29
Java Graphical Interfaces 24
We can also extend the JPanel class to include customised
layouts of graphical objects.
Since a file may contain only one public class this second
class will not be declared as public.
The JPanel class has a paintComponent method with an
argument of type Graphics, so we need to write our own
version to replace the default inherited one.
In order to work correctly a paintComponent method should
always start with a call to the inherited method.
Autumn 2016
CE203 Part 2
30
Java Graphical Interfaces 25
// Greeting3.java continued
class GreetingPanel extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.drawRect(50, 100, 40, 30);
"
g.fillRect(120, 100, 30, 40);
}
}
To use…
..
GreetingPanel panel = new GreetingPanel();
..
Autumn 2016
CE203 Part 2
31
Java Graphical Interfaces 26
Interactivity
We now wish to develop an interactive application.
The application will display a square and have a button that
can be used to change the colour of the square.
The square will be drawn on a panel at the centre of the
application.
The button, of type JButton, will be placed at the bottom of
the application using BorderLayout.SOUTH. The JButton
class has a constructor with one argument that allows us to
specify the string to be displayed on the button.
Autumn 2016
CE203 Part 2
32
Java Graphical Interfaces 27
import javax.swing.*;
import java.awt.*;
public class FilledFrame extends JFrame
{
..
.
Color col = Color.red;
public void createComponents()
{
JButton but = new JButton("Press me");
SquarePanel panel =
new SquarePanel(this);
add(but, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
}
}
// continued below
Autumn 2016
CE203 Part 2
33
Java Graphical Interfaces 28
paintComponent
method in the
SquarePanel class will need to know the
The
identity of the FilledFrame in order to access its
col variable. Hence we must supply this
information to the constructor for the
SquarePanel class.
We can do this using the keyword this, which
refers to the object to which the method in
which it appears has been applied. Note, we
can’t use this within the static context, e.g.
within the main method, which is why we use
the FilledFrame class rather than setup the
frame directly within the main function.
Autumn 2016
CE203 Part 2
myClass
this
34
Java Graphical Interfaces 29
// Square.java continued
class SquarePanel extends JPanel
{
FilledFrame theApp;
SquarePanel( FilledFrame app )
{
theApp = app;
}
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.setColor( theApp.col );
g.fillRect( 20, 30, 40, 40 );
}
}
Autumn 2016
CE203 Part 2
35
Java Graphical Interfaces 30
Although we now have an application that displays a square
and a button nothing will happen when the button is pressed;
we have not written any code that detects the button-press or
changes the value of the variable col.
In order to do this we need to understand the event-driven
programming model used by the classes in the javax.swing
package.
Autumn 2016
CE203 Part 2
36
Event-Driven Programming 1
In traditional procedural programming a main method calls
other methods, which may themselves call further methods,
so the sequence in which methods are called can be
determined by examining the program or input data.
In event-driven programming, however, after performing
initialisation the program simply waits for events to occur
and responds to them – the programmer must write methods
to be called when particular events occur.
Autumn 2016
CE203 Part 2
37
Event-Driven Programming 2
Java applications use the event-driven model: after the main
and any paint or other initialisation methods have been
called the application container will wait for events to occur.
When an event occurs it will call a method supplied by the
writer of the application. Such methods must be written in
objects that implement an interface known by the application
container, which must be informed about the identity of the
objects and with which events they are to be associated.
Autumn 2016
CE203 Part 2
38
Event-Driven Programming 3
Procedural program
1.
2.
3.
4.
5.
Initialisation
Action 1
Action 2
…..
Exit
Autumn 2016
Event-driven program
1.
2.
3.
4.
5.
Initialisation
Wait for events…
If event occurs perform associated action
Repeat steps 2-3 until exit action…
Exit
CE203 Part 2
39
Event-Driven Programming 4
Event handling may be understood via the metaphor of a postman.
Suppose we have several letters (messages) and several homes, each with its own
address.
A postman may deliver messages to addresses via the following algorithm…
for each letter in Letters,
for each home in Homes,
if letter.destination == home.address,
deliver( letter to home );
end if
end for
end for
In Java, messages are Events, which are dispatched by Event generators to Listener
interfaces.
Autumn 2016
CE203 Part 2
40
Event-Driven Programming 5
The Java Event Model Framework
Three classes and an interface…
EventObject
EventListener
EventListenerProxy
TooManyListenersException (class)
(class)
(interface)
(class)
New types of Event can be specified by extending EventObject
New classes, that have to be notified when an event occurs, can implement the EventListener
interface.
Specific types of sub-interfaces for different event categories are named <event category
name>Listener
e.g. ActionListener is the interface used for events in the Java GUI and new events
can be generated by calling addActionListener
Classes can be written to broadcast events.
Autumn 2016
CE203 Part 2
41
Event-Driven Programming 6
When the programmer wishes to respond to events associated
with a particular component he or she must add an action
listener to that component. This must be an object belonging
to a class that implements the interface ActionListener,
and is added to the component using the method
addActionListener, e.g.
but.addActionListener(new ButtonHandler());
[ There is a similar interface called MouseListener for
mouse events not associated with components. ]
Autumn 2016
CE203 Part 2
42
Event-Driven Programming 7
In order to implement the ActionListener interface a class must
have a public void method called actionPerformed, with an
argument of type ActionEvent.
This is the method that will be called when the event occurs. The
argument will provide information about the event.
Example:
We will now provide a button-handler class for the button to
change the colour of the square in our application. The
actionPerformed method will need to know the identity of the
application to access its col variable so we will need to provide a
constructor similar to the one in the SquarePanel class.
Autumn 2016
CE203 Part 2
43
Event-Driven Programming 8
// Square.java continued
class ButtonHandler implements ActionListener
{
FilledFrame theApp;
ButtonHandler( FilledFrame app )
{
theApp = app;
}
}
public void actionPerformed(ActionEvent e)
{
if (theApp.col==Color.blue)
theApp.col = Color.red;
else
theApp.col = Color.blue;
theApp.repaint();
}
Autumn 2016
CE203 Part 2
44
Event-Driven Programming 9
Simply changing the value of the application’s col variable
has no effect on the display – it is also necessary to ensure
that the panel’s paintComponent method is called again. We
cannot do this directly since there is no easy way to get hold
of an appropriate argument. Instead we call the repaint
method from the JFrame class. This method clears anything
previously drawn by paint or paintComponent methods
and calls these methods again.
Another option is to apply repaint directly to the panel, but
to do this its identity would have had to have been stored in
an instance variable of the application class.
Autumn 2016
CE203 Part 2
45
Event-Driven Programming 10
We must now modify the FilledFrame class to add the
action listener to the component, remembering that we must
pass the identity of the FilledFrame to the ButtonHandler
constructor using this.
We also need to add an extra import statement to the program
– ActionListener and ActionEvent are defined in the
package java.awt.event.
Autumn 2016
CE203 Part 2
46
Event-Driven Programming 11
import javax.swing.*; import java.awt.*; import
java.awt.event.*;
public class FilledFrame extends JFrame
{
..
Color col = Color.red;
public void createComponent()
{
JButton but = new JButton("Press me");
but.addActionListener(
new ButtonHandler(this));
SquarePanel panel =
new SquarePanel(this);
// add components to content pane
// as before
}
}
Autumn 2016
CE203 Part 2
47
Event-Driven Programming 12
Autumn 2016
CE203 Part 2
48
Event-Driven Programming 13
Summary
Event handling allows the application to wait for user / system
initiated events.
An event handler class should be created (by extending
ActionListener or in the more general case EventListener).
The public actionPerformed method can than be overwritten to
hold the code to be executed when the event occurs.
The ActionListner interface is defined in the java.awt.event.*
framework
Autumn 2016
CE203 Part 2
49
Event-Driven Programming 14
General points
- Event handling is done in the same thread as draw
operations. Therefore, even handlers should be fast, so as
not to make execution appear slow or unresponsive.
- Separate threads may be added for more complex
operations (more on this at the end of the course).
- Good practice in even handling is to implement event
handlers in a none public class, this is more secure in large
projects.
Autumn 2016
CE203 Part 2
50
Handling Multiple Buttons 1
Many applications will require more than one control item (e.g.
multiple buttons, menu items, etc.)
We consider, as a worked example, the case of multiple buttons.
If the buttons perform unrelated tasks a separate action listener class
should be written for each. However, in many cases, several buttons
will perform similar tasks and it will be inefficient to write separate
action listener classes.
Two approaches are possible:
1) We can instantiate separate objects for each button, supplying an
argument to the constructor to indicate which is which,
2) or instantiate a single object, in which case it is necessary to
determine in the actionPerformed method which button has
been pressed.
Autumn 2016
CE203 Part 2
51
Handling Multiple Buttons 2
To illustrate the use of the two approaches we will consider
an application with buttons to change the colour of a square
to specific colours.
We shall place the buttons on a panel at the bottom of the
application, using the default layout manager for a panel,
FlowLayout, in which the components are positioned from
left to right as added, starting new rows whenever necessary.
When using FlowLayout the add method takes only one
argument since no location information is required.
It is not necessary to create a subclass of JPanel for the
button panel since we do not need to write any methods for
this panel.
Autumn 2016
CE203 Part 2
52
Handling Multiple Buttons 3
In FilledFrame class
// Imports and class setup as previously
Color col = Color.black;
public void createComponents()
{
JButton butR = new JButton("Red");
JButton butG = new JButton("Green");
JButton butB = new JButton("Blue");
// need to add action listeners
// to buttons
SquarePanel panel =
new SquarePanel(this);
Autumn 2016
CE203 Part 2
53
Handling Multiple Buttons 4
// Square2.java init method continued
JPanel butPanel = new JPanel();
butPanel.add(butR);
butPanel.add(butG);
butPanel.add(butB);
add(butPanel, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
}
}
Autumn 2016
CE203 Part 2
54
Handling Multiple Buttons 5
In the first version of a button-handler class for the multiplebutton application each button will use a separate handler
object; the objects need to be distinct so we need to supply
information about the button to the constructor. The simplest
way of doing this is to supply as an argument the colour
associated with the button.
The addActionListener calls to be added to the
initialisation method will be of the form
butR.addActionListener(
new ButtonHandler(this, Color.red));
Autumn 2016
CE203 Part 2
55
Handling Multiple Buttons 6
// Square2.java continued
class ButtonHandler implements ActionListener
{
FilledFrame theApp;
Color theColor;
ButtonHandler(FilledFrame app, Color color)
{
theApp = app;
theColor = color;
}
public void actionPerformed(ActionEvent e)
{
theApp.col = theColor;
theApp.repaint();
}
}
Autumn 2016
CE203 Part 2
56
Handling Multiple Buttons 7
Autumn 2016
CE203 Part 2
57
Handling Multiple Buttons 8
In the second version of the button-handler class we will use
a single button-handler object. The actionPerformed
method will have to determine which button has been pressed
so it must have access to the identity of the buttons – hence
they must be declared as instance variables of the
FilledFrame class, instead of local variables in the
constructor.
A single ButtonHandler object will be created and then used
as an argument to all of the calls to addActionListener.
The constructor will have only one argument since the object
needs no button-identity information.
Autumn 2016
CE203 Part 2
58
Handling Multiple Buttons 9
// imports as usual
public class FlledFrame extends JFrame
{
Color col = Color.black;
JButton butR, butG, butB;
}
public void createComponents()
{
butR = new JButton("Red");
// etc
ButtonHandler bh =
new ButtonHandler(this);
butR.addActionListener(bh);
// etc
// rest of method as before
}
Autumn 2016
CE203 Part 2
59
Handling Multiple Buttons 10
In the actionPerformed method we need to determine the
identity of the button that has been pressed.
This information is stored in the ActionEvent argument that
is supplied to the method by the application container. To
retrieve the information from the argument we can apply the
getSource method, which returns a reference to the
component with which the event was associated.
Autumn 2016
CE203 Part 2
60
Handling Multiple Buttons 11
// Square3.java continued
class ButtonHandler implements ActionListener
{
FilledFrame theApp;
ButtonHandler(FilledFrame app)
{
theApp = app;
}
}
public void actionPerformed(ActionEvent e)
{
if( e.getSource()==theApp.butR )
{
theApp.col = Color.red;
}
else if // etc
theApp.repaint();
}
Autumn 2016
CE203 Part 2
61
Handling Multiple Buttons 12
Summary
-Multiple buttons are an example of the general case of multiple similar
control options in an application e.g.
-Menu items
-Keyboard events
-Mouse events
-etc.
-Two approaches are possible:
1) Instantiate separate objects that implement the ActionListener
interface for each item (button).
2) Instantiate a single object and determine the event to be performed in
the actionPerformed method.
Autumn 2016
CE203 Part 2
62
Handling Multiple Buttons 13
For applications similar to the ones we developed the first
approach would probably be chosen since it is easier to adapt if
extra colour buttons are added – only the initialisation method
needs to be modified. If the second approach were chosen it would
be necessary to modify both the initialisation and
actionPerformed methods.
However, note that the first approach is more memory intensive, a
new event handler object has to be instantiated for each button.
In many applications a switch statement is used in the
actionPerformed method to select the appropriate action. Extra
cases would have to be added for extra buttons. There would then
be no adaptability advantage and the second approach may be
preferred, particularly if there are many buttons, in order to reduce
the number of objects created.
Autumn 2016
CE203 Part 2
63
Quiz
• A chance to test your knowledge
• Practice for assessed tests and exams
• Remember: be careful in picking your username.
Please do Not use names that could cause offence.
kahoot.it
Autumn 2016
CE203 Part 2
64
Summary
• Today we talked about…
– Graphical user interfaces
– Event driven programming
– Handling multiple buttons
• Remember:
– This weeks lab includes a signed feedback session.
– Attend and get feedback from the GLAs.
– Make sure they sign you off the list.
Autumn 2016
CE203 Part 2
65
Next week…
•
•
•
•
•
Inheritance
Abstract classes
Interfaces
Java collections framework
Vectors
Autumn 2016
CE203 Part 2
66