Event Handling
Swing is event-driven: the user clicks, types, or resizes something, and the toolkit fires an event object. You register a listener (a Java interface implementation) and your Python method runs when the event happens. Jython makes this a one-line registration with a Python callable.
ActionListener - Buttons and Menus
from javax.swing import JFrame, JButton, JOptionPane
frame = JFrame("Events")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
def on_click(event):
JOptionPane.showMessageDialog(frame, "Button clicked!")
btn = JButton("Click me")
btn.addActionListener(on_click)
frame.add(btn)
frame.setSize(280, 100)
frame.setVisible(True)
A plain Python function works as a listener as long as it accepts the event argument - Jython adapts it to the Java interface.
Listeners as Classes
class QuitListener(java.awt.event.ActionListener):
def actionPerformed(self, e):
import sys
sys.exit(0)
# or with a lambda for a one-off:
btn2.addActionListener(lambda e: print("second button"))
Common Event Types
| Event | Interface | Fires when |
|---|---|---|
| ActionEvent | ActionListener | button clicked, menu selected, key in a text field |
| WindowEvent | WindowListener | window opened, closed, activated |
| ItemEvent | ItemListener | checkbox/combo selection changes |
| KeyEvent | KeyListener | key pressed/released (on a focusable component) |
| MouseEvents | MouseListener | click, press, release on a component |
Text Field Events
from javax.swing import JFrame, JTextField, JLabel
frame = JFrame("Echo")
field = JTextField(16)
label = JLabel("type something")
def on_key(event):
label.setText("typed: " + field.getText())
field.addKeyListener({
"keyPressed": on_key,
"keyReleased": lambda e: None,
"keyTyped": lambda e: None,
})
frame.add(field)
frame.add(label)
frame.setSize(320, 100)
frame.setVisible(True)
Jython allows passing a dict of method names to addKeyListener for the multiple methods of that interface.
Reading the Event Object
def on_key(e):
print("key code:", e.getKeyCode())
print("key char:", e.getKeyChar())
print("modifiers:", e.getModifiersEx())
Pitfalls
- Update the UI only from the EDT; if your handler is invoked elsewhere, wrap updates in SwingUtilities.invokeLater.
- Do long work in a worker thread and post the result to the EDT - the EDT must stay responsive.
- Lambdas and functions are the easiest listener style; use classes when the handler needs state.
Summary
Event handling in Jython Swing is: register a Python callable (function, lambda, or class) with addXxxListener, and implement the interface method (actionPerformed, keyPressed, ...) taking the event object. Read state from the event's getters, keep the EDT responsive by moving long work to worker threads, and prefer the dict style for multi-method listeners.