This guide covers how to write and use various Swing event listeners, including container, document, focus, internal frame, item, key, list data, list selection, mouse, mouse motion, mouse wheel, property change, table model, tree epxansion, tree model, tree selection, tree will-expand, undoable edit, and window listeners. Each section provides API details and practical code examples.
Container Listener
A container event is fired by a container after a component is added to or removed from it. These events are for notification only—no listener is required for successful operations.
Example
The demonstration below reacts to component additions and removals. Clicking Add a Button or Remove a Button changes the bottom panel, triggering events that display messages in the text area.

Try it:
- Launch the demo (requires JDK 7+).
- Click Add a Button—a message appears noting the addition.
- Click Remove a Button to trigger a removal event.
Event Handling Code
public class ContainerEventDemo ... implements ContainerListener ... {
// where initialization occurs:
buttonPanel = new JPanel(new GridLayout(1,1));
buttonPanel.addContainerListener(this);
public void componentAdded(ContainerEvent e) {
displayMessage(" added to ", e);
}
public void componentRemoved(ContainerEvent e) {
displayMessage(" removed from ", e);
}
void displayMessage(String action, ContainerEvent e) {
display.append(((JButton)e.getChild()).getText()
+ " was"
+ action
+ e.getContainer().getClass().getName()
+ newline);
}
}
Container Listener API
ContainerListener Interface (adapter: ContainerAdapter)
| Method | Purpose |
|---|---|
componentAdded(ContainerEvent) |
Called after a component is added to the container. |
componentRemoved(ContainerEvent) |
Called after a component is removed from the container. |
ContainerEvent Class
| Method | Purpose |
|---|---|
getChild() |
Returns the component added or removed. |
getContainer() |
Returns the container that fired the event. |
Example Project
| Example | Notes |
|---|---|
ContainerEventDemo |
Reports all container events on a single panel. |
Document Listener
Swing text components use a Document to store content. Document events fire whenever the content changes. Attach a listener to the document, not the text component. For more, see Implementing a Document Filter.
Example
This demo tracks document events on two plain text components.

Try it:
- Launch the demo.
- Type in the text field or text area—each keystroke fires an event.
- Delete text with Backspace or select-and-delete; the entire operation fires one event.
- Copy and paste triggers one event, plus an extra if text was selected before pasting.
Event Handling Code
public class DocumentEventDemo ... {
// initialization
textField.getDocument().addDocumentListener(new MyDocumentListener());
textField.getDocument().putProperty("name", "Text Field");
textArea.getDocument().addDocumentListener(new MyDocumentListener());
textArea.getDocument().putProperty("name", "Text Area");
class MyDocumentListener implements DocumentListener {
public void insertUpdate(DocumentEvent e) {
updateLog(e, "inserted into");
}
public void removeUpdate(DocumentEvent e) {
updateLog(e, "removed from");
}
public void changedUpdate(DocumentEvent e) {
// Plain text components do not fire these events
}
public void updateLog(DocumentEvent e, String action) {
Document doc = e.getDocument();
int changeLength = e.getLength();
displayArea.append(
changeLength + " character" +
((changeLength == 1) ? " " : "s ") +
action + doc.getProperty("name") + "." + newline +
" Text length = " + doc.getLength() + newline);
}
}
}
Document Listener API
DocumentListener Interface (no adapter)
| Method | Purpose |
|---|---|
changedUpdate(DocumentEvent) |
Fired when text style changes; only from StyledDocument. |
insertUpdate(DocumentEvent) |
Fired when text is inserted. |
removeUpdate(DocumentEvent) |
Fired when text is removed. |
DocumentEvent Interface
| Method | Purpose |
|---|---|
getDocument() |
Returns the document that fired the event. |
getLength() |
Length of the change. |
getOffset() |
Position of the first changed character. |
getChange() |
Returns details about changed elements. |
getType() |
Type of change: INSERT, REMOVE, or CHANGE. |
Example Projects
| Example | Notes |
|---|---|
DocumentEventDemo |
Reports events on two components using a client property to identify the source. |
TextComponentDemo |
Updates a change log; uses styled text so changedUpdate is called. Requires DocumentSizeFilter. |
Focus Listener
Focus events fire when a component gains or loses keyboard focus, whether by mouse, keyboard, or programmatically. See How to Use the Focus Subsystem for details.
Example
This demo registers listeners on several components, reporting each focus gain/loss and the opposite component.

