- (Sect. 11)
What is Swing?
Swing technology is a new GUI toolkit bundled with JDK 1.2, and available as an add-on
extension library for JDK 1.1. Swing technology is part of the Java Foundation Classes
and supports a GUI toolkit that lets developers create components that have
a pluggable look-and-feel. From an architectural standpoint, the Swing
component set extends - but does not completely replace - the Abstract
Windowing Toolkit (AWT).
Swing technology has many components that can be used in place of components in the
AWT (e.g. JFrame instead of Frame, JButton instead of Button, JApplet
instead of Applet, JPanel instead of Panel). It also has many components
that don't exist in the AWT (e.g. tool tips, toolbars, and progress bars).
However Swing technology relies on the underlying AWT being there.
The Swing toolkit allows the creation of GUI's that are every bit as
sophisticated as native code toolkits like MFC -- with the Java technology
advantage
that they run on every platform. The pluggable look and feel means that
they can have the same appearance on every platform, or you can choose to
have it look like Windows on a PC, like Motif on a Unix box, etc, just as
the user chooses.
Swing technology also supports the Accessiblity API. That API allows
the adaptive software used by disabled computer users to directly query
the Java VM and extract information about the running program, the usual
purpose for this being to determine the UI components.
Then the existing adaptive software can interpret it to the user (e.g.
read the contents of a window, etc).
Swing technology doesn't use native components, and
the adaptive software taps into
native components, so the accessibility API has a real role
in bringing the two together. The beauty of the Accessibility API is
that developers need to do little work to support it, but they
do need to be made aware of it if they implement new components.
With Swing technology, native window behavior is confined to external window frames
(and their borders) and a few other things such as fonts and the buffers
used to hold window contents. The composition, layout, and drawing of
controls is now all handled by Java code. So identical code is executed to
create and manage your user interface on every platform. Swing provides a
much greater consistency of behavior across different platforms.
Swing works with JDK 1.1 if you download the swing.jar file and add it to
your path. Swing is built in to JDK 1.2, and Javasoft has just changed its
1.2 Swing package-naming strategy. It is now called javax.swing.
- (Sect. 11)
Should I use Swing technology or AWT to build my GUIs?
Use Swing technology to build your apps now instead of AWT components, wherever you
have a choice.
Swing is a GUI toolkit that is at least as good as other commercial GUI
toolkits, and better in several respects.
With Swing technology, it is easier to
build an application that is portable between Mac, Solaris, Windows 95 and
NT, than it is to use Win32 and build an application that just
runs on Windows 95 and NT.
- (Sect. 11)
Where can I find a Swing technology tutorial?
There is a tutorial at
http://java.sun.com/docs/books/tutorial/ui/swing/index.html
which is part of this tutorial:
http://java.sun.com/docs/books/tutorial/ui/TOC.html
There is also a Swing technology FAQ at
http://www.drye.com/java/faq.html
See also
http://www.codeguru.com/java/Swing/index.shtml
There is a Swing Developer Connection website with white papers and
examples at
http://www.theswingconnection.com/.
Please let this FAQ maintainer know about other good Swing tutorials
and online resources.
- (Sect. 11)
What is the Model/View/Controller paradigm?
Model/View/Controller is a design pattern
or framework originally developed by
Prof. Trygve Reenskaug at Xerox PARC in 1978/9. MVC was developed
to allow Smalltalk to conveniently support GUIs.
Model/View/Controller is used in Swing in the more complicated widgets
like JTree and JTable.
Basically, the "model" contains your data, the "view" is the graphical
representation, and the "controller" is responsible for the interaction
between the other two. As an example, think of visually editing the
Tree widget that represents a directory. The display is the view.
Selecting a file, and dragging it to the trash can will delete the
file. In order for the delete to happen, the controller must tell the
model what just happened in the view.
In practice, inter-communication between the view and the controller is
complex, so the two are bundled together in one category in Swing. The
model (data) is separate though.
There's a reasonable white paper on MVC in Swing at
http://java.sun.com:81/products/jfc/swingdoc-static/swing_arch.html
.
There is information on other OO design patterns at
http://www.parallax.co.uk/cetus/oo_patterns.html.
- (Sect. 11)
When I run the Swing technology demo on Windows 95 I get an error "Out of
environment space."
That's because you don't have enough space for your DOS environment. You
can fix this with:
-
Right click your MS-DOS Prompt icon or window and choose Properties.
-
Choose "Memory" and on "Initial Environment", choose 4096 instead of
"auto".
-
Run Swing again, you'll be OK.
- (Sect. 11)
My Swing program runs fine on one of my MS Windows machines,
yet fails to draw correctly on the other. Why is this?
Odd painting behavior on one MS Windows system, when the program works
fine on another system is usually caused by some of the following:
- Bad graphics drivers. See if an update is available for
the graphics cards on the computers showing the problem.
- True-color resolution. This is really just bad graphics drivers
again, but in this case there are no better graphics drivers
available. If the drivers are set to 32-bit
(or even 24-bit) resolution, try setting them to a lower bit
density.
- Animated cursors. Disable them.
- Bad graphics acceleration. Turn it down.
- Special mouse drivers (such as wheel-mouse drivers, or touchpad
drivers). Again, look for corrected versions of the drivers,
or if none are available, try disabling them to at least verify
that this is (or is not) the problem.
- (Sect. 11)
How can I run Swing technology-based code in a browser?
Most current browsers have to be specifically set up to run Swing applets.
Read the article at
http://java.sun.com/products/jfc/tsc/web/applets/applets.html
for information about this. The article also contains a simple Swing
example applet, so you can confirm that that's your problem.
Another approach is to use the Java plug-in, which automatically gives
Swing technology in the browser. See
http://java.sun.com/products/jfc/tsc/swingdoc-current/java_plug_in.html
- (Sect. 11)
Why is my menu showing up behind other components when I use Swing technology?
The answer relates to lightweight and heavyweight (peer-based) components.
There is a good article about it at
http://www.javasoft.com/products/jfc/swingdoc-current/mixing.html
For those who want the quick fix, and will read the article later, adding
the line:
javax.swing.JPopupMenu.setDefaultLightWeightPopupEnabled(false);
before you create any menus will probably fix it (even if you're using
menus other than JPopupMenu).
The summary answer is that a Lightweight component will not appear over a
heavyweight component by default.
- (Sect. 11)
Why is there no JCanvas? How do I get a lightweight Canvas?
Use a JPanel as a Swing replacement for Canvas.
All Swing components have a paint(Graphics) routine that you can
override, just as you would have with Canvas,
(but you probably want to override paintComponent(Graphics)
instead, see next question).
- (Sect. 11)
Why don't the borders of my Swing components look right when I
override paint(Graphics)?
Swing technology splits painting into several different routines:
- paintComponent(Graphics),
- paintBorder(Graphics),
- paintChildren(Graphics)
all of which are called from paint(Graphics).
If you override paint(), unless you remember to do it, the paintBorder()
and paintChildren() won't get done.
In most cases, what you really want to do is override
paintComponent() instead of paint().
- (Sect. 11)
Why does my JFrame go away after I choose system close on the window?
Assume that you have a Swing JFrame component, and you handle the
windowClosing event, but do nothing in the handler. You will see that the
JFrame disappears anyway.
The reason is that JFrame's have default handling of the system close
operation, separate from the windowClosing event. You have to override
that by calling:
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
on your JFrame.
- (Sect. 11)
Why can I run the Mac Look and Feel only on Mac OS?
(This answer comes from the Swing Connection, see
http://java.sun.com/products/jfc/tsc/swingdoc-current/911.html).
Sun has not determined that it has the right to deliver the Mac look
and feel on platforms other than MacOS.
If Apple were to confirm Sun's right to deliver this look and feel
on other operating systems, Sun would be delighted to remove the lock.
To date, Apple has declined to do this.
Although you cannot use the new Mac L&F on non-Macintosh platforms,
there is a way to examine the source code so developers can use it as an
example of how to create a custom L&F. The Mac L&F is distributed in
"stuffed-binhexed" format, which is standard for the Macintosh. If you
develop on a MS-Windows platform and would like to examine the source
code for the Mac L&F then you can do that by downloading and using a
program called Aladdin Expander for Windows. You can download Aladdin
Expander from this URL:
http://www.aladdinsys.com/expander/index.html
When you have downloaded Aladdin Expander, you can use it to decode the
Mac L&F file posted on the JDC.
A recent posting on comp.lang.java.gui suggested the following
user workaround:
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
class MyOwnWindowsLookAndFeel extends WindowsLookAndFeel {
public isSupportedLookAndFeel() { return true; }
}
The desire on Sun's part to avoid infringing the Windows
Look and Feel is also the reason why the JTree uses colored
circles (and soon, little circles with a short line coming out
of them) for the nodes to indicate whether they are open or not.
The Swing team could have used
the '+' and '-' as Windows does, or even the triangles that
MacOS uses, but decided against it.
- (Sect. 11)
When I set the cursor to WAIT_CURSOR why does it only change
when my cursor is over specific components?
or
How can I change the cursor to a WAIT_CURSOR over my entire
window and all of its components, preventing any user action,
while some other process is happening. (i.e. database access,
opening another window, downloading an image, sorting some
data, etc.)
In JDK 1.0.2 only the awt Frame could change its Cursor. With
the advent of JDK 1.1 the Cursor manipulation has been move
to the Component clss. Now all Components have access to the
Cursor class.
You could change your Cursor to a WAIT_CURSOR for each
Component. This could be time-consuming. You could have a
potentially large number of Components. With the advent of the
JFC Swing, there is a mechanism to change the Cursor over the
entire Window regardless of the number of components.
The Swing component JFrame has a method:
public void setGlassPane(Component glassPane)
which sets an awt Component as the 'glassPane' for the JFrame.
This Component will cover the entire JFrame's visible user
accessible (when visible), area excluding the border set by the
underlying windowing system. With the 'glassPane' Component you
can set the 'WAIT_CURSOR' over an entire JFrame, prohibiting user
input (the 'glassPane' Component gets all user input) and blocking
the user until your 'other' processing is complete.
NOTE: You must spawn a Thread to accomplish your 'other' work if
you want to see the WAIT_CURSOR while the 'other' processing is
happening.
When the 'other' work is being accomplished, the 'glassPane'
is visible with a WAIT_CURSOR and gobbling up all user input.
When the 'other' work is finished, the Thread uses your
waitCursor() method to hide your 'glassPane' until its needed
again.
- (Sect. 11)
Why does the compiler complain that the javax.swing.ProgressMonitor method
"isCancelled()" isn't found?
In American English there are two acceptable spellings: "canceled" and
"cancelled". Note that the first one has one "el" and the second two "el's".
Sun spells this "canceled" for ProgressMonitors but many of
the secondary sources of documentation spell it "cancelled". To make
matters worse, Sun spells it "cancelled" at other times, such as the method
"isCancelled()" for PrinterJob.
- (Sect. 11)
Why doesn't pressing the Enter key activate the default
button on a Swing dialog?
The default keymap for Swing text components (derived from JTextComponent)
binds the Enter key (VK_ENTER) to the ActionEvent for text fields.
This was done to be compatible with the behavior of java.awt.Textfield.
To enable use of
the Enter key to activate the default button, remove the Enter
key binding from the default text component keymap as follows:
static
{
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
Keymap map =
JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
map.removeKeyStrokeBinding(enter);
- (Sect. 11)
How do I create non-rectangular Components?
Take a look at the following example that comes with the JDK:
$JAVAHOME\demo\awt-1.1\lightweight\RoundButtons\example.html
- (Sect. 11)
How do I get my application to start up with the JFrame maximized?
Sun left maximize / minimize / deiconify methods out of the AWT,
and resisted putting them in for a long time. They finally
added setState(NORMAL) and setState (ICONIFIED) in JDK 1.2,
but there's still no explicit maximize call.
So get the screen size using Toolkit.getScreenSize(), and
then use setBounds() or setLocation() / setSize() to move and
resize the frame.
- (Sect. 11)
How do I run Swing in my browser?
You can set things up to run Swing classes and applets
in a browser without
using the plug in. You have to place the swing.jar library on the client,
and tell the browser how to find it, but it works.