GUIs & Event Driven Programming

Download Report

Transcript GUIs & Event Driven Programming

Introduction to Swing
Introduction and Background
• Swing is Sun’s second Java GUI kit
• Built on AWT, but most programs will directly
use only Swing classes
• GUIs are built of components organized using
containers
• Swing components interact with the user using
an event listener model
About JFC and Swing
• JFC – JavaTM Foundation Classes
• Encompass a group of features for constructing
graphical user interfaces (GUI).
• Implemented without any native code.
• “Swing” is the codename of the project that
developed the first JFC components (JFC 1.11).
• The name “Swing” is frequently used to refer to new
components and related API.
1)
Initially released as an extension to JDK 1.1
About JFC and Swing (cont)
• Swing features:
– The Swing Components
• Dialog, Tabbed pane, Buttons, File Chooser, ...
– Pluggable Look and Feel
– Accessibility API
• Screen readers, Braille displays, ...
– Java 2DTM API (Java 2 Platform only)
– Drag and Drop (Java 2 Platform only)
• Between Java applications and native applications.
Pluggable Look and Feel
Each picture shows the same program but with a
different look and feel
Parts of a GUI
• Widgets
– objects like buttons,
windows, and text fields
– users interact with the
widgets using the mouse
and keyboard
– listeners may be attached to
one or more widgets
• Listeners
– objects which are notified when a
particular event occurs
– customized reaction to the event,
provided by the GUI designer
– standardized set of methods that the
listener must implement, provided by
the system
• Event Objects
– objects that contain information about
the event
• e.g. where it occurred
Swing Programs
• Four basic types of Swing
program:
– JFrame, a top level window
decorated like a native window
– JWindow, an undecorated
stand-alone window (splashscreen)
– JApplet, an embeddable
applet
– JDialog, a popup dialog
window
• Each program type is
implemented as a
framework class
How to write a Swing applet
• Extend JApplet
• Implement required
framework methods:
– init(), called when applet is
first loaded
– start(), start running
– stop(), stop running
– destroy(), clean up and
terminate
• In many cases, only init() is
needed
Swing Components
JComponent
AbstractButton
JButton
getSize()
setBackground()
setFont()
setText()
setIcon()
JToggleButton
JMenuItem
JFileChooser
JLabel
setCurrentDirectory()
setFileFilter()
JList
JPanel
JPopupMenu
JSlider
setMaximum()
setMinimum()
setPaintTicks()
• Components are the
“widgets” of Swing
• Most concrete Swing class
names start with a “J”
• All Swing components
subclass JComponent,
which provides generic
methods
• Containers, e.g. JPanel,
are also components
Swing Containers
java.awt.Component
java.awt.Container
javax.swing.JComponent
JInternalFrame
JLayeredPane
JPanel
JScrollPane
JSplitPane
JTabbedPane
• Components can be grouped
together into containers
• Within a container, component
positioning is controlled by a
layout manager, e.g.
FlowLayout, GridLayout
• Layout managers and
containers manage generic AWT
Components
• Intermediate containers are
useful for organization: they
form a containment hierarchy
Event Listeners
• User actions (mouse, keyboard) are represented as events
• Event Listeners are objects that process events on behalf
of Swing components
• Listeners are registered using a component add-listener
method, which takes the listener object as its argument
• There are many classes of events, each of which may
include several specific event types
• Each event class has an associated Java interface, e.g.
KeyListener, MouseListener
• The listener interface specifies methods that the Swing
infrastructure will call, one for each event type in the
class, e.g. keyPressed(), keyReleased()
• Event listener objects implement these interface methods
Swing Components
• Swing provides many standard GUI components
such as buttons, lists, menus, and text areas, which
you combine to create your program's GUI.
• Swing provides containers such as windows and
tool bars.
– top level: frames, dialogs
– intermediate level: panel, scroll pane, tabbed
pane, ...
– other Swing components: buttons, labels, ...
Containers
• Descendents of the java.awt.Container class
• Components that can contain other components.
• Use a layout manager to position and size the
components contained in them.
• Components are added to a container using one of the
various forms of its add method
– Depending on which layout manager is used by the
container
panel.add(component);
Top Level Containers
• Every program that presents a Swing GUI contains at
least one top-level container.
• A Top level container provides the support that Swing
components need to perform their painting and eventhandling.
• Swing provides three top-level containers:
– JFrame (Main window)
– JDialog (Secondary window)
– JApplet (An applet display area within a browser
window)
Top Level Containers (cont)
• To appear on screen, every GUI component
must be part of a containment hierarchy, with
a top-level container as its root.
• Each top-level container has a content pane
that contains visible components in that top-level
container’s GUI.
Don’t add a component
directly to a top-level
container.
JFrame
• A frame implemented as an instance of the
JFrame class, is a window that has
decorations such as a border, a title and
buttons for closing and iconifying the
window.
– The decorations on a frame are platform
dependent.
• Applications with a GUI typically use at
least one frame.
Example
import javax.swing.*;
public class HelloWorldSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("HelloWorldSwing");
final JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
pack() causes a window to be
}
sized to fit the preferred size and
layouts of its sub-components
Example
import javax.swing.*;
In this example a
custom frame is
created
public class HelloWorldFrame extends JFrame {
public HelloWorldFrame() {
super(“HelloWorldSwing”);
final JLabel label = new JLabel("Hello World");
getContentPane().add(label);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
HelloWorldFrame frame = new HelloWorldFrame();
}
}
JDialog
• Every dialog is dependent on a frame
– Destroying a frame destroys all its dependent dialogs.
– When the frame is iconified, its dependent dialogs
disappear from the screen.
– When the frame is deiconified, its dependent dialogs
return to the screen.
• A dialog can be modal. When a modal dialog is
visible it blocks user input to all other windows in
the program.
JDialog (cont)
• To create custom dialogs, use the JDialog
class directly (as in the previous
examples).
• Swing provides several standard dialogs
– JProgressBar, JFileChooser, JColorChooser,
...
• The JOptionPane class can be used to
create simple modal dialogs
– icons, title, text and buttons can be
customized.
Example
Object[] options = {"Yes!", "No, I'll pass",
"Well, if I must"};
int n = JOptionPane.showOptionDialog(
frame, "Duke is a cartoon mascot. \n" +
"Do you still want to cast your vote?",
"A Follow-up Question",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
options[2]);
JComponent
• JComponent is the base class for all
Swing components except top-level
containers.
– JLabel, JButton, JList, JPanel, JTable, ...
• To use a component that inherits from
JComponent, it must be placed in a
containment hierarchy who’s base is a toplevel container.
JComponent (cont)
• The JComponent class provides the following
(partial list):
–
–
–
–
–
–
Pluggable Look & Feel
Keystroke handling
Tooltip support
Accessibility
An infrastructure for painting
Support for borders.
• All descendents of JComponent are also
Containers
– A JButton can contain text, icons etc.
Borders
• Every JComponent can have one or more
borders.
• The class BorderFactory may be used to create
standard borders
pane.setBorder(BorderFactory.
createLineBorder(Color.black));
• Using a compound border, you can combine any
two borders, which can themselves be
compound borders
BorderFactory.createCompoundBorder(border1, border2);
Simple Borders
Titled Borders
Compound Border
Intermediate Level Containers
• Also known as panels or panes
• Simplify the positioning of other components.
– JPanel
• Play a visible and interactive role in a program’s
GUI
– JScrollPane
– JTabbedPane
• A panel’s default layout manager is FlowLayout.
– Other layout managers can easily be set
panel.setLayout(new BorderLayout());
Intermediate Level Containers
(cont)
• By default, panels don’t paint anything
except for their background.
• By default, panels are opaque.
– An opaque panel can be set as a top-level
container’s content pane.
– transparent (non-opaque) panels draw no
background.
AWT to Swing
• AWT: Abstract Windowing Toolkit
• import java.awt.*
• Swing: new with Java2
•
•
•
•
•
import javax.swing.*
Extends AWT
Standard dialog boxes, tooltips, …
Look-and-feel, skins
Event listeners
• API:
• http://java.sun.com/j2se/1.3/docs/api/index.html
GUI Component API
• Java: GUI component = class
• Properties
•
• Methods
•
• Events
•
JButton
Using a GUI Component
1. Create it
•
Instantiate object: b = new JButton(“press me”);
2. Configure it
•
•
Properties: b.text = “press me”;
java]
Methods:
b.setText(“press me”);
3. Add it
•
panel.add(b);
4. Listen to it
•
Events: Listeners
[avoided in
JButton
Anatomy of an Application GUI
GUI
Internal structure
JFrame
JFrame
JPanel
containers
JPanel
JButton
JButton
JLabel
JLabel
Using a GUI Component 2
1.
2.
3.
4.
5.
Create it
Configure it
Add children (if container)
Add to parent (if not JFrame)
Listen to it
order
important
Build from bottom up
• Create:
•
•
•
•
Frame
Panel
Components
Listeners
• Add: (bottom up)
Listener
JLabel
JButton
JPanel
• listeners into components
• components into panel
• panel into frame
JFrame
Code
JFrame f = new JFrame(“title”);
JPanel p = new JPanel( );
JButton b = new JButton(“press me”);
p.add(b); // add button to panel
f.setContentPane(p);// add panel to frame
f.show();
press me
Application Code
import javax.swing.*;
class hello {
public static void main(String[] args){
JFrame f = new JFrame(“title”);
JPanel p = new JPanel();
JButton b = new JButton(“press me”);
p.add(b);
f.setContentPane(p);
// add button to panel
// add panel to frame
f.show();
}
}
press me
Layout Management
• The process of determining the size and position
of components.
• Layout management can be done using
absolute positioning
– Size and position of every component within the
container must be specified.
– Does not adjust well when the top-level container is
resized.
– Does not adjust well to differences between users and
systems, such as font size.
Layout Manager Heuristics
null
FlowLayout
none,
programmer
sets x,y,w,h
Left to right,
Top to bottom
BorderLayout
n
w
c
s
e
CardLayout
One at a time
GridLayout
GridBagLayout
JButton
Layout Management (cont)
• Layout management is often performed
using layout mangers
– Components can provide size and position
hints to layout managers, but layout
managers have the final say on the size and
position of those components.
Layout Management (cont)
• Layout hints
– Minimum, preferred and maximum size
– X axis alignment, Y axis alignment
• Customizing layout hints
– Invoking setter methods: setMinimumSize,
setAlignmentX, ...
– Subclassing and overriding the getter
methods: getMinimumSize, getAlignmentX, ...
Layout Management (cont)
• The Java platform supplies five commonly
used layout managers:
– BorderLayout
– BoxLayout
– FlowLayout
– GridLayout
– GridBagLayout
Layout Management (cont)
• When using the add method to put a
component in a container, the container’s
layout manager must be taken into
account.
– Relative position (BorderLayout)
panel.add(component, BorderLayout.CENTER);
– Order of addition (BoxLayout, GridLayout, ...)
panel.add(component);
BorderLayout
• Has five areas available to hold components
– north, south, east, west and center
• All extra space is placed in the center area
– Only the center area is affected when the container is
resized.
• Default layout manager of content panes.
BoxLayout
• Places components in a single row (left to
right) or column (top to bottom).
• Respects component’s maximum size and
alignment hints.
FlowLayout
• Places components from left to right,
starting new rows if necessary.
• Default LayoutManager of JPanel
GridLayout
• Places components in a requested number of
rows and columns.
• Components are placed left-to-right and top-tobottom.
• Forces all components to be the same size
– as wide as the widest component's preferred width
– as high as the highest component’s preferred height
Layout Management (cont)
• The following factors influence the
amount of space between visible
components in a container:
– Layout manager
• automatically, user specified, none
– Invisible components
• often used with BoxLayout
– Empty borders
• works best with components that have no
default border such as panels and labels.
Combinations
JButton JButton
JTextArea
Combinations
JButton
JButton
JFrame
n
JPanel: FlowLayout
JPanel: BorderLayout
c
JTextArea
Code: null layout
JFrame f = new JFrame(“title”);
JPanel p = new JPanel( );
JButton b = new JButton(“press me”);
b.setBounds(new Rectangle(10,10, 100,50));
p.setLayout(null);
// x,y layout
p.add(b);
f.setContentPane(p);
press me
Code: FlowLayout
JFrame f =
JPanel p =
FlowLayout
JButton b1
JButton b2
new JFrame(“title”);
new JPanel( );
L = new FlowLayout( );
= new JButton(“press me”);
= new JButton(“then me”);
p.setLayout(L);
p.add(b1);
p.add(b2);
f.setContentPane(p);
Set layout mgr before adding components
press me then me
Applets
JApplet
• JApplet is like a JFrame
• Already has a panel
• Access panel with JApplet.getContentPane( ) contentPane
import javax.swing.*;
JButton
public class hello extends JApplet {
public void init(){
JButton b = new JButton(“press me”);
getContentPane().add(b);
}
Applet Methods
• Called by browser:
• init( ) - initialization
• start( ) - resume processing (e.g.
animations)
• stop( ) - pause
• destroy( )
- cleanup
• paint( ) - redraw stuff (‘expose’ event)
Application + Applet
import javax.swing.*;
import java.awt.*;
class helloApp {
public static void main(String[] args){
// create Frame and put my mainPanel in it
JFrame f = new JFrame(“title”);
mainPanel p = new mainPanel();
f.setContentPane(p);
f.show();
}
}
class helloApplet extends JApplet {
public void init(){
// put my mainPanel in the Applet
mainPanel p = new mainPanel();
getContentPane().add(p);
}
}
// my main GUI is in here:
class mainPanel extends JPanel {
mainPanel(){
setLayout(new FlowLayout());
JButton b = new JButton(“press me”);
add(b);
}
}
Command line
Browser
JFrame
JApplet
or
contentPane
JPanel
JButton
Applet Security
•
•
•
•
No read/write on client machine
Can’t execute programs on client machine
Communicate only with server
“Java applet window” Warning
Typical command line program
• Non-interactive
• Linear execution
program:
main()
{
code;
code;
code;
code;
code;
code;
code;
code;
code;
code;
code;
code;
}
Interactive command line
program
program:
• User input commands
• Non-linear execution
• Unpredictable order
• Much idle time
main()
{
decl data storage;
initialization code;
loop
{
}
}
get command;
switch(command)
{
command1:
code;
command2:
code;
…
}
Typical GUI program
GUI program:
• User input commands
• Non-linear execution
• Unpredictable order
• Much idle time
• Event callback procs
main()
{
decl data storage;
initialization code;
create GUI;
register callbacks;
}
main event loop;
Callback1()
{
code;
}
Callback2()
{
code;
}
…
//button1 press
GUI Events
App1
mouse
click
OK
App2
OK
Cancel
Cancel
App2 code:
App1
event
loop
Window
System
input
device
event
loop
which
app?
App2
event
loop
which
callback?
OKbtn_click()
{
do stuff;
}
OKbtn_mouseover()
{
do more stuff;
}
CancelBtn_click()
{
do different stuff;
}
Example
Example: draw program
MyDrawClass{
main()
{
DataStruct drawn_shapes;
drawn_shapes.clear();
}
create Frame, Panel, buttons, …
register listeners;
DrawPanel_listener_click()
{
drawn_shapes.add(new shape);
}
UndoButton_listener_click()
{
drawn_shapes.deleteLast();
}
…
Events Handling
• Every time a user types a character or pushes a
mouse button, an event occurs.
• Any object can be notified of an event by
registering as an event listener on the
appropriate event source.
• Multiple listeners can register to be notified of
events of a particular type from a particular
source.
Java Listeners
1. Register with a component to receive events
•
•
Give component a ref to your Listener object
JButton1.addMouseListener(new myMouseListener)
2. Receive events from component
•
•
Component will call callback procs
on your Listener object
myMouseListener.mouseClicked(event)
click
JButton1
1. addMouseListener( )
2. mouseClicked( )
myMouseListener
Types of Event Listeners
Act that results in event
Listener type
User clicks a button, presses Return while typing
in a text field, or chooses a menu item
ActionListener
User closes a frame (main window)
WindowListener
User presses a mouse button while the cursor is
over a component
MouseListener
User moves the mouse over a component
MouseMotionListener
Component becomes visible
ComponentListener
Component gets the keyboard focus
FocusListener
Table or list selection changes
ListSelectionListener
Implementing an Event Handler
•
•
•
Implement a listener interface or extend a
class that implements a listener interface.
Register an instance of the event handler class
as a listener upon one or more components.
Implement the methods in the listener interface
to handle the event.
Example
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
numClicks++;
label.setText(labelPrefix + numClicks);
}});
Listener API
• Listeners must inherit from Java Listener
base classes
• ActionListener, KeyListener, MouseListener,
MouseMotionListener, WindowListener, …
• Abstract base classes: xxxxListener
• Stubbed base classes: xxxxAdapter
• MouseListener:
• mouseClicked(), mouseEntered(), mouseExited(),
mousePressed(), mouseReleased()
Code
button1 = new JButton(“press me”);
myListener = new myListenClass;
button1.addMouseListener(myListener);
// extending a class (“subclassing”):
class myListenClass extends MouseAdapter {
public void mouseClicked(MouseEvent e){
// button clicked, do stuff here
}
}
// OR “implementing an interface”:
class myListenClass implements MouseListener {
public void mouseClicked(MouseEvent e){
// button clicked, do stuff here
An abstract
}
base class
…
(methods,
}
no code)
Event objects
• mouseClicked(MouseEvent e)
• MouseEvent:
• getX( ), getY( ), getClickCount( ), getSource( ), …
• For each listener type:
•
•
•
•
Component.addxxxxListener( )
xxxxListener abstract base class
xxxxAdapter stubbed base class
xxxxEvent
Inheritance with Swing
class myPanel extends JPanel
{
public myPanel(){
//constructor
// create buttons, …
}
public void paintComponent(Graphics g){
super.paint(g); //call overriden method
// paint stuff here
}
}
• myPanel creates JPanel via inheritance
• Override JPanel methods to add functionality
Simplifying: Implements
abstract
base class
class myPanel extends JPanel
implements MouseListener
{
public myPanel(){
//constructor
button1 = new JButton(“press me”);
button1.addMouseListener(this);
add(button1);
}
public void mouseClicked(MouseEvent e){
// button clicked, do stuff here
}
…
}
Simplifying: Anonymous classes
class myPanel extends JPanel
{
public myPanel(){
button1 = new JButton(“press me”);
button1.addMouseListener(
new MouseAdapter() {
public void mouseClicked(MouseEvent e){
// button clicked, do stuff here
}
}
Defining and
);
instantiating a
add(button1);
}
class on the fly
}
A Simple GUI
Creating a GUI
•
•
•
•
•
•
•
import Java libraries - swing, awt
construct a frame object
declare widgets - instance variables
choose, construct and set the layout
add widgets
Order doesn’t
attach listeners
matter here
implement the listeners
Find Patterns in the Code for a
Simple GUI
import
import
import
import
import
import
import
import
javax.swing.JFrame;
javax.swing.JTextArea;
Swing - Newer GUI library
javax.swing.JTextField;
May import many classes at once
javax.swing.JButton;
import javax.swing.*;
java.awt.Container;
java.awt.event.ActionListener;
java.awt.event.ActionEvent;
java.awt.FlowLayout;
AWT - Abstract
Window Toolkit
Older GUI library
Declare Widgets
(Instance Variables)
/** A simple program demonstrating input from TextFields and
Buttons, and output to a TextArea.
*/
Basic window
public class FirstExampleDemo extends JFrame
widget
{
// Declare the GUI widgets we'll use.
private JTextArea outputTA = new JTextArea(10, 30);
private JTextField inputTF = new JTextField(30);
private JButton clearButton = new JButton("Clear");
Format the Main Window
and Add the Widgets
// Set up the GUI.
public FirstExampleDemo()
{ this.setSize(400, 300);
// Add all the GUI widgets to the frame
Container contents = this.getContentPane();
contents.setLayout(new FlowLayout());
contents.add(outputTA);
contents.add(inputTF);
contents.add(clearButton);
Must set the layout style of
the window, and add the
widgets to the associated
Content Pane
Attach Listeners
ClearListener cl = new ClearListener();
// Attach listeners
clearButton.addActionListener(cl);
inputTF.addActionListener(new AddListener());
}
Define Listeners
(Implement Interfaces)
// Define a listener for the add textfield.
private class AddListener implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ String text = inputTF.getText();
outputTA.append(text + "\n");
ActionListener
inputTF.setText("");
invoked on mouse
}
click or enter key
}
// Define a listener for the clear button.
private class ClearListener implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ outputTA.setText("");
}
}
}
Implementing a Listener
• implement an interface
– the system needs to know that when an event happens,
the listener attached to one of your widgets has a
predictable set of methods
• using inner classes
– the listener the GUI designer writes needs to be
defined within the GUI class (helper class)
– the listener typically needs access to the private
instance variables (widgets) of the GUI class to update
the display
Complex GUI
A Calculator
Patterns from the Calculator GUI
• Layout choices
– FlowLayout, GridLayout, BorderLayout, …
• JPanel
– allows a nested layout design
• ActionEvent object (ActionListener
parameter) methods
– public Object getSource()
• returns the widget which invoked the listener
– public String getActionCommand()
• returns text associated with the widget
Layout Choices
& Nesting Panels
// Add all the GUI widgets to the frame
Container contents = this.getContentPane();
contents.setLayout(new BorderLayout());
contents.add(displayScreen, BorderLayout.NORTH);
//A BorderLayout has 5 regions - north, south, east, west, center
contents.add(addOperations(), BorderLayout.EAST);
contents.add(addNumbers(), BorderLayout.CENTER);
JPanel opButtons = new JPanel();
opButtons.setLayout(new GridLayout(3, 2));
//Specify the number of rows, columns in the grid
Using ActionEvent Objects in a
Listener
private class DigitListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
displayScreen.append(e.getActionCommand());
}
}
Every digit button needs basically
the same listener. All the listener
needs to know is the number
showing on the button.
… but it doesn’t do anything
• To make the calculator work properly, we need more
code
• Separate the application logic from the GUI
– create a new class, for example
• CalcApp - program logic class
• CalcGUI - program GUI class
• listeners need to call methods from CalcApp
– need to have an object from CalcApp as an instance variable in
the CalcGUI class
– may want to communicate to the GUI from the CalcApp class
– send “this” as a parameter to the CalcApp constructor when initializing
the instance variable in the CalcGUI class
Create the Program Logic
• Write code that will logically accept a
number generated by clicking the digit
buttons
• Write the code that will logically
calculate the sum of two numbers
• Update the GUI listeners by calling
methods from the application class
Conclusions
• Swing is still buggy (e.g. painting glitches)
• Lack of built-in support of Java2 in today’s
browsers makes using Swing more difficult
BUT
• Swing is powerful and easy to use
• Java’s OO model is perfectly suited for GUI
programming
References
• http://java.sun.com/j2se/1.3/docs/api/
index.html
• http://java.sun.com/docs/books/tutorial/uiswing/compon
ents/components.html