Try it:
- Launch the demo.
- Observe the initial message: "Focus gained: JTextField" (opposite component is null).
- Click a label (by default not focusable).
- Click the combo box; focus shifts are reported. Note that when focus moves, the first component fires a loss before the second fires a gain.
- Selecting from the combo box or clicking it again produces no focus events.
- The text area is not clickable (
setRequestFocusEnabled(false)) but can still receive focus via keyboard Tab for accessibility. - Tab through components, move to another window to see temporary focus loss, etc.
Event Handling Code
public class FocusEventDemo ... implements FocusListener {
public FocusEventDemo() {
JTextField inputField = new JTextField("A TextField");
inputField.addFocusListener(this);
JLabel infoLabel = new JLabel("A Label");
infoLabel.addFocusListener(this);
// ... register for other components
}
public void focusGained(FocusEvent e) {
displayMessage("Focus gained", e);
}
public void focusLost(FocusEvent e) {
displayMessage("Focus lost", e);
}
void displayMessage(String prefix, FocusEvent e) {
display.append(prefix
+ (e.isTemporary() ? " (temporary):" : ":")
+ e.getComponent().getClass().getName()
+ "; Opposite component: "
+ (e.getOppositeComponent() != null ?
e.getOppositeComponent().getClass().getName() : "null")
+ newline);
}
}
Focus Listener API
FocusListener Interface (adapter: FocusAdapter)
| Method | Purpose |
|---|---|
focusGained(FocusEvent) |
Called after component gains focus. |
focusLost(FocusEvent) |
Called after component loses focus. |
FocusEvent API
| Method | Purpose |
|---|---|
boolean isTemporary() |
Whether the focus change is temporary. |
getComponent() |
The component that fired the event. |
getOppositeComponent() |
The other component involved in the focus change. |
Example Projects
| Example | Notes |
|---|---|
FocusEventDemo |
Reports all focus events on several components. |
TrackFocusDemo |
Custom Picture component draws a red border when it has focus. |
Internal Frame Listener
Similar to WindowListener, an internal frame listener reacts to events like opening, closing, iconifying, deiconifying, activating, and deactivating an internal frame.
Example

Try it:
- Launch the demo.
- Click Show Internal Frame to open an event-generator frame.
- Interact: activate, iconify, maximize, or close the frame; events are displayed.
Event Handling Code
public class InternalFrameEventDemo ... implements InternalFrameListener {
public void internalFrameClosing(InternalFrameEvent e) {
displayMessage("Internal frame closing", e);
}
public void internalFrameClosed(InternalFrameEvent e) {
displayMessage("Internal frame closed", e);
monitoredWindow = null;
}
// ... other methods similarly report events
void displayMessage(String prefix, InternalFrameEvent e) {
display.append(prefix + ": " + e.getSource() + newline);
}
}
Internal Frame Listener API
InternalFrameListener Interface (adapter: InternalFrameAdapter)
| Method | Purpose |
|---|---|
internalFrameOpened(InternalFrameEvent) |
Called after internal frame is first shown. |
internalFrameClosing(InternalFrameEvent) |
Called when the user requests closing. |
internalFrameClosed(InternalFrameEvent) |
Called after the frame is disposed. |
internalFrameIconified/Deiconified |
Called after iconification/deiconification. |
internalFrameActivated/Deactivated |
Called after activation/deactivation. |
Item Listener
Item events are fired by components that implement ItemSelectable, such as check boxes, check box menu items, toggle buttons, and combo boxes.
Example Code
// initialization
optionCheckbox.addItemListener(this);
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
displayLabel.setVisible(true);
} else {
displayLabel.setVisible(false);
}
}
Item Listener API
ItemListener Interface (no adapter)
| Method | Purpose |
|---|---|
itemStateChanged(ItemEvent) |
Called when item state changes. |
ItemEvent Class
| Method | Purpose |
|---|---|
getItem() |
Returns the component-specific object associated with the item. |
getItemSelectable() |
Returns the component that fired the event. |
getStateChange() |
Returns SELECTED or DESELECTED. |
Example Projects
| Example | Notes |
|---|---|
ComponentEventDemo |
Listens to a check box to control label visibility. |
CheckBoxDemo |
Four check boxes share one listener. |
MenuDemo |
Listens to check box menu items and toggle buttons. |
Key Listener
Key events indicate keyboard input. They are fired by the component with keyboard focus. For special reactions, consider key bindings (How to Use Key Bindings).
Two basic types of notifications:
- Typing a Unicode character (key-typed event)
- Pressing or releasing a key (key-pressed and key-released events)
Example

