Swings and Threads - PowerPoint PPT Presentation

1 / 58
About This Presentation
Title:

Swings and Threads

Description:

Because multi-threading is very useful/relevant for GUI development ... Therefore, the call to setVisible() is in a 'red box' and is not thread-safe! ... – PowerPoint PPT presentation

Number of Views:153
Avg rating:3.0/5.0
Slides: 59
Provided by: henrica
Category:
Tags: redbox | swings | threads

less

Transcript and Presenter's Notes

Title: Swings and Threads


1
Swings and Threads
2
GUIs/Graphics in this course
  • Many of the Java programming assignments in this
    course will require the development/use of
    graphical elements
  • GUIs with buttons, pull-down lists, ...
  • Flashing/Moving drawn objects, ...
  • Why?
  • Because multi-threading is very useful/relevant
    for GUI development
  • Because a few fundamental multi-threading
    concepts are well illustrated by GUI development
  • Because youll most likely develop some
    multi-threaded GUI in your life at some point
  • Because it will be helpful to visualize program
    execution for understanding it and debugging it
  • Similar principles apply for non-Java GUIs
  • Before getting to the GUIs, lets talk about
    thread safety

3
Thread Safety
  • You may have heard the term thread-safe before
  • This term is applied to functions/methods
  • A method is thread-safe if two or more threads
    can be in it at the same time
  • Two or more threads can have an activation record
    for the method in their stack, and nothing bad
    happens
  • Threads dont step on each others toes
  • The program has correct behavior
  • If a method is not thread safe, then the
    programmer must be very careful when using
    threads
  • We will see many examples of non-thread-safe
    methods
  • We will see many ways in which to make methods
    thread-safe
  • In upcoming lectures

4
Example of Thread Unsafety
  • A common example of thread unsafety is when a
    function/method uses static variables
  • Such static variables are meant to be
    remembered from invocation to invocation of the
    method
  • For instance, to keep a counter value around
    between calls to the method
  • But if two threads call the method then the
    behavior of the method can be invalid
  • We should really have a different static variable
    for each thread, but when writing the code one
    doesnt know how many threads could be calling
    the function/method
  • This is exactly the case for the strtok()
    function...

5
Thread Unsafety Example in C
  • strtok() C library function used to isolate
    sequential tokens in a string
  • e.g., useful to extract space-separated words
    from a string that contains a sentence
  • strtok() is known to not be thread-safe!
  • You should never use it in a program in which
    multiple threads may call it at the same time
  • Fortunately, a thread-safe version is provided in
    the C library strtok_r()
  • When using a library, either standard or custom,
    its key to know which methods are thread-safe
    and which ones are not
  • When developing a library its very important to
    document properly which functions are thread-safe
    and which are not

6
java.awt
  • An soon-to-be-antiquated way to do GUIs in Java
    is to use the java.awt package directly
  • You may have used it in previous courses
  • With awt you can create windows, frames, buttons,
    pull-down menus, etc.
  • The nice thing about awt is that it is
    thread-safe!
  • Which required the awt developers to be careful
    so that awt users wouldnt have to
  • General rule the more thread-safe the more
    inefficient
  • well understand this in future lectures

7
javax.swing
  • The new, improved package for Java GUI
    development is javax.swing
  • Many advantages over awt
  • More customizable
  • More components
  • Can change look-and-feel very easily
  • A bunch of cool gadgets
  • Different design choice Swing is NOT
    thread-safe!
  • More efficient
  • Potentially more trouble to program with
  • Lets look a Swing before talking about
    multi-threading
  • This will just be an overview
  • All details in the Java docs and on-line
    tutorials
  • links on course Web site

8
GUIs with Swing
  • Swing provides many graphic components
  • Also includes Java2D
  • Graphics2D object
  • Provides fancy drawing capabilities that you
    dont have to use in this class
  • But feel free to use it to learn how it works
  • Each component starts with a capital J
  • JFrame
  • JButton
  • JLabel
  • ...
  • Some components look and feel similar to awt
    components
  • In fact Swing reuses a bunch of awt stuff, as
    well see
  • Lets look at a few examples

9
A Frame with a Clickable Button
10
A Frame with a Clickable Button
  • Things to note in the previous ode
  • The root graphical object is a JFrame
  • Everything is inside a JFrame
  • The ButtonInFrame class implements ActionListener
  • Makes it possible to react to Swing components
    being interacted with by the user
  • button.addActionListener(this)
  • The actionPerformed() method of the ButtonInFrame
    object will be called whenever the user interacts
    with the button
  • frame.pack()
  • Resizes the frame so that all its internal
    components are displayed at their preferred
    sizes
  • frame.setVisible(true)
  • By default, a frame is not visible

