Title: CS242 Advanced Programming Concepts in Java
1CS242Advanced Programming Concepts in Java
Prof. Searleman jets_at_clarkson.edu
2Announcements
- IBM Master the Mainframe Contest
- Registration is now open Contest starts Oct. 1st
- over 17,000 in prizes, including T-shirts,
pre-paid debit cards, Nintendo Wii systems and
trips to the mainframe lab in Poughkeepsie, NY. - No mainframe or large systems experience is
necessary. - Contest homepage ibm.com/university/contest
- Clarkson Student Chapter of the ACM
- Why didnt you tell me this 8.923 years ago?
Dr. Richard Sharp, Thursday, Oct.
4th, 730 pm, Snell 212 - Java game challenge
a horrible death to die
3Outline
- Event-Driven Programming
- Event Object, Event Sources and Event Listeners
- Action Handling
- examples ButtonGUI ButtonPanel
- Identifying the Event Source
- getSource() and getActionCommand()
- Custom Painting
- PaintComponent()
- Graphics Context
- Toolkit
- HW3 due today
- Exam1 Thursday, Oct. 11, SC356, 700 pm
4Exam1 concepts
- Object-Oriented Programming
- polymorphism
- inheritance vs. composition
- Objects and Classes
- references, static, public/private, final,
immutable - casting
- Methods
- constructor, accessor, mutator
- this, this(), super, super()
- toString(), equals() hashCode(), compareTo()
interactions - Interfaces
- Arrays
- Exception Handling
- throwing, propagating, try/catch
5Recap Basic Swing code
- Import the pertinent packages
- Set up a top-level container.
- Display the container.
- Be thread-safe.
- javax.swing.SwingUtilities.invokeLater(
- new Runnable()
- public void run()
- / create and show the GUI /
- // end run
- // end Runnable
- ) // create and run a thread
Why thread-safe? Show example of non-responsive
GUI.
6Recap Action Handling
- A simple form of event handling just one action
to perform when the event occurs - Uses interface ActionListener
- ActionListener has only one method to implement
actionPerformed()
7Example 2 ButtonGUI
Action to perform count show the number of
times the button was clicked
8exampleButtonGUI
9public class ButtonGUI implements ActionListener
private static String labelPrefix "Number
of button clicks " private int numClicks
0 final JLabel label new
JLabel(labelPrefix "0 ") public
Component createComponents() JButton
button new JButton(Click Me!")
button.addActionListener(this)
label.setLabelFor(button) JPanel pane
new JPanel(new GridLayout(0, 1))
pane.setBorder(BorderFactory.createEmptyBorder(30,
30, 10, 30)) pane.add(button)
pane.add(label) return pane
10// public class ButtonGUI // implements
ActionListener (cont) public void
actionPerformed(ActionEvent evt)
numClicks label.setText(labelPrefix
numClicks)
3. When the button is clicked, an ActionEvent
object is created and sent as arg evt in method
actionPerformed in listener ButtonGUI The
desired response is to increment the instance
variable numClicks and update the JLabel. (The
info in the event object is ignored)
11private static void createAndShowGUI() JFrame
frame new JFrame(ButtonClicks")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS
E) ButtonGUI interface new ButtonGUI()
Component contents interface.createCom
ponents() frame.getContentPane().add(contents,
BorderLayout.CENTER) frame.pack()
frame.setVisible(true) public static void
main(String args) javax.swing.SwingUtilities
.invokeLater(new Runnable() public void
run() createAndShowGUI() )
12Example 3 ButtonPanel
Action to perform paint the background red when
the red button is clicked or paint it blue when
the blue button is clicked
13exampleButtonPanel
14a ButtonPanel object will be the event listener
public class ButtonPanel extends JPanel
implements ActionListener private JButton
button1 private JButton button2 public
ButtonPanel() setLayout(new
BoxLayout(this, BoxLayout.X_AXIS))
setBorder(BorderFactory.createEmptyBorder(30,30
,30,30)) button1 new JButton("red")
button2 new JButton("blue")
event sources are two buttons, stored as instance
variables
the constructor sets the layout border for the
panel, and creates the 2 buttons
15// constructor for ButtonPanel(), cont
add(Box.createHorizontalGlue())
add(button1) add(Box.createHorizontalStrut(
15)) add(button2) add(Box.createHorizontal
Glue()) button1.addActionListener(this)
button2.addActionListener(this)
add the 2 buttons to the panel, with some glue
and struts between them
register the panel as a listener for both button1
and button2
16// ButtonPanel (cont) public void
actionPerformed(ActionEvent evt)
// Action to perform make the background // red
if the red button was clicked, or // blue if
the blue button was clicked
question how does the panel tell which button
was clicked?
answer that information is encapsulated in the
event object, evt
17Identifying the event source
- There are two methods
- getSource()
- getActionCommand()
18java.util.eventObject
- public Object getSource()
- Returns
- The object on which the Event actually occurred.
19// ButtonPanel (cont) public void
actionPerformed(ActionEvent evt) Color
color getBackground() Object source
evt.getSource() if (source button1)
color Color.red else if (source
button2) color Color.blue
setBackground(color) repaint()
20private static void createAndShowGUI()
JFrame frame new JFrame("ColorSelector")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS
E) frame.getContentPane().setLayout(new
GridLayout(0,1)) ButtonPanel toolBar new
ButtonPanel() frame.getContentPane().add(toolBa
r) frame.pack() frame.setVisible(true)
21java.awt.event.ActionEvent
- public String getActionCommand()
- Returns the command string associated with this
action. This string allows a "modal" component to
specify one of several commands, depending on its
state. For example, a single button might toggle
between "show details" and "hide details". The
source object and the event would be the same in
each case, but the command string would identify
the intended action.
22javax.swing.AbstractButton
- public void setActionCommand(String actionCommand)
- Sets the action command for this button.
23// Version 2 of the GUI (based on action
command) public class ButtonPanel extends JPanel
implements ActionListener // need to
change the constructor public ButtonPanel()
setLayout(new BoxLayout(this,
BoxLayout.X_AXIS))
setBorder(BorderFactory.createEmptyBorder(30,30,30
,30)) button1 new JButton("red")
button1.setActionCommand(redBackground)
button2 new JButton("blue")
button2.setActionCommand(blueBackground)
// the rest of the constructor stays the same
24// Version 2 need to change actionPerformed publ
ic void actionPerformed(ActionEvent evt)
Color color getBackground() String
cmd evt.getActionCommand() if
(cmd.equals(redBackground) color
Color.red else if (cmd.equals(blueBackgrou
nd) color Color.blue
setBackground(color) repaint()
25Things to remember
- event handlers can be instances of any class
- event handling code executes in a single thread
(event-dispatching thread). This ensures that
each event handler will finish executing before
the next one starts. Painting code also occurs
in the event-dispatching thread, so while the
actionPerformed() is executing, the GUI is frozen
(e.g. cant be repainted or respond to mouse
clicks) - event handlers MUST execute very quickly if only
a few lines of code, can be implemented as an
anonymous class
26Painting a GUI
- When a Swing GUI needs to (re)paint itself
- starts with the highest component works down
the containment hierarchy - Swing uses a repaint manager to repaint
lightweight components - Swing uses double-buffering by default
- a component should not be interrupted in the
middle of (re)painting itself - the repaint() method is thread-safe
27Painting is an Event
- like event-handling code, painting code executes
on the event-dispatching thread - while an event is being handled, no painting will
occur, and - if painting takes a long time, no events will be
handled during that time
28Painting a JComponent
- each JComponent is responsible for painting three
items (invoked in this order) - 1. protected void paintComponent(Graphics g)
- - this is what to override to do custom painting
- - do NOT override the paint() method
- 2. protected void paintBorder(Graphics g)
- - do NOT override or invoke this method
- 3. protected void paintChildren(Graphics g)
- - do NOT override or invoke this method
29Painting a JComponent
- in other words, the JComponent first paints
itself, then its border, then each of the
children contained in it - each component has a boolean property opaque
- - if false, then is transparent
- - if true, then the rectangular painting region
is completely filled with its background color
before it is rendered - (i.e. it obscures anything under it)
30Example Painting ButtonPanel
GUI
Containment Hierarchy
Action to perform paint the background red when
the red button is clicked or paint it blue when
the blue button is clicked
31- When the GUI for ButtonPanel is painted, here's
what happens - The top-level container, JFrame, paints itself.
- The content pane first paints its background,
which is a solid gray rectangle. It then tells
the JPanel to paint itself. In most look and
feels, the JPanel is opaque by default and the
content pane's background rectangle doesn't
actually appear in the finished GUI, being
completely obscured by the JPanel.
32- 3. Next, the JPanel it paints its border.
Finally, the panel asks its children to paint
themselves. - To paint themselves, each JButton paints its
background rectangle, if necessary, then the text
that the button contains, and then its border. If
the button has the keyboard focus, meaning that
any typing goes directly to the button for
processing, the button does some
look-and-feel-specific painting to make clear
that it has the focus.
33note that JComponent optimizes its repainting
time if none of its children overlap (since
repaint manager does not have to compute the
hidden and visible areas for each child before
rendering them). 5. When a button is clicked,
the event is handled by changing the background
color of the panel and repainting it.
34Painting a transparent component
- When repaint is invoked on a JComponent such as a
label that is both visible and non-opaque - 1. Code inherited from JComponent causes the
non-opaque component to look through its
containment hierarchy to find the closest
containing component that's completely opaque.
For example, if the transparent component is a
label in a transparent panel in a content pane,
then the label's closest opaque container is the
content pane.
352. The opaque container paints itself. 3. The
children of the opaque container are asked to
paint themselves. Eventually, the transparent
component is painted. note transparent
components are expensive to render, so it can
help performance to make a component
opaque setOpaque(true)
36Graphics Context
- protected void paintComponent(Graphics g)
- the Graphics object g encapsulates graphics
settings for drawing images text, and it
provides some simple 2D methods for painting - state current color, current font, current
painting area - methods (from Graphics2D) drawString(),
drawRect(), fillRect(), drawImage(),
37Coordinate System
You can retrieve a Swing components current
position and size through the location (Point)
and size (Dimension) properties of JComponent
38JFrame frame new JFrame(test) frame.setBounds
(20,20,200,200) frame.setVisible(true) Rectangl
e r new Rectangle() r frame.getBounds(r) Sys
tem.out.println(X r.x()) System.out.println(
Y r.y()) System.out.println(Width
r.width()) System.out.println(Height
r.height())
39System.out.println(X frame.getX()) System.ou
t.println(Y frame.getY()) System.out.println
(Width frame.getWidth()) System.out.println(
Height frame.getHeight()) Point ulPoint
new Point() ulPoint component.getLocation(ulPoi
nt)
40Specifying sizes of components
- setSize() layout manager may reset this
- setPreferredSize() suggestion to the layout
manager - setMinimumSize() smallest size for the
component when it is in a container - setMaximumSize() - similar
41/ _at_version 1.20 25 Mar 1998 _at_author Cay
Horstmann / import java.awt. import
java.awt.event. import javax.swing. class
NotHelloWorldPanel extends JPanel public
void paintComponent(Graphics g)
super.paintComponent(g) g.drawString("Not a
Hello, World program", 75, 100)
When you do custom painting, the first line in
your paintComponent SHOULD ALWAYS BE
super.paintComponent(g)
42class NotHelloWorldFrame extends JFrame public
NotHelloWorldFrame() setTitle("NotHelloWorld
") setSize(300, 200)
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
Container contentPane getContentPane()
contentPane.add(new NotHelloWorldPanel())
public class NotHelloWorld public static
void main(String args) JFrame frame
new NotHelloWorldFrame() frame.show()
43Size Placement of a JComponent
- public abstract class Toolkit
- Abstract superclass of all implementations of the
Abstract Window Toolkit (i.e. java.awt). - Methods include
- Toolkit getDefaultToolkit()
- Dimension getScreenSize()
- int getScreenResolution()
- etc.
- example CenteredFrame
44/ _at_author Cay Horstmann / public CenteredFrame
extends JFrame public CenteredFrame()
setTitle("CenteredFrame")
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
Toolkit tk Toolkit.getDefaultToolkit()
Dimension d tk.getScreenSize() int
screenHeight d.height int screenWidth
d.width // make this window 1/4th the
area of the screen setSize(screenWidth / 2,
screenHeight / 2) // center the window on
the screen setLocation(screenWidth / 4,
screenHeight / 4) // add an icon to the
window title bar Image img
tk.getImage("icon.gif") setIconImage(img)