Try it:
- Launch the demo.
- Type 'a': three events (pressed, typed, released) appear.
- Press Shift: only pressed and released, no typed.
- Type 'A' (Shift+A): multiple events with Shift as a modifier.
- Press Caps Lock then 'A': Caps Lock is not a modifier.
- Tab: consumed by focus subsystem unless disabled.
- Function keys, left/right Shift, numpad keys, and Num Lock illustrate location and action key concepts.
Event Handling Code
public class KeyEventDemo ... implements KeyListener {
// initialization
typingField = new JTextField(20);
typingField.addKeyListener(this);
public void keyTyped(KeyEvent e) {
displayInfo(e, "KEY TYPED: ");
}
public void keyPressed(KeyEvent e) {
displayInfo(e, "KEY PRESSED: ");
}
public void keyReleased(KeyEvent e) {
displayInfo(e, "KEY RELEASED: ");
}
private void displayInfo(KeyEvent e, String keyStatus) {
int id = e.getID();
String keyString;
if (id == KeyEvent.KEY_TYPED) {
char c = e.getKeyChar();
keyString = "key character = '" + c + "'";
} else {
int keyCode = e.getKeyCode();
keyString = "key code = " + keyCode + " (" + KeyEvent.getKeyText(keyCode) + ")";
}
int modifiersEx = e.getModifiersEx();
String modString = "extended modifiers = " + modifiersEx;
String tmpString = KeyEvent.getModifiersExText(modifiersEx);
if (tmpString.length() > 0) {
modString += " (" + tmpString + ")";
} else {
modString += " (no extended modifiers)";
}
String actionString = "action key? " + (e.isActionKey() ? "YES" : "NO");
int location = e.getKeyLocation();
String locationString = "key location: ";
if (location == KeyEvent.KEY_LOCATION_STANDARD) locationString += "standard";
else if (location == KeyEvent.KEY_LOCATION_LEFT) locationString += "left";
else if (location == KeyEvent.KEY_LOCATION_RIGHT) locationString += "right";
else if (location == KeyEvent.KEY_LOCATION_NUMPAD) locationString += "numpad";
else locationString += "unknown";
// ... display information ...
}
}
Key Listener API
KeyListener Interface (adapter: KeyAdapter)
| Method | Purpose |
|---|---|
keyTyped(KeyEvent) |
Called after a Unicode character is typed. |
keyPressed(KeyEvent) |
Called when a key is pressed. |
keyReleased(KeyEvent) |
Called when a key is released. |
KeyEvent Class
| Method | Purpose |
|---|---|
getKeyChar() |
Unicode character for typed events. |
getKeyCode() |
Key code identifying the physical key. |
getKeyText(int) / getKeyModifiersText(int) |
Text descriptions. |
getModifiersEx() / getModifiersExText(int) |
Extended modifiers mask and description. |
isActionKey() |
True for action keys (Cut, Copy, F-keys, etc.). |
getKeyLocation() |
Location: standard, left, right, numpad, unknown. |
Example Project
| Example | Notes |
|---|---|
KeyEventDemo |
Reports key events on a text field. |
List Data Listener
List data events are fired when the contents of a mutable list change. Since the model fires them, register on the list model.
Example

Try it:
- Launch the demo.
- Add a ski resort name; an
intervalAddedevent fires. - Delete contiguous items; an
intervalRemovedevent fires. - Move items; two
contentsChangedevents occur.
Event Handling Code
private DefaultListModel<String> skiResortsModel;
// ...
skiResortsModel = new DefaultListModel<>();
skiResortsModel.addListDataListener(new MyListDataListener());
class MyListDataListener implements ListDataListener {
public void contentsChanged(ListDataEvent e) {
log.append("contentsChanged: " + e.getIndex0() + ", " + e.getIndex1() + newline);
}
public void intervalAdded(ListDataEvent e) {
log.append("intervalAdded: " + e.getIndex0() + ", " + e.getIndex1() + newline);
}
public void intervalRemoved(ListDataEvent e) {
log.append("intervalRemoved: " + e.getIndex0() + ", " + e.getIndex1() + newline);
}
}
List Data Listener API
ListDataListener Interface (no adapter)
| Method | Purpose |
|---|---|
intervalAdded(ListDataEvent) |
Called when items are added. |
intervalRemoved(ListDataEvent) |
Called when items are removed. |
contentsChanged(ListDataEvent) |
Called when item contents change. |
ListDataEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getIndex0() |
First changed index. |
getIndex1() |
Last changed index. |
getType() |
CONTENTS_CHANGED, INTERVAL_ADDED, INTERVAL_REMOVED. |
Example Project
| Example | Notes |
|---|---|
ListDataEventDemo |
Reports list data events. |
List Selection Listener
List selection events occur when the selection in a list or table changes. They fire from the ListSelectionModel. You can register on the selection model or directly on a JList.
Two demos are shown: one for a list and one for a table. Both let you change the selection mode dynamically (single, single interval, multiple interval).
List Example (ListSelectionDemo)