11
A row of four JComboBoxes
  • The JComboBox component is a pull-down list that
    allows the user to select an item
  • Lets build a GUI that displays four boxes and
    prints out to the screen the user selections

12
A row of four JComboBoxes
13
A row of four JComboBoxes
  • Things to note about the previous code
  • frame.setLayout(new FlowLayout())
  • Swing uses the same layout system as awt
  • More on this on the next slides
  • Vector...
  • Java 1.5 uses generics
  • More on this in a few slides
  • ((Integer)(boxesi.getSelectedItem)).intValue()
  • The getSelectedItem method returns an Object
  • That Object has to be cast to whatever we know it
    was, in this case in Integer
  • Then we can call intValue() to get an int

14
Layouts for GUIs
  • A JFrame can have different layouts
  • FlowLayout
  • GridLayout
  • BorderLayout
  • and several other options, with some rather fancy
  • See the on-line Java Docs

15
Nested Layouts
  • You can put multiple JPanel components in a
    JFrame
  • Each JPanel can also have a layout!

Flow Layout
16
Nested Layouts
  • You can put multiple JPanel components in a
    JFrame
  • Each JPanel can also have a layout!

Border Layout
Grid Layout
Flow Layout
17
Nested Layouts
  • You can put multiple JPanel components in a
    JFrame
  • Each JPanel can also have a layout!

Flow Layout
Border Layout
Grid Layout
Flow Layout
18
Layouts
  • Layouts have a lot of bells and whistles
  • For instance, there are several ways to control
    what happens in the case of the user resizing the
    window
  • There are several on-line examples,
    documentation, tutorials
  • Some of which are listed on the course Web site
  • In this class we wont be focusing on having
    great looking GUIs, but you may want to play with
    Swing to get it to do exactly what you want
  • Chances are youll be asked to develop Java GUIs
    with Swing in your career at some point

19
Generics
  • When Java was designed it departed from C in
    several way
  • C had thrown in a bunch of stuff, which makes
    C programming challenging
  • Java took some of the most confusing features
    out
  • No multiple inheritance
  • No generic abstract data types
  • Unfortunately, these features are useful
  • The concept of multiple inheritance was added
    back in some form with the concept of interfaces
  • The concepts of generics was finally added in
    Java 1.5

20
Example a Vector
  • Say you want to create a Vector of JFrames
  • That java.util package provides an implementation
    of the abstract Vector data type
  • A Vector is basically an array that can grow and
    shrink, with all the functions you might expect
  • add(), remove(), elementAt(), etc.
  • See the Java Docs for all details
  • Before Java 1.5, elements of a Vector object were
    simply of type Object
  • Very general makes it easy to create a Vector of
    anything
  • anything but primitive datatypes like int, char,
    etc.

21
Why Generics in Java?
  • The problem is that enforcing vector elements to
    only be of type Object prevents the detection of
    some basic errors at compile time
  • Example
  • I create a vector of Objects that I intent to use
    to store JFrame objects
  • Another developer on my team misunderstands what
    I mean and adds a bunch of JPanel objects in the
    vector
  • Everything compiles fine because everythings an
    Object
  • But at run time, I extract a vector element
    thinking its a JFrame but its a JPanel!
  • This can cause a runtime error

22
A Generic Vector
  • // A vector of JFrames
  • Vector vector
  • vector new Vector()
  • vector.add(new JPanel()) // Compilation error!
  • If you try to use a raw Vector without
    specifying the type of elements, then Java 1.5
    will complain about unchecked calls

23
How about drawing?
  • The JPanel object allows drawing
  • Similar to awts Canvas object
  • The typical usage is as follows
  • Create a class that extends JPanel
  • Override the paintComponent() method to draw
    whatever you want
  • Create an instance of your class
  • Add that instance to a JFrame
  • Lets look at an example
  • A black panel with a red disk in it

24
JPanel Example
  • MyPanel class extends JPanel

25
JPanel Example
  • A class to create the MyPanel object

26
JPanel Example
  • The fillOval(x,y,w,h) method draws a filled oval
    inside a rectangle with top-left corner at
    coordinates (x,y), with width w, and with height
    h
  • What it looks like
  • Note that the point (0,0) is in the top-left
    corner of the screen

27
A Flashing Panel
  • Lets now modify our code so that the Panels
    background flashes blue every second
  • This can be done in a naïve way by simply writing
    a loop that changes the background every second
  • Lets see how we could

28
FlashingPanelAttempt
  • This will appear to work almost always
  • But there is a problem with it, which could
    appear for more complex programs

