0
# Interface Implementation and Proxying
1
2
Create Python implementations of Java interfaces and proxy objects for bidirectional communication between Python and Java code. This module enables Python classes to implement Java interfaces and allows Java code to call back into Python.
3
4
## Capabilities
5
6
### Modern Interface Implementation
7
8
Modern approach using annotations to implement Java interfaces from Python classes.
9
10
```python { .api }
11
class JImplements:
12
"""Annotation to implement Java interfaces from Python classes.
13
14
Modern approach for creating Python implementations of Java interfaces.
15
"""
16
17
def __init__(self, *interfaces, **kwargs):
18
"""Create interface implementation annotation.
19
20
Args:
21
*interfaces: Java interface classes to implement
22
**kwargs: Additional options like deferred=True
23
"""
24
25
def JOverride(func):
26
"""Decorator to mark method as overriding Java method.
27
28
Used to explicitly mark methods that override or implement
29
Java interface methods.
30
31
Args:
32
func: Python method that overrides Java method
33
34
Returns:
35
func: The decorated method
36
"""
37
```
38
39
### Legacy Proxy System
40
41
Legacy proxy system for interface implementation (deprecated in favor of JImplements).
42
43
```python { .api }
44
class JProxy:
45
"""Create proxies for Java interfaces (legacy approach).
46
47
Note: Deprecated in favor of JImplements annotation.
48
"""
49
50
def __init__(self, interface, inst=None, loader=None, dict=None):
51
"""Create a proxy for Java interface.
52
53
Args:
54
interface: Java interface class
55
inst: Python instance implementing the interface
56
loader: Class loader (optional)
57
dict: Method dictionary (optional)
58
"""
59
```
60
61
## Usage Examples
62
63
### Implementing Java Interfaces (Modern Approach)
64
65
```python
66
import jpype
67
from jpype import JImplements, JOverride
68
69
jpype.startJVM()
70
71
# Get Java interface
72
Runnable = jpype.java.lang.Runnable
73
ActionListener = jpype.javax.swing.event.ActionListener
74
75
# Implement single interface
76
@JImplements(Runnable)
77
class MyRunnable:
78
def __init__(self, name):
79
self.name = name
80
81
@JOverride
82
def run(self):
83
print(f"Running task: {self.name}")
84
85
# Create instance and use with Java
86
task = MyRunnable("background_task")
87
thread = jpype.java.lang.Thread(task)
88
thread.start()
89
thread.join()
90
91
jpype.shutdownJVM()
92
```
93
94
### Multiple Interface Implementation
95
96
```python
97
import jpype
98
from jpype import JImplements, JOverride
99
100
jpype.startJVM()
101
102
# Import required interfaces
103
Runnable = jpype.java.lang.Runnable
104
Comparable = jpype.java.lang.Comparable
105
106
# Implement multiple interfaces
107
@JImplements(Runnable, Comparable)
108
class MultiTask:
109
def __init__(self, priority, name):
110
self.priority = priority
111
self.name = name
112
113
@JOverride
114
def run(self):
115
print(f"Executing task: {self.name} (priority: {self.priority})")
116
117
@JOverride
118
def compareTo(self, other):
119
return self.priority - other.priority
120
121
# Use with Java APIs
122
task1 = MultiTask(1, "high_priority")
123
task2 = MultiTask(2, "low_priority")
124
125
# Sort using Java Collections
126
tasks = jpype.java.util.ArrayList()
127
tasks.add(task1)
128
tasks.add(task2)
129
130
jpype.java.util.Collections.sort(tasks)
131
132
jpype.shutdownJVM()
133
```
134
135
### Event Handling with GUI
136
137
```python
138
import jpype
139
from jpype import JImplements, JOverride
140
141
jpype.startJVM()
142
143
# GUI event handling
144
ActionListener = jpype.javax.swing.event.ActionListener
145
146
@JImplements(ActionListener)
147
class ButtonClickHandler:
148
def __init__(self, button_name):
149
self.button_name = button_name
150
151
@JOverride
152
def actionPerformed(self, event):
153
print(f"Button clicked: {self.button_name}")
154
source = event.getSource()
155
print(f"Event source: {source}")
156
157
# Use with Swing components
158
JFrame = jpype.javax.swing.JFrame
159
JButton = jpype.javax.swing.JButton
160
161
frame = JFrame("Test Window")
162
button = JButton("Click Me")
163
handler = ButtonClickHandler("test_button")
164
165
button.addActionListener(handler)
166
frame.add(button)
167
frame.setSize(200, 100)
168
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
169
# frame.setVisible(True) # Uncomment for GUI display
170
171
jpype.shutdownJVM()
172
```
173
174
### Callback and Observer Patterns
175
176
```python
177
import jpype
178
from jpype import JImplements, JOverride
179
180
jpype.startJVM()
181
182
# Custom observer interface implementation
183
Observer = jpype.java.util.Observer
184
185
@JImplements(Observer)
186
class DataObserver:
187
def __init__(self, name):
188
self.name = name
189
190
@JOverride
191
def update(self, observable, arg):
192
print(f"Observer {self.name} received update: {arg}")
193
194
# Use with Observable
195
Observable = jpype.java.util.Observable
196
197
class DataModel(jpype.java.util.Observable):
198
def __init__(self):
199
super().__init__()
200
self.data = ""
201
202
def set_data(self, data):
203
self.data = data
204
self.setChanged()
205
self.notifyObservers(data)
206
207
# Set up observer pattern
208
model = DataModel()
209
observer1 = DataObserver("console_logger")
210
observer2 = DataObserver("file_logger")
211
212
model.addObserver(observer1)
213
model.addObserver(observer2)
214
215
model.set_data("New data arrived")
216
217
jpype.shutdownJVM()
218
```
219
220
### Deferred Interface Implementation
221
222
```python
223
import jpype
224
from jpype import JImplements, JOverride
225
226
jpype.startJVM()
227
228
# Deferred implementation (loaded after JVM starts)
229
@JImplements("java.lang.Runnable", deferred=True)
230
class DeferredTask:
231
def __init__(self, message):
232
self.message = message
233
234
@JOverride
235
def run(self):
236
print(f"Deferred task: {self.message}")
237
238
# Use normally
239
task = DeferredTask("delayed_initialization")
240
thread = jpype.java.lang.Thread(task)
241
thread.start()
242
thread.join()
243
244
jpype.shutdownJVM()
245
```
246
247
### Exception Handling in Interface Methods
248
249
```python
250
import jpype
251
from jpype import JImplements, JOverride
252
253
jpype.startJVM()
254
255
Callable = jpype.java.util.concurrent.Callable
256
257
@JImplements(Callable)
258
class RiskyTask:
259
def __init__(self, should_fail=False):
260
self.should_fail = should_fail
261
262
@JOverride
263
def call(self):
264
if self.should_fail:
265
# Raise Java exception from Python
266
raise jpype.java.lang.RuntimeException("Task failed!")
267
return "Task completed successfully"
268
269
# Use with ExecutorService
270
ExecutorService = jpype.java.util.concurrent.Executors.newSingleThreadExecutor()
271
272
# Successful task
273
success_task = RiskyTask(False)
274
future1 = ExecutorService.submit(success_task)
275
print(future1.get()) # "Task completed successfully"
276
277
# Failing task
278
fail_task = RiskyTask(True)
279
future2 = ExecutorService.submit(fail_task)
280
281
try:
282
result = future2.get()
283
except jpype.java.util.concurrent.ExecutionException as e:
284
print(f"Task failed with: {e.getCause()}")
285
286
ExecutorService.shutdown()
287
jpype.shutdownJVM()
288
```
289
290
### Legacy Proxy Usage (Deprecated)
291
292
```python
293
import jpype
294
295
jpype.startJVM()
296
297
# Legacy proxy approach (not recommended)
298
Runnable = jpype.java.lang.Runnable
299
300
class LegacyTask:
301
def run(self):
302
print("Legacy task running")
303
304
# Create proxy (deprecated approach)
305
task_instance = LegacyTask()
306
proxy = jpype.JProxy(Runnable, inst=task_instance)
307
308
thread = jpype.java.lang.Thread(proxy)
309
thread.start()
310
thread.join()
311
312
jpype.shutdownJVM()
313
```
314
315
### Method Name Mapping
316
317
```python
318
import jpype
319
from jpype import JImplements, JOverride
320
321
jpype.startJVM()
322
323
# Handle method name conflicts with Python keywords
324
ActionListener = jpype.javax.swing.event.ActionListener
325
326
@JImplements(ActionListener)
327
class KeywordHandler:
328
@JOverride
329
def actionPerformed(self, event):
330
# Python method name maps to Java actionPerformed
331
print("Action performed")
332
333
# Explicit method mapping for complex cases
334
Comparator = jpype.java.util.Comparator
335
336
@JImplements(Comparator)
337
class CustomComparator:
338
@JOverride
339
def compare(self, o1, o2):
340
# Compare based on string representation
341
s1 = str(o1)
342
s2 = str(o2)
343
if s1 < s2:
344
return -1
345
elif s1 > s2:
346
return 1
347
else:
348
return 0
349
350
@JOverride
351
def equals(self, other):
352
return self is other
353
354
jpype.shutdownJVM()
355
```