Table Example (TableListSelectionDemo)

Try it:
- Launch either demo.
- Select items; observe lead and anchor, use Ctrl and Shift to modify selection; events are reported.
Event Handling Code
JList itemList;
ListSelectionModel selectionModel = itemList.getSelectionModel();
selectionModel.addListSelectionListener(new SharedListSelectionHandler());
class SharedListSelectionHandler implements ListSelectionListener {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
int firstIdx = e.getFirstIndex();
int lastIdx = e.getLastIndex();
boolean adjusting = e.getValueIsAdjusting();
output.append("Event for indexes " + firstIdx + " - " + lastIdx
+ "; isAdjusting is " + adjusting
+ "; selected indexes:");
if (lsm.isSelectionEmpty()) {
output.append(" <none>");
} else {
int minIdx = lsm.getMinSelectionIndex();
int maxIdx = lsm.getMaxSelectionIndex();
for (int i = minIdx; i <= maxIdx; i++) {
if (lsm.isSelectedIndex(i)) {
output.append(" " + i);
}
}
}
output.append(newline);
}
}
List Selection Listener API
ListSelectionListener Interface (no adapter)
| Method | Purpose |
|---|---|
valueChanged(ListSelectionEvent) |
Called when selection changes. |
ListSelectionEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object (list or selection model). |
getFirstIndex() |
First index whose selection value changed. |
getLastIndex() |
Last index whose selection value changed. |
getValueIsAdjusting() |
True if the selection is still changing. |
Example Projects
| Example | Notes |
|---|---|
ListSelectionDemo |
Reports all selection events on a list; dynamic mode change. |
TableListSelectionDemo |
Same for a table. |
ListDemo |
Enables/disables buttons based on selection. |
SplitPaneDemo |
Listens on a single-selection list. |
SimpleTableSelectionDemo |
Uses two listeners on a table (column and row). |
Mouse Listener
Mouse events notify when the user interacts with a component using the mouse: entering/exiting, pressing/releasing buttons.
Example
A blank yellow area reports all mouse events.

