Использование библиотек Java


Jython оборачивает Java библиотеки так, что любая из них может быть использована напрямую или через наследование. Кроме того, Python стенографически упрощает кодирование.

В качестве иллюстрации рассмотрим пример HTMLButton.java из 13 главы Thinking in Java, 2nd edition (вероятно вы уже загрузили и установили исходный код этой книги с сайта www.BruceEckel.com, так как некоторые примеры этой книги используют библиотеки из этой книги). Вот версия для Jython:

## interpreter:PythonSwing.py
#
Пример HTMLButton.java из
#
"Thinking in Java, 2nd edition," Chapter 13,
# конвертированный в Jython.
# Не запускайте это как часть автоматической сборки:
#=M
@echo skipping PythonSwing.py
from javax.swing
import JFrame, JButton, JLabel
from java.awt
import FlowLayout

frame = JFrame
("HTMLButton", visible=1,
  defaultCloseOperation=JFrame.EXIT_ON_CLOSE
)


def kapow
(e):
  frame.contentPane.add
(JLabel("<html>"+
   
"<i><font size=+4>Kapow!"))
 
# Заставляем перераспределить,
  # чтобы включить новую метку:
  frame.validate
()

button = JButton("<html><b><font size=+2>" +
 
"<center>Hello!<br /><i>Press me now!",
  actionPerformed=kapow
)
frame.contentPane.layout = FlowLayout()
frame.contentPane.add(button)
frame.pack()
frame.size=200, 500
##~

Если вы сравните Java версию программы с приведенной выше реализацией на Jython, вы увидите, что Jython короче и в общем легче для понимания. Например, в Java версии для настройки фрейма вы делали несколько вызовов: конструктора JFrame( ), метода setVisible( ) и метода setDefaultCloseOperation( ), в приведенном выше примере эти три операции выполняются в единственном вызове конструктора.

Также обратите внимание, что JButton сконфигурирован с методом actionListener( ) внутри конструктора с присвоением kapow. Кроме того, осведомленность Jython'а о JavaBean означает, что вызов любого метода с именем, начинающегося с "set", может быть заменено простым присвоением, как вы видите выше.

Единственный метод, не перешедший из Java - это метод pack( ), который, кажется, является неотъемлемой частью для запуска правильного переразмещения. Также очень важно, чтобы вызов pack( ) произошел прежде установки размеров.

Наследование от библиотечных классов Java

Вы легко можете наследовать от стандартных библиотечных классов Java в Jython. Вот пример Dialogs.java из Chapter 13 Thinking in Java, 2nd edition, конвертированный в Jython:

## interpreter:PythonDialogs.py
# Dialogs.java from
"Thinking in Java, 2nd
# edition,"
Chapter 13, converted into Jython.
# :
#=M
@echo skipping PythonDialogs.py
from java.awt
import FlowLayout
from javax.swing
import JFrame, JDialog, JLabel
from javax.swing
import JButton

class MyDialog(JDialog):
  def __init__
(self, parent=None):
    JDialog.__init__
(self,title="My dialog", modal=1)
   
self.contentPane.layout = FlowLayout()
   
self.contentPane.add(JLabel("A dialog!"))
   
self.contentPane.add(JButton("OK",
      actionPerformed = lambda e, t=self: t.dispose
()))
   
self.pack()

frame = JFrame("Dialogs", visible=1,
  defaultCloseOperation=JFrame.EXIT_ON_CLOSE
)
dlg = MyDialog()
frame.contentPane.add(
 
JButton("Press here to get a Dialog Box",
    actionPerformed = lambda e: dlg.show
()))
frame.pack()
##~


MyDialog
наследуется от JDialog, и вы можете видеть поименованный аргумент, использованный в вызове конструктора базового класса.

Обратите внимание, что при создании JButton "ОК" метода actionPerformed устанавливается внутри конструктора, и что функция создается при использовании ключевого слова Python lambda. Здесь создается безымянная функция с аргументом, стоящим перед двоеточием, и выражением, которое генерирует возвращаемое значение, после двоеточия. Как вы должны знать, Java прототип для метода actionPerformed( ) содержит единственный аргумент, но выражение lambda указывает два. Однако второму аргументу предоставлено значение по умолчанию, так что функция может быть вызвана только с одним аргументом. По этой причине второй аргумент указан со значением по умолчанию, поскольку это способ передать self в lambda выражение, которое может быть использовано для уничтожения диалога.

Сравните этот код с версией, которая опубликована в Thinking in Java, 2nd edition. Вы обнаружите, что особенности языка Python позволяют сильно сжать и направить реализацию.