IMPORTANT NOTE: Please update your bookmarks to use http://www.drye.com/java/faq.html. You may need to edit your bookmark by hand.
This FAQ is regularly posted in comp.lang.java.gui and the Swing mailing list (swing@eos.dk). It is available on the web at http://www.drye.com/java/faq.html. If you have comments or questions, please send them to Stephen Drye - swingfaq@drye.com.
Many thanks to Bill Wake for doing the initial work on getting the web version of this FAQ going and maintaining the first few versions.
Recent Edit History:
[March 7, 2002]JDK 1.4 is out. Fixed link to Java Report (thanks to Otten Sicco).
[November 15, 2000] All quiet on the Swing front. Added some
non-Swing questions that I get asked frequently.
[May 11, 2000] JDK 1.3 is out, and new Look and Feels.
[March 20, 2000] Spoke too soon. Updated Drag and Drop link, added forthcoming
book, and added jGuru Swing site. Thanks to John Zukowski.
[March 15, 2000] It has been really quiet on the Swing front. Added a question
on modifying a JTable header.
[December 14, 1999] Philip Milne released the XML serialization
trial, and also made several suggestions for the JTable section. Matt Robinson
and Pavel Vorobiev's book is out. Added Linux JDK to the tools.
[September 6, 1999] Changed books section. Added question
on dynamic menus in a menu bar and updated 2.10. Thanks to Per Cederberg,
David Lamb and John Zukowski.
[September 2, 1999] Updated for JDK 1.3 beta. Added new
books. Thanks to Kathy Walrath. I apologize to the fellow who mentioned
OS/2's Netscape supporting Swing, since I lost his name.
[July 11, 1999] Added "emergency" URL and a JList/JTree
question. Also tidied up question 1.9. Thanks to Brian Sletten and Alex
Rosen.
[June 28, 1999] Updates to Swing Drag and Drop and the location
of The Java Tutorial. Thanks to Gene De Lisa and Jeff Dinkins.
[June 24, 1999] Notes from JavaOne.
[May 3, 1999] Updates to Drag and Drop, new questions and corrections.
Discontinued text version. Thanks to Christian Kaufhold, Andreas Rueckert,
Patrick Ohnewein and Georg Kraemer.
[Apr 25, 1999] FAQ assumes new stewardship. Updates for Swing
1.1.1beta2 and Java 2.
[12-1-98] Added JForge to tools list - thanks to Cameron Newhan.
Added information on Swing DataBank, internal frames, and table double-click.
[11-8-98] Posted to comp.lang.java.gui.
0.1 How do I change the icon of my JFrame?
0.2 How do I get rid of the yellow Applet warning with my JApplet?
*New* 0.3 How do I maximize/minimize a JFrame? How do I display a JFrame without a title bar?
2.1. Why do I get a run-time Error when I
add components to a JFrame/JDialog/JInternalFrame/JWindow?
2.2. Where are the scroll bars on my JList (or
JTextArea)?
2.3. How can I save space in my screens?
2.4. What's the easiest way to create a dialog?
2.5. How can I prevent a window from closing?
2.6. Can I mix Swing and AWT components?
2.7. How do I use internal frames?
2.8. How do I use an image as the background for
a JPanel?
2.9. How can I capture KeyEvents for the Tab
key?
2.10. How can I make a JComboBox textfield
empty?
2.11. Why is my JList/JTree component sized improperly
when I add/remove items from the Model?
2.12. I've added/removed menu(s) from a JMenuBar.
Why isn't the change showing?
2.13 Can I save my UI designs as XML documents?
2.14 How do I change fonts/colors/etc. in my JOptionPane?
3.1. How do I put my information in a table?
3.2. Why doesn't my JTable show the column names?
3.3. How do I add and delete rows in a JTable?
3.4. Why don't my changes in the table model show up
in the JTable view?
3.5. How do I get different colored table cells?
3.6. How do I load cells on demand?
3.7. How do I get a sorted table?
3.8. How can I get my table to scroll horizontally?
3.9. How can I make sure a certain cell is visible?
3.10. How do I hide a column in a table?
3.11. How do I detect double-click on a table cell?
3.12. How can I change the width a of column of a
JTable?
3.13. How can I remove a column from a JTable?
3.14. How can I add a column to a JTable?
3.15. How can listen for clicks on a JTable
header?
3.16. How can I display an image in a JTable
cell?
3.17. How can I convert from model indices to view
indices (when the user has reordered the columns)?
3.18. I want to change the Header of my JTable (to change
the text alignment, for example), and I can't find a way to do it!
3.19. How can I programmatically stop editing in a
JTable?
0.1 How do I change the icon of my JFrame?
Since JDK 1.2 there has been a method in Frame (JFrame's parent) to set the
icon. Its name is setIconImage().
0.2 How do I get rid of the yellow Applet warning
with my JApplet?
You have to sign your applet. See the Netscape, Internet Explorer or Sun Java Plug-in documentation for details on how to do this.
*New* 0.3 How do I maximize/minimize a JFrame? How do I display a JFrame without a title bar?
There are new methods on Frame (the AWT parent of JFrame) to do this in J2SDK 1.4. See http://java.sun.com/j2se/1.4/docs/guide/awt/AWTChanges.html#zoom and http://java.sun.com/j2se/1.4/docs/guide/awt/AWTChanges.html#undecorated for details
Swing is a standard part of Java 2 and higher. Swing 1.1.1 is the last version of Swing which will be compatible with JDK 1.1.
1.2. What is the JFC?
JFC stands for "Java Foundation Classes". This is the term for several
capabilities included in the Java 2 Platform. (Some pieces are available for
JDK 1.1.)
Websites
Mailing Lists
Available now (alphabetically by author):
Forthcoming:
1.6. Can I run Swing under a browser?
Swing is not included by default in current versions of Netscape Navigator or
Microsoft Internet Explorer. See the README or CHANGES.TXT files that come in
the Swing distribution for an explanation of how to make Swing work with the
browser. Alternatively, the Java Plugin includes Swing, and works with even
the older 3.x versions of these browsers. JDK 1.2.2 is now included on all of
those AOL coasters you get, too.
OS/2's version of Netscape uses the system's default Java implementation, so Swing works there. All versions of Mozilla (including Netscape 6.0) will behave this way in the future.
1.7. What package is Swing in?
Swing has finally settled into the javax.swing package. Swing
1.0.3 was the last version to use the old package names.
1.8. What tools support Swing and/or JFC?
The easiest place to see this approach is in JTable. You can define a TableModel object (the Model), and tell a JTable (combined View-Controller) to observe that model. When the data changes, the JTable is notified, and it updates its display. Several Views could monitor a single table; the Model notifies them of changes, and lets the Views figure out how to update the display. (A common mistake is to write code to update the TableModel but not send any notifications. This shows up as the changes not being reflected unless you do a resize or force a repaint. Notification is part of the Model's job. DefaultTableModel sends these notifications for you, so see its source code for examples of what to do)
There are other design patterns used in the Swing libraries. For example, the "Composite" pattern describes how to handle a containment hierarchy of objects; JComponent implements this pattern. "Decorator" describes how to compose functionality; using CompoundBorder to nest one border inside another uses this approach. Time spent studying design patterns will often help you better understand the design of Swing.
1.10 Swing performance
Many people complain about the performance of Swing. There are some slow
components in Swing, but for the most part Swing runs quite well if used
properly.
According to the Swing team at JavaOne, Kestrel (Java 2 SDK 1.3) will include a significant number of performance improvements, including improving Java2D's support for common Swing operations. Some of these changes have already made it into Swing 1.1.1 (as of beta 2). See http://java.sun.com/products/jfc/tsc/special_report/performance/performance.html for details.
The first performance issue to look at is how Swing is being used. Many methods in Swing are there solely to provide compatibility with the AWT components. These methods tend to be the worst culprits for poor performance, since they hide the component's model from you. Remember that most Swing components are designed to be used by manipulating their model directly. The default model for the component also tends to be a bit slow, since it has no knowledge of what your application is trying to do with the component. If you use your own custom models, you generally see a significant performance improvement.
Another trick to remember is to fill your models when they aren't associated with a component. After a model has been associated with a component, it sends Events to the component when it is being modified (for every new item added!). If you add the items to the model when it is not associated with a component, and then associate the model after it is filled the component only gets one Event, notifying it that the model has been added.
1.11 Swing and Threads
The Swing Connection (http://www.theswingconnection.com)
has a number of good articles on this topic, the most recent being "The
Last Word in Swing Threads" (http://java.sun.com/products/jfc/tsc/tech_topics/threads3/threads3.html).
A quick summary is:
myWindow.getContentPane().add(component)2.2. Where are the scroll bars on my JList (or JTextArea)?
panel.add(component)use
panel.add(new JScrollPane(component));Components that implement the Scrollable interface will interact with JScrollPane to configure the scrolling behavior. Components that don't implement Scrollable will get the default behavior supplied by JScrollPane.
2.3. How can I save space in my screens?
Look at JSplitPane, JTabbedPane, JLayeredPane, and
JScrollPane. They all provide ways to let other components share space.
2.4. What's the easiest way to create a dialog?
Use a JOptionPane. It builds in features useful in simple dialogs.
2.5. How can I prevent a window from closing?
By default, a window is hidden (but not disposed of) when it is closed. This
happens after all window listeners have executed. To prevent the window from
closing unless the program closes it, use this code:
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);2.6. Can I mix Swing and AWT components?
2.7. How do I use internal frames?
Sun has a couple of articles explaining JInternalFrame and JDesktopPane
in the Swing Connection:
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
java.awt.Color oldColor = g.getColor();
if (opaque)
{
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
}
if (theImage != null)
{
g.drawImage(theImage.getImage(), 0, 0, this);
}
g.setColor(oldColor);
}
2.9. How can I capture KeyEvents for the Tab
key? 2.10. How can I make a JComboBox textfield
empty?
Call theComboBox.setSelectedItem(null); <Per Cederberg>
2.11. Why is my JList/JTree component
sized improperly when I add/remove items from the Model?
While there could be many reasons for this behavior, one possibility is that
you have a JScrollPane in a GridBagLayout without a minimum
size set. Try setting a reasonable value and see if your problem disappears.
<Brian Sletten>
2.12. I've added/removed menu(s) from a JMenuBar.
Why isn't the change showing?
You have to call revalidate() and repaint() on the JMenuBar.
JMenuBar doesn't update itself automatically. The reason for
this is so you can add or remove multiple menus together, and then update the
menu bar once when you are done.
2.13 Can I save my UI designs as XML documents?
This should be added in JDK 1.4. There's an article about this new support on
The Swing Connection. Using XML serialization is much more compact than using
the old Object serialization, but it isn't appropriate for serializing everything.
See http://java.sun.com/products/jfc/tsc/articles/persistence/index.html
2.14 How do I change fonts/colors/etc. in my
JOptionPane?
The easiest way is to use the JOptionPane constructor where you supply the components that are used to build the JOptionPane. Since you create the components, you can do whatever you want to them before you pass them to the JOptionPane. The constructors to use are any of the ones that take Objects. See the JOptionPane JavaDoc for details on what kinds of Objects you can pass to these constructors.
3.2. Why doesn't my JTable show the column
names?
Although JTable has the column information, it only shows the column
headers when the table is put into a JScrollPane:
panel.add(new JScrollPane(myJTable))3.3. How do I add and delete rows in a JTable?
3.4. Why don't my changes in the table model show
up in the JTable view?
The model needs to notify the view of changes. The AbstractTableModel
provides methods to do this, with names like fireTableDataChanged()
and fireTableRowsInserted(). Your method would make its change, then
call the appropriate "fire" routine to notify listeners of exactly
what happened, so they can go to the model and get the current state. DefaultTableModel
does this automatically.
3.5. How do I get different colored table cells?
The look-and-feel is usually responsible for providing the appearance of the
cells. You can install a TableCellRenderer that uses the row and column
position to determine what color the cell should be.
3.6. How do I load cells on demand?
Subclass AbstractTableModel, and have your implementation of getValueAt()
check whether the cell (or row) is loaded. If so, return it; if not, load it
first and then return the value.
3.7. How do I get a sorted table?
You can provide a sorting table model as a wrapper around a base table model.
When the base table changes, the sorted table will re-sort. Operations involving
the row must be translated according to the sorted order. The Swing distribution
package comes with an example.
3.8. How can I get my table to scroll horizontally?
By default, the columns only subdivide the space available to them. Turn off
auto-resize to get horizontal scrolling.
JTable table = ... table.setAutoResizeMode (JTable.AUTO_RESIZE_OFF); JScrollPane pane = new JScrollPane(table);3.9. How can I make sure a certain cell is visible?
JTable table = ... table.scrollRectToVisible(table.getCellRect(row,column,true));3.10. How do I hide a column in a table?
JTable table = ...
TableColumn deletedColumn = table.getColumn("Column Title");
table.removeColumn(deletedColumn);
It can later be added back into the table by addColumn(). This only affects
what column is shown by the JTable; the model is unaffected.
3.11. How do I detect a double-click on a table
cell?
A JTable is a Component, so it can have a MouseListener attached.
Check the MouseEvent to see how many clicks are in the event. If it's
two, you can look at theTable.rowAtPoint(event.getPoint()) to help
find out what was clicked on.
3.12. How can I change the width a of column of
a JTable?
You need to use these two lines of code:
table.getColumnModel().getColumn(index).setPreferredWidth(<width>); table.sizeColumnsToFit(-1);The sizeColumnsToFit() call is no longer needed in JDK 1.3.
3.13. How can I remove a column from a JTable?
You have to remove it from the ColumnModel.
TableColumnModel model = table.getColumnModel(); model.removeColumn(model.getColumn(index));3.14. How can I add a column to a JTable?
3.15. How can listen for clicks on a JTable
header?
Look at the Swing examples in demo/jfc/Table/TableSorter.java.
There is a MouseListener that does exactly that.
3.16. How can I display an image in a JTable
cell?
Write a custom TableCellRenderer. A TableCellRenderer returns
a Component that is used to display a table cell. To use images, you
would probably return either a JComponent in whose paintComponent
method you paint your image, or a JLabel that has the image set as
icon.
First make getValueAt() return the Icon for that cell. Then, make getClassForColumn() return ImageIcon.class (Icon.class also works as of 1.3) in your table model. - Philip Milne
3.17. How can I convert from model indices to view
indices (when the user has reordered the columns)?
Use one of these two methods: JTable.convertColumnIndexToModel(int)
or JTable.convertColumnIndexToView(int).
3.18. I want to change the Header renderer of my
JTable (to change the text alignment, for example), and I can't find
a way to do it!
The ability to do this is hidden pretty well. The renderer for the JTable
header isn't an attribute of the JTable, it is an attribute of each
TableColumn.
First, you need to get the TableColumn you want to change the header
renderer for. To do that, you need to get the column's name Object,
which you either know from when you created the columns, or you can find it
by calling getColumnName(viewIndex)(if you only know the model index,
you need to convert it to the view index). Then you can call getColumn(name).
Finally, you can then call setHeaderRenderer() on the TableColumn.
JTableHeader had two new methods added in JDK 1.3, getDefaultRenderer() and setDefaultRenderer(TableCellRenderer) - Philip Milne
3.19. How can I programmatically stop editing in a JTable?
This method will do the job:
public boolean stopCellEditing() {
try {
int column = table.getEditingColumn();
if (column > -1) {
TableCellEditor cellEditor = table.getColumnModel().getColumn(column).getCellEditor();
if (cellEditor == null) {
cellEditor = table.getDefaultEditor(table.getColumnClass(column));
}
if (cellEditor != null) {
cellEditor.stopCellEditing();
}
}
}
catch (Exception e) {
return false;
}
return true;
}
4.2. How do I use the EditorKit for HTML?
The easiest way is to create a JEditorPane and call setContentType("text/html").
The JEditorPane will look for an EditorKit registered as supporting
that type, and will find the HTMLEditorKit by default.
4.3. How can I use the HTMLEditorKit
without using a JEditorPane?
Create an instance of HTMLEditorKit directly, and then create an empty
Document using the createDefaultDocument() method. The read()
and write() methods can then be used to load or save the document to
a stream.
4.4. Which version of HTML does the HTMLEditorKit
support?
It supports a subset of HTML 3.2. The parser in Swing 1.1.1beta2 is much
improved.
4.5. How do I use the RTFEditorKit?
The easiest way is to create a JEditorPane and call setContentType("text/rtf").
The JEditorPane will look for an EditorKit registered as supporting
that type, and will find the RTFEditorKit by default.
4.6. How can I use the RTFEditorKit without
creating a JEditorPane?
Create an instance of RTFEditorKit directly, and then create an empty
Document using the createDefaultDocument() method. The read()
and write() methods can then be used to load or save the document to
a stream.
5.2. How can I get different icons for my tree nodes?
The look-and-feel is usually responsible for providing the icons in a tree.
To draw your own icons for a node, implement and install a custom TreeCellRenderer.
5.3. How do I load nodes on demand?
Make a subclass of DefaultMutableTreeNode. Override getAllowsChildren()
and getChildCount() to load the tree beneath each node the first time
those methods are called.
5.4. Why won't my folder/directory/etc. TreeNodes
draw properly when they don't have any children?
Set allowsChildren to be true for all of your container nodes, and
askAllowsChildren to true in the TreeModel. By default,
askAllowsChildren is false, which makes the model call isLeaf()
to decide how to render a node. The isLeaf() method returns true
if the node doesn't have any children at the moment. So, by default all childless
nodes are drawn as leaves regardless of whether they could have children.
5.5. How do I expand or collapse all tree nodes?
JTree does not have a method to do this directly. You can expand the
whole tree like this:
int row = 0;
while (row < tree.getRowCount()) {
tree.expandRow(row);
row++;
}
or collapse it like this:
int row = tree.getRowCount() - 1;
while (row >= 0) {
tree.collapseRow(row);
row--;
}
5.6 How can I automatically start editing a TreeNode,
for example a new node that the user has added?
It's easy with DefaultMutableTreeNodes and a DefaultTreeModel model:
DefaultMutableTreeNode newNode = ... model.insertNodeInto(parentNode, newNode, 0); // or whatever position
TreePath path = new TreePath(newNode.getPath()); tree.expandPath(new TreePath(parent.getPath())); tree.setSelectionPath(path); tree.startEditingAtPath(path);
6.2. How do I create a custom UndoableEdit?
There are two ways to do this. The quickest way is to make your model StateEditable
and use the StateEdit class. The more efficient way is to create a
subclass of AbstractUndoableEdit to represent the changes that can
happen to the data in your model.
For components that have simple text labels, the accessibleName is by default set to the text on the component. Components such as JMenBar or JTextArea that don't have simple text labels need to have the accessibleName explicitly set.
To set the accessibleName or accessibleDescription, get the AccessibleContext for the object and use the methods it provides, as in this code fragment:
JTextArea noteArea = new JTextArea();
noteArea.getAccessibleContext().setAccessibleName("Notes");
noteArea.getAccessibleContext().setAccessibleDescription(
"The notes you want to take");
7.2. How do I make a non-Swing component accessible?
For example, if your class is a custom scrolling marquee, you would override the getAccessibleText() method to return an instance of AccessibleText. It provides methods so that assistive technologies can retrieve more detailed information about the text, for example the individual words in the text.
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex_ignored) {
// default l&f left in place
}
8.2. Can I run Windows or Mac look-and-feel on other
platforms? There is an alternative MacOS look and feel available from http://www.ing.unitn.it/~luttero/javaonMac/ that supports a more Mac-like single menu bar along the top of the screen.
8.3. How do I create a UI delegate for my custom
component?
Have your component extend from JComponent (or a descendant of JComponent).
Create a subclass of ComponentUI for your custom component, overriding
at least the createUI() and paint() methods. To enable the
new UI, override four methods of your JComponent subclass:
public class MyComponent extends JComponent {
public void updateUI() {
setUI((MyComponentUI)UIManager.getUI(this));
}
public void setUI(MyComponent newUI) {
super.setUI(newUI);
}
public MyComponentUI getUI() {
return (MyComponentUI)ui;
}
public String getUIClassID() {
return "MyComponentUI";
}
}
8.4. How do I create a new look-and-feel? 8.5 What other look and feels are available?
Drag-and-drop was featured as a "Question of the Week" at the JDC: http://developer.javasoft.com/developer/qow/archive/1/index.html.
More recent information has appeared at:
Article 1: http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html
Article 2 in upcoming august javaworld
JavaOne presentation http://industry.java.sun.com/javaone/99/event/0,1768,617,00.html
The Java DnD FAQ, http://www.rockhoppertech.com/java-drag-and-drop-faq.html
<Gene De Lisa>
10.2. Can I use drag-and-drop with a JTree?
Apparently not at this time: bug
4165577 (http://developer.javasoft.com/developer/bugParade/bugs/4165577.html)
in the JDC bug database reports problems with this combination.
John Zukowski published another article where he uses a draggable JTree:
http://java.miningco.com/library/weekly/aa011299.htm.
"I used DnD with JTree in Java 2 for myself, so it is usable.
But the JDC says bug 4165577 is still in progress.
The problem with DnD is that nearly all components which support a SelectionListener
have problems when the SelectionListener and the DragGestureRecognizer
interfere with each other (am I selecting or dragging?). This applies not only
to JTree but also JTable and JTextPane. The only
workaround I have found is to disable the SelectionListener for DnD".
<Georg Kraemer>
Feedback is welcome at swingfaq@drye.com.
The authors are:
Acknowledgements: Thanks to Marjan Bace of Manning Publications for his encouragement in developing this document. Some information in this FAQ is from Java Foundation Classes: Swing Reference.
This FAQ is irregularly posted to comp.lang.java.gui and the swing mailing list. It is also available at http://www.drye.com/swing/faq.html.