Try it:
- Launch the demo.
- Move into the yellow area: mouse-entered events.
- Press and hold the left mouse button (don't move): mouse-pressed, possibyl exit/enter.
- Release: mouse-released, then mouse-clicked if the cursor hasn't moved.
- Drag out of the window and release: pressed, exited, released (no move notifications unless using a motion listener).
Event Handling Code
public class MouseEventDemo ... implements MouseListener {
// initialization
drawingArea.addMouseListener(this);
addMouseListener(this);
public void mousePressed(MouseEvent e) {
saySomething("Mouse pressed; # of clicks: " + e.getClickCount(), e);
}
public void mouseReleased(MouseEvent e) {
saySomething("Mouse released; # of clicks: " + e.getClickCount(), e);
}
public void mouseEntered(MouseEvent e) {
saySomething("Mouse entered", e);
}
public void mouseExited(MouseEvent e) {
saySomething("Mouse exited", e);
}
public void mouseClicked(MouseEvent e) {
saySomething("Mouse clicked (# of clicks: " + e.getClickCount() + ")", e);
}
void saySomething(String description, MouseEvent e) {
textArea.append(description + " detected on "
+ e.getComponent().getClass().getName() + "." + newline);
}
}
Mouse Listener API
MouseListener Interface (adapter: MouseAdapter or MouseInputAdapter)
| Method | Purpose |
|---|---|
mouseClicked(MouseEvent) |
Called after a click. |
mouseEntered(MouseEvent) |
Called when cursor enters component bounds. |
mouseExited(MouseEvent) |
Called when cursor exits component bounds. |
mousePressed(MouseEvent) |
Called when a mouse button is pressed over the component. |
mouseReleased(MouseEvent) |
Called when a mouse button is released. |
MouseEvent / InputEvent Classes
| Method | Purpose |
|---|---|
getClickCount() |
Number of consecutive clicks. |
getX(), getY(), getPoint() |
Position relative to component. |
getXOnScreen(), getYOnScreen(), getLocationOnScreen() |
Absolute screen position. |
getButton() |
Which button changed state. |
isPopupTrigger() |
True if the event should bring up a popup menu. |
getModifiers() / getModifiersEx() |
Modifier keys and mouse buttons mask. |
getModifiersExText(int) |
Text description of modifiers. |
getWhen() |
Timestamp of the event. |
isAltDown(), isControlDown(), etc. |
Individual modifier states. |
MouseInfo Class
| Method | Purpose |
|---|---|
getPointerInfo() |
Returns current pointer info. |
getNumberOfButtons() |
Number of mouse buttons. |
Example Projects
| Example | Notes |
|---|---|
MouseEventDemo |
Reports all mouse events on a blank panel. |
GlassPaneDemo |
Uses MouseInputAdapter on the glass pane to re-dispatch events. |
TableSortDemo |
Listens on table header for sorting. |
PopupMenuDemo |
Shows popup on mouse click. |
TrackFocusDemo |
Custom component requests focus on click. |
Mouse Motion Listener
Mouse motion events track cursor movement. Separate from button events.
Example

Try it:
- Launch the demo.
- Move the cursor into the yellow rectangle: mouse-moved events.
- Hold the button and drag: mouse-dragged events.
Event Handling Code
public class MouseMotionEventDemo ... implements MouseMotionListener {
// initialization
drawingArea.addMouseMotionListener(this);
public void mouseMoved(MouseEvent e) {
saySomething("Mouse moved", e);
}
public void mouseDragged(MouseEvent e) {
saySomething("Mouse dragged", e);
}
void saySomething(String description, MouseEvent e) {
textArea.append(description
+ " (" + e.getX() + "," + e.getY() + ")"
+ " detected on "
+ e.getComponent().getClass().getName()
+ newline);
}
}
Additional Example: Rectangle Selection
The SelectionDemo draws a rectangle as the user drags. It extends MouseInputAdapter to handle pressed, dragged, and released in one inner class.
private class MyListener extends MouseInputAdapter {
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect = new Rectangle(x, y, 0, 0);
updateDrawableRect(getWidth(), getHeight());
repaint();
}
public void mouseDragged(MouseEvent e) {
updateSize(e);
}
public void mouseReleased(MouseEvent e) {
updateSize(e);
}
void updateSize(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect.setSize(x - currentRect.x, y - currentRect.y);
updateDrawableRect(getWidth(), getHeight());
Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);
repaint(totalRepaint.x, totalRepaint.y, totalRepaint.width, totalRepaint.height);
}
}
Mouse Motion Listener API
MouseMotionListener Interface (adapter: MouseMotionAdapter or MouseAdapter)
| Method | Purpose |
|---|---|
mouseDragged(MouseEvent) |
Called when the mouse is moved with a button held. Fired by the component that received the previous press. |
mouseMoved(MouseEvent) |
Called when the mouse is moved without a button held. |
Mouse Wheel Listener
Mouse wheel events notify when the wheel rotates. Scroll panes register wheel listeners automatically for scrolling.
Example

