Swing Event Listeners: A Comprehensive Guide with Examples

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.

Container Event Demo

Try it:

  1. Launch the demo (requires JDK 7+).
  2. Click Add a Button—a message appears noting the addition.
  3. 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.

Document Event Demo

Try it:

  1. Launch the demo.
  2. Type in the text field or text area—each keystroke fires an event.
  3. Delete text with Backspace or select-and-delete; the entire operation fires one event.
  4. 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.

Focus Event Demo

Try it:

  1. Launch the demo.
  2. Observe the initial message: "Focus gained: JTextField" (opposite component is null).
  3. Click a label (by default not focusable).
  4. 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.
  5. Selecting from the combo box or clicking it again produces no focus events.
  6. The text area is not clickable (setRequestFocusEnabled(false)) but can still receive focus via keyboard Tab for accessibility.
  7. 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

Internal Frame Event Demo

Try it:

  1. Launch the demo.
  2. Click Show Internal Frame to open an event-generator frame.
  3. 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

Key Event Demo

Try it:

  1. Launch the demo.
  2. Type 'a': three events (pressed, typed, released) appear.
  3. Press Shift: only pressed and released, no typed.
  4. Type 'A' (Shift+A): multiple events with Shift as a modifier.
  5. Press Caps Lock then 'A': Caps Lock is not a modifier.
  6. Tab: consumed by focus subsystem unless disabled.
  7. 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

List Data Event Demo

Try it:

  1. Launch the demo.
  2. Add a ski resort name; an intervalAdded event fires.
  3. Delete contiguous items; an intervalRemoved event fires.
  4. Move items; two contentsChanged events 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)

List Selection Demo

Table Example (TableListSelectionDemo)

Table List Selection Demo

Try it:

  1. Launch either demo.
  2. 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.

Mouse Event Demo

Try it:

  1. Launch the demo.
  2. Move into the yellow area: mouse-entered events.
  3. Press and hold the left mouse button (don't move): mouse-pressed, possibyl exit/enter.
  4. Release: mouse-released, then mouse-clicked if the cursor hasn't moved.
  5. 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

Mouse Motion Event Demo

Try it:

  1. Launch the demo.
  2. Move the cursor into the yellow rectangle: mouse-moved events.
  3. 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

Mouse Wheel Event Demo

Try it:

  1. Launch the demo.
  2. Move cursor over the text area, rotate the wheel away (UP events) and toward (DOWN events).
  3. 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

  1. addPropertyChangeListener(PropertyChangeListener) – notified of all bound property changes.
  2. 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

Tree Expand Event Demo

Try it:

  1. Launch the demo.
  2. Expand a node: tree-expanded event.
  3. 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

Tree Will-Expand Demo

Try it:

  1. Launch the demo.
  2. Click the graphic next to "Potrero Hill" to expand; a confirmation dialog appears.
  3. If you press "Expand" or close the dialog, expansion proceeds.
  4. Try again and press "Cancel Expansion" – expansion is vetoed.
  5. 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)

Window Event Demo

Try it:

  1. Launch the demo; initial messages tell which window states are supported.
  2. Click another window: lost focus and deactivated.
  3. Click back: activated and gained focus.
  4. Iconify: iconified events; deactivated and lost focus also fire.
  5. Deiconify: deiconified events; reactivated.
  6. Maximize/restore (if supported).
  7. 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.

Tags: java swing event-listeners gui Tutorial

Posted on Tue, 12 May 2026 17:43:01 +0000 by fastfingertips