29
How does it work in the JVM?
  • The JVM has an event dispatch thread, which does
    two things
  • Catches and dispatches swing events
  • e.g., mouse click goes to the right button
  • Execute paint operations of swing components
  • e.g., redraw something
  • Should not have too much to do lest the GUI
    isnt responsive
  • As we said before, Swing was not designed to be
    thread safe
  • Swings single-thread rule the state of
    realized swing components can only be modified
    by the event dispatch thread
  • A component is realized when
  • paint(), setVisible(true), or pack() has been
    called
  • It is part of a realized component
  • Essentially, a component is realized once it is
    visible/usable
  • The event dispatch thread is the thread that
    executes the actionPerformed() method
  • Therefore there are only a few places in the code
    where one can safely modify the state of
    components...

30
Safe Swing code
  • public class Stuff implements EventListener
  • public JFrame frame
  • public JButton button
  • public Stuff()
  • button new Button()
  • frame new Jframe()
  • frame.add(button)
  • frame.pack()
  • frame.setVisible(true)
  • ...
  • public void someMethod()
  • ...
  • public void actionPerformed(ActionEvent event)
  • ...

31
Safe Swing code
  • public class Stuff implements EventListener
  • public JFrame frame
  • public JButton button
  • public Stuff()
  • button new Button()
  • ...
  • frame new Jframe()
  • frame.add(button)
  • ...
  • frame.setVisible(true)
  • ...
  • public void someMethod()
  • ...
  • public void actionPerformed(ActionEvent event)
  • ...

32
Unsafe Swing Code
  • Lets look at what happens when one doesnt write
    safe code
  • Were going to use a contrived example that
    causes a problem almost instantly
  • In a real-world situation the problem may happen
    very rarely, which makes it extremely difficult
    to observe it and therefore to fix it!
  • We implement a JFrame that has a scrollable list
    in which a thread rapidly adds/remove elements
  • Yes, its useless
  • But it has invalid code in the red boxes in the
    previous slide

33
Example
34
Example
35
What happens?
36
Lesson
  • What we saw is a typical multi-threading bug
  • The code looks fine
  • Were not even using index into arrays but just
    use some built in class to add/remove elements to
    some data structure via its methods
  • And yet, we saw an out of bound exception
  • Therefore
  • The data structures methods are not thread-safe
  • More than one thread calls them
  • The two threads are
  • Our own WorkerThread
  • The JVMs event dispatcher thread, which we
    didnt even create!
  • We wrote code that modifies the state of a swing
    component inside one of the red boxes

37
How do we fix it?
  • Solution Ensure that only the event dispatch
    thread calls the removeElement() and the
    addElement() methods, as these methods are not
    thread-safe in the swing package
  • But how can we do this?
  • The code to remove/add elements cannot go into
    any of the green boxes of the Safe Swing code
    slide
  • Luckily, there is a mechanism to do exactly this
  • The InvokeLater() method forces some code to be
    executed by the event-dispatcher thread
  • The swing designers put it there exactly so that
    we can do what we wanted to do in our example

38
InvokeLater()
  • The class SwingUtilities contains a static method
    called invokeLater()
  • invokeLater() takes a Runnable object as
    parameter
  • That Runnable objects run method should contain
    the code that should be executed by the
    event-dispatch thread
  • The execution request is put on the
    event-dispatch threads queue, and the thread
    will get to it later (soon)
  • One more reason why nothing requiring a long
    execution time should ever be executed by the
    event-dispatch thread
  • Never put much work in the actionPerformed()
    method
  • Never give much work to do via invokeLater()
  • Example (using a compact syntax)
  • invokeLater(new Runnable()
  • void run() ...
  • )

39
How can we fix our code?
  • Create two Runnable classes

40
How can we fix our code?
  • Call invokeLater()

41
Other unsafe code
  • Lets look at our flashing panel program again
  • Turns out there are two big problems with it

42
Other unsafe code
  • Problem 1 the event-dispatch thread may miss
    the setBackground calls
  • Unlikely with the sleep(1000) in this program
  • But what if we had many threads and a shorter
    period?
  • Problem 2 the calls to setBackground() are not
    thread-safe!
  • May cause a problem with the event-dispatcher
    thread
  • Very unlikely, but if it ever happens it will be
    very hard to debug
  • Nothing worse than a user saying your code fails
    once a month for no known reason

43
Fixed Flashing Panel
44
Even Pickier Thread-Safety
  • There is a third problem with our flashing panel
    program!
  • After the call to pack(), the JFrame object is
    realized
  • Therefore, the call to setVisible() is in a red
    box and is not thread-safe!
  • It is very unlikely that there could be a problem
  • But removing all doubts is easy