Try it:
- Launch the demo.
- Move cursor over the text area, rotate the wheel away (UP events) and toward (DOWN events).
- Change system mouse-wheel settings to see effect on scroll type and amounts.
Event Handling Code
public class MouseWheelEventDemo ... implements MouseWheelListener {
// initialization
textArea.addMouseWheelListener(this);
public void mouseWheelMoved(MouseWheelEvent e) {
String message;
int notches = e.getWheelRotation();
if (notches < 0) {
message = "Mouse wheel moved UP " + -notches + " notch(es)" + newline;
} else {
message = "Mouse wheel moved DOWN " + notches + " notch(es)" + newline;
}
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
message += " Scroll type: WHEEL_UNIT_SCROLL" + newline;
message += " Scroll amount: " + e.getScrollAmount() + " unit increments per notch" + newline;
message += " Units to scroll: " + e.getUnitsToScroll() + " unit increments" + newline;
message += " Vertical unit increment: "
+ scrollPane.getVerticalScrollBar().getUnitIncrement(1) + " pixels" + newline;
} else {
message += " Scroll type: WHEEL_BLOCK_SCROLL" + newline;
message += " Vertical block increment: "
+ scrollPane.getVerticalScrollBar().getBlockIncrement(1) + " pixels" + newline;
}
saySomething(message, e);
}
}
Mouse Wheel Listener API
MouseWheelListener Interface (adapter: MouseAdapter)
| Method | Purpose |
|---|---|
mouseWheelMoved(MouseWheelEvent) |
Called when the wheel rotates. |
MouseWheelEvent Class
| Method | Purpose |
|---|---|
getScrollType() |
WHEEL_BLOCK_SCROLL or WHEEL_UNIT_SCROLL. |
getWheelRotation() |
Number of notches; positive = down/away, negative = up/toward. |
getScrollAmount() |
Units to scroll per notch (positive). |
getUnitsToScroll() |
Signed scroll amount for the event. |
Example Project
| Example | Notes |
|---|---|
MouseWheelEventDemo |
Reports wheel events in a text area. |
Property Change Listener
A property change event is fired when a bound property of a bean changes. All Swing components are beans.
Common scenarios:
- Detecting a new value in a formatted text field.
- Reacting to dialog button clicks or selection changes.
- Tracking the focused component via the keyboard focus manager.
Registration Methods
addPropertyChangeListener(PropertyChangeListener)– notified of all bound property changes.addPropertyChangeListener(String propertyName, PropertyChangeListener)– notified only for a specific property.
Example Code (specific property)
amountField.addPropertyChangeListener("value", new FormattedTextFieldListener());
class FormattedTextFieldListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent e) {
Object source = e.getSource();
if (source == amountField) {
amount = ((Number)amountField.getValue()).doubleValue();
}
// recompute and update UI
}
}
Property Change Listener API
PropertyChangeListener Interface (no adapter)
| Method | Purpose |
|---|---|
propertyChange(PropertyChangeEvent) |
Called when a bound property changes. |
PropertyChangeEvent Class
| Method | Purpose |
|---|---|
getNewValue() / getOldValue() |
New/old values. |
getPropertyName() |
Name of the changed property. |
setPropagationId() |
Reserved for future use. |
Example Projects
| Example | Notes |
|---|---|
FormattedTextFieldDemo |
Listens on formatted text field value. |
DialogDemo |
CustomDialog listens on option pane value and inputValue. |
FileChooserDemo2 |
Listens on directoryChanged and selectedFileChanged. |
TrackFocusDemo |
Listens on focusOwner property of KeyboardFocusManager. |
Table Model Listener
A JTable uses a TableModel to manage data. A TableModelListener detects changes in the model's data. Implement tableChanged() after calling addTableModelListener(). See Listening for Data Changes for details.
Table Model Listener API
TableModelListener Interface (no adapter)
| Method | Purpose |
|---|---|
tableChanged(TableModelEvent) |
Called when table data or structure changes. |
TableModelEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getFirstRow() |
First changed row; HEADER_ROW for header. |
getLastRow() |
Last changed row. |
getColumn() |
Changed column; ALL_COLUMNS constant. |
getType() |
INSERT, DELETE, or UPDATE. |
Tree Expansion Listener
Tree expansion listeners are called after a tree node expands or collapses.
Example

Try it:
- Launch the demo.
- Expand a node: tree-expanded event.
- Collapse a node: tree-collapsed event.
Event Handling Code
public class TreeExpandEventDemo ... {
class DemoArea ... implements TreeExpansionListener {
public DemoArea() {
tree.addTreeExpansionListener(this);
}
public void treeExpanded(TreeExpansionEvent e) {
saySomething("Tree-expanded event detected", e);
}
public void treeCollapsed(TreeExpansionEvent e) {
saySomething("Tree-collapsed event detected", e);
}
}
void saySomething(String description, TreeExpansionEvent e) {
textArea.append(description + "; path = " + e.getPath() + newline);
}
}
Tree Expansion Listener API
TreeExpansionListener Interface (no adapter)
| Method | Purpose |
|---|---|
treeCollapsed(TreeExpansionEvent) |
Called after node collapses. |
treeExpanded(TreeExpansionEvent) |
Called after node expands. |
TreeExpansionEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getPath() |
TreePath from root to the expanded/collapsed node. |
Example Projects
| Example | Notes |
|---|---|
TreeExpandEventDemo |
Displays messages on every expansion/collapse. |
TreeExpandEventDemo2 |
Adds a tree-will-expand listener. |
Tree Model Listener
Detects changes to the data displayed by a tree. Useful to detect tree node edits. (See Dynamically Changing a Tree.)
Tree Model Listener API
TreeModelListener Interface (no adapter)
| Method | Purpose |
|---|---|
treeNodesChanged(TreeModelEvent) |
One or more sibling nodes changed. |
treeNodesInserted(TreeModelEvent) |
Nodes were inserted. |
treeNodesRemoved(TreeModelEvent) |
Nodes were removed. |
treeStructureChanged(TreeModelEvent) |
Major structure change from a given node. |
TreeModelEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getChildIndices() |
Indexes of changed/inserted/removed children. |
getChildren() |
Child objects. |
getPath() |
TreePath to the parent. |
getTreePath() |
Same as getPath() as a TreePath. |
Example Project
| Example | Notes |
|---|---|
DynamicTreeDemo |
DynamicTree implements tree model listener to detect user edits. |
Tree Selection Listener
Detects when a user selects nodes in a tree. Register a TreeSelectionListener.
Example
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
if (node == null) return;
Object nodeInfo = node.getUserObject();
// react to node selection
}
});
Set single selection: tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
Modes: DISCONTIGUOUS_TREE_SELECTION, SINGLE_TREE_SELECTION, CONTIGUOUS_TREE_SELECTION.
Tree Selection Listener API
TreeSelectionListener Interface (no adapter)
| Method | Purpose |
|---|---|
valueChanged(TreeSelectionEvent) |
Called when selection changes. |
TreeSelectionEvent API
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getNewLeadSelectionPath() |
Current lead path. |
getOldLeadSelectionPath() |
Previous lead path. |
getPath() |
First path element. |
getPaths() |
Added/removed paths. |
isAddedPath(), isAddedPath(int), isAddedPath(TreePath) |
Whether a path was added. |
getLastSelectedPathComponent() |
Last component in the first node of the selection. |
getLeadSelectionPath() (in JTree) |
Current lead path. |
Example Project
| Example | Notes |
|---|---|
TreeDemo |
Reacts to node clicks by showing an HTML document. |
Tree Will-Expand Listener
A tree-will-expand listener vetoes expansion or collapse before it happens. Use a tree expansion listener for post-event notification.
Example

