Title: Web Programming Course
1Web Programming Course
- Lecture 2 GUI, AWT, Swing
2Programming in prehistoric times
- Early programs were all batch processing
- There was no interaction with the user
3Command-driven programs
- Allow the user to enter commands
- Much more flexible
- Still only a single source of inputs
- Not good enough for modern programs
4Modern event-driven programs
- Multiple sources of input
- mouse clicks
- keyboard
- timers
- external events
- A new program structure is required
- event loop
5Java hides the event loop
- The event loop is built into Java GUIs
- GUI stands for Graphical User Interface
- Interacting with a GUI component (such as a
button) causes an event to occur - An Event is an object
- You create Listeners for interesting events
- The Listener gets the Event as a parameter
6AWT (Abstract Window Toolkit)
- Present in all Java implementations
- Described in most Java textbooks
- Adequate for many applications
- OS-dependent
- Uses the controls defined by your OS
- Difficult to build an attractive GUI
- import java.awt.import java.awt.event.
7Swing
- Same concepts as AWT
- Defined in JDK version 1.1 and later
- Many more controls, and they are more flexible
- Some controls, but not all, are a lot more
complicated - Gives a choice of look and feel packages
- Much easier to build an attractive GUI
- import javax.swing.
8Swing vs. AWT
- AWT is simpler
- Swing is more flexible and better looking
- Mixing Swing and AWT components is not
recommended - Many of the common controls are just renamed
- AWT Button b new Button ("OK")
- Swing JButton b new JButton("OK")
- Learning the AWT is a good start for learning
Swing
9To build a GUI...
- Make a Container to display things
- usually a Frame or Dialog for an application
- or an Applet
- Create some Components, such as buttons, text
areas, panels, etc. - Add the Components to the Container
- Arrange, or lay-out, your Components
- Attach Listeners to your Components
- Interacting with a Component causes an Event to
occur - A Listener gets a message when an interesting
event occurs, and executes your code to deal with
it
10Containers and Components
- The goal of a Container is to hold and display
Components - Some common subclasses of Component are Button,
Checkbox, Label, List, Scrollbar, TextField, and
TextArea - A Container is also a Component
- This allows Containers to be nested
- Not uncommon with Layout Managers
- Some Container subclasses are Panel (and Applet),
Window, and Frame
11An Applet is Panel is a Container
java.lang.Object ----java.awt.Component
----java.awt.Container
----java.awt.Panel
----java.applet.Applet
so you can display things in an Applet
12Applets
- An application has a main() method
- An Applet usually does not
- An Applet's main method is in the Browser
- Browser invokes the Applet
- To write an Applet, you extend Applet and
override some of its methods - The most important methods are init(), start(),
and paint(Graphics g)
13To create an applet
- public class MyApplet extends Applet
- This is the only way to make an Applet
- You can add components to the applet
- As there is no main() method, the best place to
initialize, add and layout the components is
init() - You can paint directly on the applet
- However, it is better to paint on a contained
component - Do all painting from paint(Graphics g)
14Example A "Life" applet
15Some types of components
Button
Checkbox
Label
Scrollbar
Choice
TextField
List
TextArea
Button
Checkbox
16Creating Components
- Label lab new Label ("Hello World")
- Button but new Button ("Click me!")
- Checkbox toggle new Checkbox ("toggle")
- TextField txt new TextField ("Initial
text", 20) - Scrollbar scrolly new Scrollbar
(Scrollbar.HORIZONTAL, initialValue,
bubbleSize, minValue, maxValue)
17Adding components to the Applet
- class MyApplet extends Applet
- public void init ()
- add (lab) // identical to this.add(lab)
- add (but)
- add (toggle)
- add (txt)
- add (scrolly)
- ...
18Creating a Frame
- When you write an Applet, you get a Panel for
free - When you write an application, you need to create
and use a Frame - Frame frame new Frame()
- frame.setTitle("My Frame")
- frame.setSize(300, 200) // width, height
- ... add components ...
- frame.setVisible(true)
- Or use
- class MyClass extends Frame
19Arranging Components
- Every Container has a layout manager
- The default layout for a Panel is FlowLayout
- An Applet is a Panel
- Therefore, the default layout for a Applet is
also FlowLayout - You could set the layout explicitly with
setLayout (new FlowLayout()) - In many cases, a single layout is not enough
- Applet may include a number of Panels, each using
a different layout
20FlowLayout
- Use add(component) to add to a component when
using a FlowLayout - Components are added left-to-right
- If no room, a new row is automatically started
- Exact layout depends on size of an applet
- Components are made as small as possible
- FlowLayout is convenient but often ugly
21Complete example FlowLayout
import java.awt.import java.applet. public
class FLExample extends Applet public void
init () setLayout (new FlowLayout ())
add (new Button ("One")) add (new Button
("Two")) add (new Button ("Three")) add
(new Button ("Four")) add (new Button
("Five")) add (new Button ("Six"))
22BorderLayout
- At most five components can be added
- If you want more components, add a Panel, then
add components to it. - setLayout (new BorderLayout())
- Specify the destination of every added component
add (new Button("NORTH"), BorderLayout.NORTH)
23Complete example BorderLayout
import java.awt.import java.applet. public
class BorderLayoutExample extends Applet
public void init () setLayout (new
BorderLayout()) add(new Button("One"),
BorderLayout.NORTH) add(new
Button("Two"), BorderLayout.WEST)
add(new Button("Three"), BorderLayout.CENTER)
add(new Button("Four"), BorderLayout.EAST)
add(new Button("Five"), BorderLayout.SOUTH)
add(new Button("Six"),
BorderLayout.SOUTH)
24GridLayout
- The GridLayout manager divides the container up
into a given number of rows and columns
- new GridLayout(rows, columns)
- Setting rows0 or columns0 means as many as
needed - All sections of the grid are equally sized and as
large as possible
25Complete example GridLayout
import java.awt.import java.applet. public
class GridLayoutExample extends Applet public
void init () setLayout(new GridLayout(2,
3)) add(new Button("One")) add(new
Button("Two")) add(new Button("Three"))
add(new Button("Four")) add(new
Button("Five"))
26Checkbox Example
- public class Checkboxes extends Frame
- public Checkboxes()
- super("Checkboxes")
- setLayout(new GridLayout(0, 2))
- Checkbox box
- for(int i0 i
- box new Checkbox("Checkbox " i)
- if (i2 0)
- box.setState(true)
-
- add(box)
-
- pack()
- setVisible(true)
-
-
27CheckboxGroup Example
- import java.applet.Applet
- import java.awt.
- public class CheckboxGroups extends Applet
- public void init()
- setLayout(new GridLayout(4, 2))
- setBackground(Color.lightGray)
- setFont(new Font("Serif", Font.BOLD, 16))
- add(new Label("Flavor", Label.CENTER))
- add(new Label("Toppings", Label.CENTER))
- CheckboxGroup flavorGroup new
CheckboxGroup() - add(new Checkbox("Vanilla", flavorGroup,
true)) - add(new Checkbox("Colored Sprinkles"))
- add(new Checkbox("Chocolate", flavorGroup,
false)) - add(new Checkbox("Cashews"))
- add(new Checkbox("Strawberry", flavorGroup,
false)) - add(new Checkbox("Kiwi"))
-
28Using a Panel
- Panel p new Panel()
- add (p, BorderLayout.SOUTH)
- p.add (new Button ("Button 1"))
- p.add (new Button ("Button 2"))
- Allows more flexible layouts of components
- Every panel gets its own layout
- Logical separation of components
- Order of adding components to a panel and adding
a panel to a container is arbitrary
29Making components active
- Most components already appear to do something
buttons click, text appears - No response on the actions is defined
- To associate an action with a component, attach a
listener to it - Components send events, listeners listen for
events and invoke appropriate handlers - Different components may send different events,
and require different listeners
30Listeners
- Listeners are interfaces, not classes
- class MyButtonListener implements
ActionListener - An interface is a group of methods that must be
supplied - When you say implements, you are promising to
supply those methods - Thus, every component has a set of well-known
actions - Handlers implement the responses to these actions
31Writing a Listener
- For a Button, you need an ActionListener
- button.addActionListener (new
MyButtonListener ()) - An ActionListener must have an actionPerformed(Act
ionEvent) method - public void actionPerformed(ActionEvent e)
32MyButtonListener
public void init () ...
b1.addActionListener (new MyButtonListener ())
class MyButtonListener implements ActionListener
public void actionPerformed (ActionEvent e)
showStatus ("Ouch!")
33Useful Listeners and Methods
34Useful Listeners and Methods
35MouseEvent example
- import java.applet.Applet
- import java.awt.
- public class ClickReporter extends Applet
- public void init()
- setBackground(Color.yellow)
- addMouseListener(new ClickListener())
-
-
- public class ClickListener extends
- MouseAdapter
- public void mousePressed(MouseEvent event)
- System.out.println("Mouse pressed at ("
- event.getX() "," event.getY()
").") -
36Summary Building a GUI recipe
- Create a container, such as Frame or Applet
- Choose a layout manager
- Create more complex layouts by adding Panels
- each Panel can have its own layout manager
- Create other components and add them to the
Panels - For each active component, look up which
Listeners it can have - Create (implement) the Listeners
- often there is one Listener for each active
component - Active components can share the same Listener
- For each Listener, supply the methods that it
requires
37Adding a few listeners
- import java.applet.Applet
- import java.awt.
- import java.awt.event.
- public class SimpleWhiteboard extends Applet
- protected int lastX0, lastY0
- public void init()
- setBackground(Color.white)
- setForeground(Color.blue)
- addMouseListener(
- new PositionRecorder())
- addMouseMotionListener(
- new LineDrawer())
-
- protected void record(int x, int y)
- lastX x lastY y
-
38Adding a few listeners
- private class PositionRecorder extends
MouseAdapter - public void mouseEntered(MouseEvent event)
- record(event.getX(), event.getY())
-
- public void mousePressed(MouseEvent event)
- record(event.getX(), event.getY())
-
-
- private class LineDrawer extends
MouseMotionAdapter - public void mouseDragged(MouseEvent event)
- int x event.getX()
- int y event.getY()
- Graphics g getGraphics()
- g.drawLine(lastX, lastY, x, y)
- record(x, y)
-
-
39AWT and Swing
- AWT Buttons vs. Swing JButtons
- A Button is a Component
- A JButton is an AbstractButton, which is a
JComponent, which is a Container, which is a
Component - Containers
- Swing uses AWT Containers
- AWT Frames vs. Swing JFrames
- A Frame is a Window is a Container is a Component
- A JFrame is a Frame is a Container is a Component
- Layout managers
- Swing uses the AWT layout managers, plus a couple
of its own - Listeners
- Swing uses many of the AWT listeners, plus a
couple of its own
40Importing the necessary packages
- The Swing components are in javax.swing., so it
needs to be imported for a Swing application - Swing is built on top of AWT and uses a number of
AWT packages, including most of the layout
managers, so you need to import java.awt. - Most listeners also come from the AWT, so you
also need to import java.awt.event. - A few listeners, such as DocumentListener and
ListSelectionListener, are specific to Swing, so
you may need to import javax.swing event.
41JButton Example Code
- import java.awt.
- import javax.swing.
- public class JButtons extends JFrame
- public static void main(String args)
- new JButtons()
-
- public JButtons()
- super("Using JButton")
- WindowUtilities.setNativeLookAndFeel()
- addWindowListener(new ExitListener())
- Container content getContentPane()
- content.setBackground(Color.white)
- content.setLayout(new FlowLayout())
42JButton Example Code
- JButton button1 new JButton("Java")
- content.add(button1)
- ImageIcon cup new ImageIcon("images/cup.gif"
) - JButton button2 new JButton(cup)
- content.add(button2)
- JButton button3 new JButton("Java", cup)
- content.add(button3)
- JButton button4 new JButton("Java", cup)
- button4.setHorizontalTextPosition(SwingConstan
ts.LEFT) - content.add(button4)
- pack()
- setVisible(true)
-
43Make a Container
- For an application, a container is typically
JFrame - JFrame frame new JFrame()
- JFrame frame new JFrame("Text in title bar")
- You can create a JFrame in your main class
- It is often more convenient to have the main
class extending JFrame - For an applet, your main class extends JApplet
- Once your application or applet is up and
running, it create and display various dialogs
44Creating components
- JButton button new JButton("Click me!")
- JLabel label new JLabel("This is a JLabel")
- JTextField textField1 new JTextField("This is
the initial text") - JTextField textField2 new JTextField("Initial
text", columns) - JTextArea textArea1 new JTextArea("Initial
text") - JTextArea textArea2 new JTextArea(rows,
columns) - JTextArea textArea3 new JTextArea("Initial
text", rows, columns) - JCheckBox checkbox new JCheckBox("Label for
checkbox") - JRadioButton radioButton1 new
JRadioButton("Label for button") - ButtonGroup group new ButtonGroup()group.add(r
adioButton1) group.add(radioButton2) - Many others
45Layout managers
- Useful layout managers are
- BorderLayout, FlowLayout and GridLayout are
adopted from AWT - BorderLayout is the default layout for JFrame and
JApplet - BoxLayout
- Creates a horizontal row or a vertical stack
- GridBagLayout
- Modifiable grid of rows and columns
- NullLayout
- The most flexible and the hardest one
- Coordinates and dimensions of the components are
specified - Many more
46NullLayout Manager
- setLayout(null)
- Button b1 new Button("Button 1")
- Button b2 new Button("Button 2")
- ...
- b1.setBounds(0, 0, 150, 50)
- b2.setBounds(150, 0, 75, 50)
- ...
- add(b1)
- add(b2)
- ...
47BorderLayout
- public class BorderLayoutExample extends JApplet
public void init () setLayout(new
BorderLayout ()) add(new JButton("One"),
BorderLayout.NORTH) add(new JButton("Two"),
BorderLayout.WEST) add(new
JButton("Three"), BorderLayout.CENTER)
add(new JButton("Four"), BorderLayout.EAST)
add(new JButton("Five"), BorderLayout.SOUTH)
add(new JButton("Six"))
48FlowLayout
- public class FlowLayoutExample extends JApplet
public void init () setLayout(new
FlowLayout ()) add(new JButton("One"))
add(new JButton("Two")) add(new
JButton("Three")) add(new JButton("Four"))
add(new JButton("Five")) add(new
JButton("Six"))
49GridLayout
- public class GridLayoutExample extends JApplet
public void init() setLayout(new
GridLayout(2, 3)) add(new
JButton("One")) add(new
JButton("Two")) add(new
JButton("Three")) add(new
JButton("Four")) add(new
JButton("Five"))
50BoxLayout
- public class BoxLayoutExample extends JApplet
public void init () Box box new
Box(BoxLayout.Y_AXIS) add(box)
box.add(new JButton("One")) box.add(new
JButton("Two")) box.add(new
JButton("Three")) box.add(new
JButton("Four")) box.add(new
JButton("Five")) box.add(new
JButton("Six"))
51Nested layouts
- A JPanel is both a JContainer and a Component
- Since it is a container, you can put other
components into it - Since it is a component, you can put it into
other containers - All but the very simplest GUIs are built by
creating several JPanels, arranging them, and
putting components (possibly other JPanels) into
them - A good approach is to draw (on paper) the desired
arrangement, then finding an arrangement of
JPanels and their layout managers that
accomplishes it
52An example of nested layout
- Container container new JFrame() //or
JApplet() JPanel p1 new JPanel()
p1.setLayout(new BorderLayout())p1.add(new
JButton("A"), BorderLayout.NORTH) // also
add buttons B, C, D, EJPanel p2 new
JPanel()p2.setLayout(new GridLayout(3,
2))p2.add(new JButton("F")) // also add
buttons G, H, I, J, KJPanel p3 new
JPanel()p3.setLayout(new BoxLayout(p3,
BoxLayout.Y_AXIS))p3.add(new JButton("L"))
// also add buttons M, N, O, P
container.setLayout(new BorderLayout())
container.add(p1, BorderLayout.CENTER)
container.add(p2, BorderLayout.SOUTH)
container.add(p3, BorderLayout.EAST)
53Nested Layout
- public NestedLayout()
- setLayout(new BorderLayout(2,2))
- textArea new JTextArea(12,40)
- bSaveAs new JButton("Save As")
- fileField new JTextField("C\\Document.txt")
- bOk new JButton("OK")
- bExit new JButton("Exit")
- add(textArea,BorderLayout.CENTER)
- JPanel bottomPanel new JPanel()
- bottomPanel.setLayout(new GridLayout(2,1))
- JPanel subPanel1 new JPanel()
- JPanel subPanel2 new JPanel()
- subPanel1.setLayout(new BorderLayout())
- subPanel2.setLayout(new FlowLayout(FlowLayout.
RIGHT,2,2)) - subPanel1.add(bSaveAs,BorderLayout.WEST)
- subPanel1.add(fileField,BorderLayout.CENTER)
- subPanel2.add(bOk)
- subPanel2.add(bExit)
- bottomPanel.add(subPanel1)
54Suggested program arrangement
- class SomeClass
- // Declare components as instance
variables JFrame frame // Can also define
them here if you prefer JButton button - public static void main(String args)
new SomeClass().createGui() - // Define components and attach
listeners in a method void createGui()
frame new JFrame() button
new JButton("OK") frame.add(button)
// (uses default BorderLayout)
button.addActionListener(new MyOkListener())
-
- class MyOkButtonListener implements
ActionListener public void
actionPerformed(ActionEvent event) //
Code to handle button click goes here
55Suggested program arrangement
- class SomeClass extends JFrame
- // Declare components as instance
variables // JFrame frame // Does not need
this JButton button - public static void main(String args)
new SomeClass().createGui() - // Define components and attach
listeners in a method void createGui()
// frame new JFrame() // Don't need
this button new JButton("OK")
add(button) // Was frame.add(button)
button.addActionListener(new MyOkListener())
-
- class MyOkButtonListener implements
ActionListener public void
actionPerformed(ActionEvent event)
// Code to handle button click goes here
56Getting values
- Some actions normally cause the program to do
something click a button, or select from a menu - Some user actions set values to be used later
entering text, setting a checkbox or a radio
button - You can listen for events from these, but its
not usually a good idea - Instead, read their values when you need them
- String myText myJTextField.getText()
- String myText myJTextArea.getText()
- boolean checked myJCheckBox.isSelected()
- boolean selected1 myJRadioButton1.isSelected()
57Enabling and disabling components
- From HCI point of view, it is a bad style to
remove components you do not want the user to be
able to use - It is better to enable and disable controls
- Disabled controls appear grayed out
- The user may still wonder, but that is less
confusing - anyComponent.setEnabled(bool)
- For textual components, it is possible to disable
writing through component.setEditable(bool)
58Dialogs
- A dialog (small accessory window) can be modal or
non-modal - When your code opens a modal dialog, it waits for
a result from the dialog before continuing
(blocking) - When your code opens a non-modal dialog, you can
keep working in another container (non-blocking) - Java supplies a few useful modal dialogs
- You can create your own dialogs (with JDialog),
but they are non-modal by default
59Message dialogs
- JOptionPane.showMessageDialog(parentJFrame,
"This is a JOptionPane \"message\" dialog.") - Notice that showMessageDialog is a static method
of JOptionPane - The parentJFrame is typically the main GUI
window (but it is possible to use null if no main
GUI window is used)
60Confirm dialogs
- int yesNo JOptionPane.showConfirmDialog(
parentJFrame, "Is this what
you wanted to see?") - if (yesNo JOptionPane.YES_OPTION) ...
else ...
61Input dialogs
- String userName JOptionPane.showInputDialog(
parentJFrame,
"What is your name?")
62Option dialogs
- Object options new String "English",
"Chinese", "French", "German" - int option JOptionPane.showOptionDialog(paren
tJFrame, "Choose an option", "Option Dialog",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTIO
N_MESSAGE, null, options, options0) // use
as default
- 4th argument could be JOptionPane.YES_NO_CANCEL_OP
TION - 5th argument specifies which icon to use in the
dialog it could be one of ERROR_MESSAGE,
INFORMATION_MESSAGE, WARNING_MESSAGE, or
PLAIN_MESSAGE - 6th argument (null above) can specify a custom
icon
63Load file dialogs
- JFileChooser chooser new JFileChooser()choose
r.setDialogTitle("Load which file?") - int result chooser.showOpenDialog(enclosingJFra
me)if (result JFileChooser.APPROVE_OPTION)
File file chooser.getSelectedFile()
// use file
- Also test CANCEL_OPTION or ERROR_OPTION
- You will get back a File object. To use it, you
must know how to do file I/O
64JOptionPane Message Dialogs (Windows
Look-And-Feel)
65JOptionPane Confirmation Dialogs (Java
Look-And-Feel)
66Loading images
- import java.awt.
- import javax.swing.
- class JavaMan extends JPanel
- private Image javaMan
- public JavaMan3()
- String imageFile System.getProperty("user.di
r") - "/images/Java-Man.gif"
- javaMan getToolkit().getImage(imageFile)
- setBackground(Color.white)
-
- public void paintComponent(Graphics g)
- super.paintComponent(g)
- g.drawImage(javaMan, 0, 0, this)
-
-
67Quitting the program
- gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
- Other options are DO_NOTHING_ON_CLOSE,
HIDE_ON_CLOSE, and DISPOSE_ON_CLOSE - Window closing operation should be explicitly
defined for AWT frames - windowClosed(WindowEvent e)
- System.exit(0)
-