45
Absolutely safe code
46
Thread-Safe Methods
  • Some of the Swing methods are thread-safe
  • As stated explicitly in the documentation
  • For these, one doesnt have to call invokeLater()
    or invokeAndWait()
  • repaint()
  • revalidate(), invalidate()
  • Use to facilitate adding components to an
    existing/displayed GUI
  • Say you have a graphical component that you want
    to update/modify in your application
  • As long as you put all updates in the
    paintComponent() method, which is called by
    repaint(), you dont need to worry about using
    invokeLater because repaint() is called by the
    event dispatch thread
  • In the end, there are many ways to not need
    invokeLater(), and many developers dont know (or
    have forgotten) that it exists
  • Which once in a blue moon leads to terrible bugs

47
Standard Way to Create a GUI
48
Background Threads
  • In many cases, one really has the following
    simple system
  • A main thread for the application execution
  • The Event Dispatch (ED) thread that deals with
    all Swing events
  • But what if clicking on some buttons can launch a
    time consuming computation?
  • Clearly you dont want the ED to do it, to avoid
    the frozen syndrome
  • Therefore, you use worker threads, often called
    background threads
  • When the button is clicked, for instance, a new
    thread is spawned to do the computation
  • This could be done in the actionPerformed()
    method of the ActionListener of the button.

49
Worker Threads in a GUI
  • In many GUI apps worker threads dont need to
    talk to each other
  • They are independent threads
  • Perhaps they can terminate each other, but thats
    it
  • At this point, we have all the tools to do all
    the above
  • We can create threads, call invokeLater(), etc.
  • Well see how to terminate threads later in the
    course
  • This is something countless developers do
  • Create a GUI
  • Create worker threads for everything under the
    sun
  • This requires quite a bit of code to be rewritten
  • Turns out, there is a very convenient class
    called SwingWorker, recently added to Java SE 6
  • Although around as a separate download for years
  • Lets talk briefly about it
  • Ill omit some details as there are great
    SwingWorker tutorials on-line
  • You can do everything in this course without it,
    but you may find it used in the real world

50
Why SwingWorker?
  • If the only reason you have threads in your GUI
    is so that it is responsive, and if these threads
    do not need to talk to each other at all, then
    SwingWorker is convenient
  • It removes the need to create threads explicitly
  • You never have Thread/Runnable objects visible to
    you
  • SwingWorker is an generic abstract class that
    must be extended
  • It has important methods
  • doInBackground() do the work without freezing
    everything
  • done() invoked when the method finishes
  • publish() used to provide intermediate results
  • process() used to deal with published
    intermediate results
  • Only the first one must absolutely be overridden
  • It also makes it possible to get some object
    returned by doInBackground()
  • which is why the class is generic

51
SwingWorker Example
  • Say you want to have a GUI in which you have a
    Load button
  • When clicked, the button counts from 1 to 100,
    sleeping .10 seconds in between numbers
  • While counting some progress bar on the GUI is
    updated
  • When done, we want to get back a String that says
    done
  • Yes, this is USELESS, but its simple and quick,
    and if you know how to do it, you can do useful
    things
  • Lets look at this in details

52
(No Transcript)
53
(No Transcript)
54
(No Transcript)
55
(No Transcript)
56
(No Transcript)
57
SwingWorker Conclusion
  • SwingWorker provides a higher abstraction above
    Threads to avoid the hassle of multi-threaded
    programming in some situations
  • There is actually a cooler way to update a
    progress bar using properties (see on-line
    material if curious)
  • There are several such higher levels of
    abstractions (will see something called
    ThreadPool for instance)
  • But in the end, if you dont know how things work
    underneath its difficult to write good
    concurrent code
  • For assignments you can use SwingWorker if you
    feel like it
  • There is a link to the .jar file and some
    documentation on the courses Web page

58
Conclusion
  • Multi-threading issues aplenty in programs that
    dont even have multiple threads!
  • One has to be very thorough and saying my code
    is thread-safe is a big claim
  • Something that may always work could break one
    day, especially on a different system
  • Some developers dont even know that calling
    setVisible() after pack() is technically a
    thread-safety problem
  • but its considered dangerous by some
  • Some developers would never do it
  • considered completely paranoid by some
  • but if youve been bitten once by a horrible
    multi-threading bug that took you 1 month to
    figure out then ...
  • For simple background tasks, SwingWorker is
    useful
  • You MUST understand what code runs in the ED
    thread
  • SwingUtilities.isEventDispatchThread() returns a
    boolean
  • Check out the on-line material and documentations
Write a Comment
User Comments (0)
About PowerShow.com