Try it:
- Launch the demo.
- Click the graphic next to "Potrero Hill" to expand; a confirmation dialog appears.
- If you press "Expand" or close the dialog, expansion proceeds.
- Try again and press "Cancel Expansion" – expansion is vetoed.
- Collapsing "Potrero Hill" proceeds without a dialog.
Event Handling Code
public class TreeExpandEventDemo2 ... {
class DemoArea ... implements TreeWillExpandListener {
public DemoArea() {
tree.addTreeWillExpandListener(this);
}
public void treeWillExpand(TreeExpansionEvent e) throws ExpandVetoException {
saySomething("Tree-will-expand event detected", e);
// show dialog...
if (/* user chose to cancel */) {
saySomething("Tree expansion cancelled", e);
throw new ExpandVetoException(e);
}
}
public void treeWillCollapse(TreeExpansionEvent e) {
saySomething("Tree-will-collapse event detected", e);
}
}
}
Tree Will-Expand Listener API
TreeWillExpandListener Interface (no adapter)
| Method | Purpose |
|---|---|
treeWillCollapse(TreeExpansionEvent) |
Called before collapse; throw ExpandVetoException to veto. |
treeWillExpand(TreeExpansionEvent) |
Called before expand; throw ExpandVetoException to veto. |
Undoable Edit Listener
Undoable edit events occur on text components when an undoable operation happens: insert, delete, style change. Helps implement Undo/Redo.
Event Handling Code
// initialization
document.addUndoableEditListener(new MyUndoableEditListener());
protected class MyUndoableEditListener implements UndoableEditListener {
public void undoableEditHappened(UndoableEditEvent e) {
undoManager.addEdit(e.getEdit());
undoAction.updateState();
redoAction.updateState();
}
}
Undoable Edit Listener API
UndoableEditListener Interface (no adapter)
| Method | Purpose |
|---|---|
undoableEditHappened(UndoableEditEvent) |
Called when an undoable event occurs. |
UndoableEditEvent Class
| Method | Purpose |
|---|---|
getSource() |
Firing object. |
getEdit() |
Returns the UndoableEdit representing the edit. |
Example Project
| Example | Notes |
|---|---|
TextComponentDemo |
Implements undo/redo with an undoable edit listener. |
Window Listener
Implement WindowListener, WindowFocusListener, and WindowStateListener to handle WindowEvent objects. All methods are in WindowAdapter.
Window events fire after a window opens, closes, is iconified/deiconified, activated/deactivated, gains/loses focus, or changes state (maximized, etc.).
Common uses: save data before closing, stop animations when minimized.
Example (WindowEventDemo)

Try it:
- Launch the demo; initial messages tell which window states are supported.
- Click another window: lost focus and deactivated.
- Click back: activated and gained focus.
- Iconify: iconified events; deactivated and lost focus also fire.
- Deiconify: deiconified events; reactivated.
- Maximize/restore (if supported).
- Close: a closing message appears for 2 seconds, then the window disposes.
Event Handling Code
public class WindowEventDemo extends JFrame implements WindowListener,
WindowFocusListener,
WindowStateListener {
static WindowEventDemo frame = new WindowEventDemo("WindowEventDemo");
JTextArea display;
private void addComponentsToPane() {
display = new JTextArea();
display.setEditable(false);
JScrollPane scrollPane = new JScrollPane(display);
scrollPane.setPreferredSize(new Dimension(500, 450));
getContentPane().add(scrollPane, BorderLayout.CENTER);
addWindowListener(this);
addWindowFocusListener(this);
addWindowStateListener(this);
checkWM();
}
public void checkWM() {
Toolkit tk = frame.getToolkit();
if (!tk.isFrameStateSupported(Frame.ICONIFIED))
displayMessage("Your window manager doesn't support ICONIFIED.");
else displayMessage("Your window manager supports ICONIFIED.");
// ... similar for MAXIMIZED_VERT, MAXIMIZED_HORIZ, MAXIMIZED_BOTH
}
public void windowClosing(WindowEvent e) {
displayMessage("WindowListener method called: windowClosing.");
ActionListener task = e2 -> {
if (frame.isDisplayable()) frame.dispose();
};
Timer timer = new Timer(500, task);
timer.setInitialDelay(2000);
timer.setRepeats(false);
timer.start();
}
public void windowClosed(WindowEvent e) { displayMessage("windowClosed."); }
public void windowOpened(WindowEvent e) { displayMessage("windowOpened."); }
public void windowIconified(WindowEvent e) { displayMessage("windowIconified."); }
public void windowDeiconified(WindowEvent e) { displayMessage("windowDeiconified."); }
public void windowActivated(WindowEvent e) { displayMessage("windowActivated."); }
public void windowDeactivated(WindowEvent e) { displayMessage("windowDeactivated."); }
public void windowGainedFocus(WindowEvent e) { displayMessage("windowGainedFocus."); }
public void windowLostFocus(WindowEvent e) { displayMessage("windowLostFocus."); }
public void windowStateChanged(WindowEvent e) {
displayStateMessage("windowStateChanged.", e);
}
void displayMessage(String msg) {
display.append(msg + newline);
System.out.println(msg);
}
void displayStateMessage(String prefix, WindowEvent e) {
int state = e.getNewState();
int oldState = e.getOldState();
String msg = prefix + "\n" + "New state: " + convertStateToString(state)
+ "\n" + "Old state: " + convertStateToString(oldState);
displayMessage(msg);
}
String convertStateToString(int state) {
if (state == Frame.NORMAL) return "NORMAL";
String strState = " ";
if ((state & Frame.ICONIFIED) != 0) strState += "ICONIFIED";
if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) strState += "MAXIMIZED_BOTH";
else {
if ((state & Frame.MAXIMIZED_VERT) != 0) strState += "MAXIMIZED_VERT";
if ((state & Frame.MAXIMIZED_HORIZ) != 0) strState += "MAXIMIZED_HORIZ";
}
return strState.trim();
}
}
Window Listener API
WindowListener Interface
| Method | Purpose |
|---|---|
windowOpened(WindowEvent) |
After window is first shown. |
windowClosing(WindowEvent) |
When user requests closing. |
windowClosed(WindowEvent) |
After window is closed. |
windowIconified / windowDeiconified |
After iconify/deiconify. |
windowActivated / windowDeactivated |
After activation/deactivation (frames/dialogs only). |
WindowFocusListener Interface
| Method | Purpose |
|---|---|
windowGainedFocus / windowLostFocus |
After the window gains/loses focus. |
WindowStateListener Interface
| Method | Purpose |
|---|---|
windowStateChanged(WindowEvent) |
After state changes via iconification, maximization, etc. |
WindowEvent Class
| Method | Purpose |
|---|---|
getWindow() |
The window that fired the event. |
getOppositeWindow() |
The other window involved in focus/activation change. |
getOldState() / getNewState() |
Previous/new state as bitmask. |
Example Projects
| Example | Notes |
|---|---|
WindowEventDemo |
Reports all window events. |
SliderDemo |
Stops animation when window is minimized. |
InternalFrameEventDemo |
Similar for internal frames. |
DialogDemo |
Uses setDefaultCloseOperation instead of a window listener. |
Frame |
A demo that creates and destroys multiple windows. |