Jython - 快速指南
Jython - Overview
Jython是Python编程语言的JVM实现。 它旨在在Java平台上运行。 Jython程序可以导入和使用任何Java类。 就像Java一样,Jython程序编译为bytecode 。 其中一个主要优点是用Python设计的用户界面可以使用AWT , Swing或SWT Package GUI元素。
Jython以JPython开头,后来被重命名,紧跟着Guido Van Rossum创建的标准Python实现CPython 。 Jython由Jim Hugunin于1997年创立。 Jython 2.0于1999年发布。从那时起,Jython 2.x版本对应于等效的CPython版本。 2015年5月发布的Jython 2.7.0对应于CPython 2.7。 Jython 3.x的开发正在进行中。
Python和Java之间的区别
以下是Python和Java之间的区别 -
Python是一种动态类型语言。 因此,不需要变量的类型声明。 另一方面,Java是一种静态类型语言,这意味着变量的类型声明是强制性的,不能更改。
Python只有未经检查的异常,而Java同时检查和取消选中异常。
Python使用缩进进行作用域,而Java使用匹配的大括号。
由于Python是一种基于解释器的语言,因此它没有单独的编译步骤。 但是,Java程序需要编译为字节码,然后由JVM执行。
Python支持多重继承,但在Java中,多重继承是不可能的。 然而,它具有接口的实现。
与Java相比,Python具有更丰富的内置数据结构(列表,dicts,元组,一切都是对象)。
Python和Jython之间的区别
以下是Python和Jython之间的区别 -
Python的参考实现,称为CPython,是用C语言编写的。 另一方面,Jython完全用Java编写,是一个JVM实现。
标准Python可在多个平台上使用。 Jython适用于安装了JVM的任何平台。
标准Python代码编译为.pyc文件,而Jython程序编译为.class文件。
Python扩展可以用C语言编写。 Jython的扩展是用Java编写的。
Jython本质上是真正的多线程。 然而,Python使用Global Interpreter Lock (GIL)机制来实现此目的。
两种实现都有不同的垃圾收集机制。
在下一章中,我们将学习如何在Jython中导入Java库。
Jython - Installation
在安装Jython 2.7之前,请确保系统已安装JDK 7或更高版本。 Jython以可执行jar文件的形式提供。 从http://www.jython.org/downloads.html下载并双击其图标或运行以下命令 -
java -jar jython_installer-2.7.0.jar
将开始安装向导,必须提供安装选项。 这是系统的安装程序。
向导的第一步要求您选择语言。
第二步提示您接受许可协议。
在下一步中,选择安装类型。 建议选择标准安装。
下一个屏幕会询问您对选项的确认,然后继续完成安装。
安装过程可能需要一些时间才能完成。
安装完成后,从目标目录中的bin目录调用jython.exe 。 假设Jython安装在C:\jython27 ,请C:\jython27执行以下操作。
C:\jython27\bin\jython
将出现一个Python提示符(>>>),在其前面可以执行任何Python语句或Python脚本。
Jython - Importing Java Libraries
Jython最重要的特性之一是它能够在Python程序中导入Java类。 我们可以在Jython中导入任何java包或类,就像在Java程序中一样。 以下示例显示如何在Python(Jython)脚本中导入java.util包以声明Date类的对象。
from java.util import Date
d = Date()
print d
从命令行保存并运行上面的代码作为UtilDate.py 。 将显示当前日期和时间的实例。
C:\jython27\bin>jython UtilDate.py
Sun Jul 09 00:05:43 IST 2017
Java库中的以下包经常在Jython程序中导入,主要是因为标准Python库没有它们的等价物或者不那么好。
- Servlets
- JMS
- J2EE
- Javadoc
- Swing被认为优于其他GUI工具包
可以在Jython脚本中导入任何Java包。 这里,以下java程序在名为foo的包中存储和编译。
package foo;
public class HelloWorld {
public void hello() {
System.out.println("Hello World!");
}
public void hello(String name) {
System.out.printf("Hello %s!", name);
}
}
此HelloWorld.class在以下Jython脚本中导入。 可以从Jython脚本importex.py调用importex.py 。
from foo import HelloWorld
h = HelloWorld()
h.hello()
h.hello("IoWiki")
从命令行保存并执行上面的脚本以获得以下输出。
C:\jython27\bin>jython importex.py
Hello World!
Hello IoWiki!
Jython - Variables and Data Types
变量是计算机内存中的命名位置。 每个变量都可以包含一个数据。 与Java不同,Python是一种动态类型语言。 因此在使用Jython时也是如此; 事先声明数据类型的变量没有完成。 数据决定变量的类型,而不是决定哪些数据可以存储在其中的变量类型。
在以下示例中,为变量分配了一个整数值。 使用type()内置函数,我们可以验证变量的类型是否为整数。 但是,如果为同一个变量分配了一个字符串,那么type()函数将string作为同一个变量的类型。
> x = 10
>>> type(x)
<class 'int'>
>>> x = "hello"
>>> type(x)
<class 'str'>
这解释了为什么Python被称为动态类型语言。
以下Python内置数据类型也可以在Jython中使用 -
- Number
- String
- List
- Tuple
- Dictionary
Python将数字数据识别为数字,可以是整数,带浮点的实数或复数。 String,List和Tuple数据类型称为序列。
Jython数字
在Python中,任何带符号的整数都被称为'int'类型。 为了表示一个长整数,附加字母'L'。 将整数部分与小数部分分开的小数点数字称为“浮点数”。 小数部分可以包含使用'E'或'e'以科学记数法表示的指数。
复数也在Python中定义为数值数据类型。 复数包含实部(浮点数)和附加有'j'的虚部。
为了表示八进制或十六进制表示中的数字,将0O或0X作为前缀。 以下代码块给出了Python中不同数字表示的示例。
int -> 10, 100, -786, 80
long -> 51924361L, -0112L, 47329487234L
float -> 15.2, -21.9, 32.3+e18, -3.25E+101
complex -> 3.14j, 45.j, 3e+26J, 9.322e-36j
Jython Strings
字符串是用单个(例如“hello”),double(例如“hello”)或三个(例如“hello”“o”“”hello“”“)引号括起来的任何字符序列。 如果字符串的内容跨越多行,则三引号特别有用。
Escape序列字符可以逐字包含在三引号字符串中。 以下示例显示了在Python中声明字符串的不同方法。
str = ’hello how are you?’
str = ”Hello how are you?”
str = """this is a long string that is made up of several lines and non-printable
characters such as TAB ( \t ) and they will show up that way when displayed. NEWLINEs
within the string, whether explicitly given like this within the brackets [ \n ], or just
a NEWLINE within the variable assignment will also show up.
"""
打印时的第三个字符串将给出以下输出。
this is a long string that is made up of
several lines and non-printable characters such as
TAB ( ) and they will show up that way when displayed.
NEWLINEs within the string, whether explicitly given like
this within the brackets [
], or just a NEWLINE within
the variable assignment will also show up.
Jython列表
List是序列数据类型。 它是逗号分隔项的集合,不一定是同一类型,存储在方括号中。 可以使用基于零的索引访问List中的单个项目。
以下代码块总结了Python中List的用法。
list1 = ['physics', 'chemistry', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
print "list1[0]: ", list1[0]
print "list2[1:5]: ", list2[1:5]
下表描述了一些与Jython列表相关的最常见的Jython表达式。
Jython表达 | 描述 |
---|---|
len(List) | Length |
List[2]=10 | Updation |
Del List [1] | Deletion |
List.append(20) | Append |
List.insert(1,15) | Insertion |
List.sort() | Sorting |
Jython Tuples
元组是存储在括号中的逗号分隔数据项的不可变集合。 无法删除或修改元组中的元素,也无法将元素添加到元组集合中。 以下代码块显示了Tuple操作。
tup1 = ('physics','chemistry‘,1997,2000);
tup2 = (1, 2, 3, 4, 5, 6, 7 );
print "tup1[0]: ", tup1[0]
print "tup2[1:5]: ", tup2[1:5]
Jython字典
Jython Dictionary类似于Java Collection框架中的Map类。 它是键值对的集合。 用逗号分隔的对用大括号括起来。 Dictionary对象不遵循从零开始的索引来检索其中的元素,因为它们是通过散列技术存储的。
相同的键在字典对象中不能出现多次。 但是,多个键可以具有相同的关联值。 Dictionary对象提供的不同功能如下所述 -
dict = {'011':'New Delhi','022':'Mumbai','033':'Kolkata'}
print "dict[‘011’]: ",dict['011']
print "dict['Age']: ", dict['Age']
下表描述了一些与Dictionary相关的最常见的Jython表达式。
Jython表达 | 描述 |
---|---|
dict.get(‘011’) | Search |
len(dict) | Length |
dict ['044'] ='钦奈' | Append |
del dict ['022'] | Delete |
dict.keys() | list of keys |
dict.values() | List of values |
dict.clear() | 删除所有元素 |
Jython - Using Java Collection Types
除了Python的内置数据类型之外,Jython还可以通过导入java.util package来使用Java集合类。 以下代码描述了下面给出的类 -
- 带有add()的Java ArrayList对象
- remove()
- ArrayList类的get()和set()方法。
import java.util.ArrayList as ArrayList
arr = ArrayList()
arr.add(10)
arr.add(20)
print "ArrayList:",arr
arr.remove(10) #remove 10 from arraylist
arr.add(0,5) #add 5 at 0th index
print "ArrayList:",arr
print "element at index 1:",arr.get(1) #retrieve item at index 1
arr.set(0,100) #set item at 0th index to 100
print "ArrayList:",arr
上面的Jython脚本产生以下输出 -
C:\jython27\bin>jython arrlist.py
ArrayList: [10, 20]
ArrayList: [5, 20]
element at index 1: 20
ArrayList: [100, 20]
Jarray类
Jython还实现了Jarray Object ,它允许在Python中构建Java数组。 为了使用jarray,只需在Jython中定义一个序列类型,并将其与序列中包含的对象类型一起传递给jarrayobject。 jarray中的所有值必须是相同的类型。
下表显示了与jarray一起使用的字符类型代码。
角色类型代码 | 对应的Java类型 |
---|---|
Z | Boolean |
C | char |
B | byte |
H | short |
I | int |
L | long |
F | float |
D | double |
以下示例显示了jarray的构造。
my_seq = (1,2,3,4,5)
from jarray import array
arr1 = array(my_seq,'i')
print arr1
myStr = "Hello Jython"
arr2 = array(myStr,'c')
print arr2
这里my_seq被定义为整数元组。 它被转换为Jarray arr1。 第二个例子显示Jarray arr2是从mySttr string序列构造的。 上面脚本jarray.py的输出如下 -
array('i', [1, 2, 3, 4, 5])
array('c', 'Hello Jython')
Jython - Decision Control
决策结构具有一个或多个要由程序评估或测试的条件,以及要执行的一个或多个语句,如果条件被确定为真,并且可选地,如果条件被执行则可以执行其他语句被认定是假的。
下图显示了大多数编程语言中的典型决策结构的一般形式 -
当条件为真或假时,Jython不使用花括号来指示要执行的语句块(如Java中的情况)。 相反,使用统一缩进(左边距的空白区域)来形成语句块。 当“if”语句中给出的条件为真时,这种统一缩进的块使得条件代码被执行。
在可选的“else”语句之后可能存在类似的块。 Jython还提供了elif statement ,可以使用它来测试连续的条件。 这里, else clause将出现在最后,只有当所有前面的条件都失败时才会执行。 使用if..elif..else的一般语法如下。
if expression1:
statement(s)
elif expression2:
statement(s)
elif expression3:
statement(s)
else:
statement(s)
在以下示例中,如果..elif ..else构造用于计算用户输入的金额的不同值的折扣。
discount = 0
amount = input("enter Amount")
if amount>1000:
discount = amount*0.10
elif amount>500:
discount = amount*0.05
else:
discount = 0
print 'Discount = ',discount
print 'Net amount = ',amount-discount
上述代码的输出如下所示。
enter Amount1500
Discount = 150.0
Net amount = 1350.0
enter Amount600
Discount = 30.0
Net amount = 570.0
enter Amount200
Discount = 0
Net amount = 200
Jython - Loops
通常,程序中的语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。 可能存在需要多次执行代码块的情况。 提供此类重复功能的looping statements称为looping statements 。
在Jython中,循环可以由两个语句组成,它们是 -
while声明和
The for statement
WHILE循环
Jython中的while循环语句与Java中的类似。 只要给定条件为真,它就会重复执行一个语句块。 以下流程图描述了while循环的行为。
下面给出了while语句的一般语法。
while expression:
statement(s)
以下Jython代码使用while循环重复递增和打印变量的值,直到它小于零。
count = 0
while count<10:
count = count+1
print "count = ",count
print "Good Bye!"
Output - 输出如下。
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
Good Bye!
FOR循环
Jython中的FOR循环不是Java中的计数循环。 相反,它具有遍历序列数据类型(如字符串,列表或元组)中的元素的能力。 Jython中FOR语句的一般语法如下所示 -
for iterating_var in sequence:
statements(s)
我们可以使用FOR语句显示字符串中的每个字符,以及List或Tuple中的每个项目,如下所示 -
#each letter in string
for letter in 'Python':
print 'Current Letter :', letter
Output - 输出如下。
Current Letter : P
Current Letter : y
Current Letter : t
Current Letter : h
Current Letter : o
Current Letter : n
让我们考虑另一个实例如下。
#each item in list
libs = [‘PyQt’, 'WxPython', 'Tkinter']
for lib in libs: # Second Example
print 'Current library :', lib
Output - 输出如下。
Current library : PyQt
Current library : WxPython
Current library : Tkinter
这是另一个要考虑的实例。
#each item in tuple
libs = (‘PyQt’, 'WxPython', 'Tkinter')
for lib in libs: # Second Example
print 'Current library :', lib
Output - 上述程序的输出如下。
Current library : PyQt
Current library : WxPython
Current library : Tkinter
在Jython中, for语句还用于迭代range()函数生成的数字列表。 range()函数采用以下形式 -
range[([start],stop,[step])
默认情况下,start和step参数为0和1。 生成的最后一个数字是停止步骤。 FOR语句遍历range() function形成的列表。 例如 -
for num in range(5):
print num
它产生以下输出 -
0
1
2
3
4
Jython - 函数
复杂的编程逻辑被分解为一个或多个独立且可重用的语句块,称为函数。 Python的标准库包含大量内置函数。 也可以使用def关键字定义自己的函数。 用户定义的函数名称后跟一个形成其主体的语句块,该语句以return语句结束。
一旦定义,就可以从任何环境中多次调用它。 让我们考虑以下代码来说明问题。
#definition of function
defSayHello():
"optional documentation string"
print "Hello World"
return
#calling the function
SayHello()
可以将函数设计为从调用环境接收一个或多个参数/参数。 在调用这样的参数化函数时,需要提供与函数定义中使用的类似数据类型相同数量的参数,否则Jython解释器会抛出TypeError异常。
例子 (Example)
#defining function with two arguments
def area(l,b):
area = l*b
print "area = ",area
return
#calling function
length = 10
breadth = 20
#with two arguments. This is OK
area(length, breadth)
#only one argument provided. This will throw TypeError
area(length)
output如下 -
area = 200
Traceback (most recent call last):
File "area.py", line 11, in <module>
area(length)
TypeError: area() takes exactly 2 arguments (1 given)
执行其中定义的步骤后,被调用的函数返回到调用环境。 如果在函数定义内的return关键字前面提到了一个表达式,它可以返回数据。
#defining function
def area(l,b):
area = l*b
print "area = ",area
return area
#calling function
length = 10
breadth = 20
#calling function and obtaining its reurned value
result = area(length, breadth)
print "value returned by function : ", result
如果从Jython提示符执行上述脚本,则获得以下输出。
area = 200
value returned by function : 200
Jython - Modules
模块是Jython脚本,其中定义了一个或多个相关的函数,类或变量。 这允许Jython代码的逻辑组织。 通过从模块或特定元素(函数/类)导入模块或模块中定义的程序元素,可以在另一个Jython脚本中使用它。
在下面的代码(hello.py SayHello()中定义了一个函数SayHello() 。
#definition of function
defSayHello(str):
print "Hello ", str
return
要从另一个脚本使用SayHello()函数,请在其中导入hello.py module 。
import hello
hello.SayHello("IoWiki")
但是,这将导入模块中定义的所有函数。 为了从模块导入特定功能,请使用以下语法。
from modname import name1[, name2[,... nameN]
例如,要仅导入SayHello()函数,请按如下所示更改上述脚本。
from hello import SayHello
SayHello("IoWiki")
在调用函数时,无需为模块的名称添加前缀。
Jython - Package
包含一个或多个Jython模块的任何文件夹都被识别为包。 但是,它必须有一个名为__init__.py的特殊文件,它提供要使用的函数的索引。
现在让我们了解一下,如何创建和导入包。
Step 1 - 创建一个名为package1的文件夹,然后在其中创建并保存以下g模块。
#fact.py
def factorial(n):
f = 1
for x in range(1,n+1):
f = f*x
return f
#sum.py
def add(x,y):
s = x+y
return s
#mult.py
def multiply(x,y):
s = x*y
return s
Step 2 - 在package1文件夹中,使用以下内容创建并保存__init__.py文件。
#__init__.py
from fact import factorial
from sum import add
from mult import multiply
Step 3 - 在package1文件夹外创建以下Jython脚本test.py
# Import your Package.
import package1
f = package1.factorial(5)
print "factorial = ",f
s = package1.add(10,20)
print "addition = ",s
m = package1.multiply(10,20)
print "multiplication = ",m
Step 4 - 从Jython提示符执行test.py. 将获得以下输出。
factorial = 120
addition = 30
multiplication = 200
Jython - Java Application
下载jython-standalone-2.7.0.jar - 用于在其官方下载页面中嵌入Jython的Java应用程序: http://www.jython.org/downloads.html : jython-standalone-2.7.0.jar并将此jar文件包含在Java CLASSPATH环境变量中。
该库包含PythonInterpreter类。 使用此类的对象,可以使用execfile()方法执行任何Python脚本。 PythonInterpreter使您可以直接使用PyObjects 。 Jython运行时系统已知的所有对象都由PyObject类或其子类之一的实例表示。
PythonInterpreter类有一些常用的方法,这些方法在下面给出的表中进行了解释。
Sr.No. | 方法和描述 |
---|---|
1 | setIn(PyObject) 设置要用于标准输入流的Python对象 |
2 | setIn(java.io.Reader) 设置java.io.Reader以用于标准输入流 |
3 | setIn(java.io.InputStream) 设置java.io.InputStream以用于标准输入流 |
4 | setOut(PyObject) 设置要用于标准输出流的Python对象 |
5 | setOut(java.io.Writer) 设置java.io.Writer以用于标准输出流 |
6 | setOut(java,io.OutputStream) 设置java.io.OutputStream以用于标准输出流 |
7 | setErr(PyObject) 设置Python错误对象以用于标准错误流 |
8 | setErr(java.io.Writer 设置java.io.Writer以用于标准错误流 |
9 | setErr(java.io.OutputStream) 设置java.io.OutputStream以用于标准错误流 |
10 | eval(String) 将字符串计算为Python源并返回结果 |
11 | eval(PyObject) 评估Python代码对象并返回结果 |
12 | exec(String) 在本地名称空间中执行Python源字符串 |
13 | exec(PyObject) 在本地名称空间中执行Python代码对象 |
14 | execfile(String filename) 在本地名称空间中执行Python源文件 |
15 | execfile(java.io.InputStream) 在本地名称空间中执行Python源的输入流 |
16 | compile(String) 将Python源字符串编译为表达式或模块 |
17 | compile(script, filename) 将Python源代码的脚本编译为表达式或模块 |
18 | set(String name, Object value) 在本地名称空间中设置Object类型的变量 |
19 | set(String name, PyObject value) 在本地名称空间中设置PyObject类型的变量 |
20 | get(String) 获取本地名称空间中变量的值 |
21 | get(String name, Class javaclass 获取本地名称空间中变量的值。 该值将作为给定Java类的实例返回。 |
以下代码块是一个Java程序,它具有PythonInterpreter对象的嵌入式Jython脚本“hello.py”.usingexecfile()方法。 它还显示了如何使用set()和get()方法设置或读取Python变量。
import org.python.util.PythonInterpreter;
import org.python.core.*;
public class SimpleEmbedded {
public static void main(String []args) throws PyException {
PythonInterpreter interp = new PythonInterpreter();
System.out.println("Hello, world from Java");
interp.execfile("hello.py");
interp.set("a", new PyInteger(42));
interp.exec("print a");
interp.exec("x = 2+2");
PyObject x = interp.get("x");
System.out.println("x: "+x);
System.out.println("Goodbye ");
}
}
编译并运行上面的Java程序以获得以下输出。
Hello, world from Java
hello world from Python
42
x: 4
Goodbye
Jython - Eclipse Plugin
PyDev是Eclipse IDE的开源插件,可以在Python,Jython以及IronPython中开发项目。 它托管在https://pydev.org 。 下面给出了在Eclipse IDE中安装PyDev插件的分步过程。
Step 1 - 打开Eclipse IDE并从“帮助”菜单中选择“ Install New Software选项。
Step 2 - 在带有标签的工作前的文本框中输入http://pydev.org/updates ,然后单击“添加”。 选择列表中的所有可用条目,然后单击“下一步”。 向导将花费几分钟完成安装,它将提示重新启动IDE。
Step 3 - 现在从“窗口”菜单中选择首选项选项。 “首选项”对话框将打开,如下所示。
Step 4 - 展开Interpreters节点,然后在左窗格中选择Jython Interpreter。 在右窗格中,单击new以提供jython.jar file路径。
我们现在准备使用Eclipse启动Jython项目。
Jython - A Project in Eclipse
要在eclipse中创建项目,我们应该遵循下面给出的步骤。
Step 1 - 选择文件? 新的? 项目。 从过滤器对话框中选择PyDev 。 提供项目名称,项目类型,然后单击Finish。
Step 2 - Hello项目现在将出现在左侧的项目资源管理器中。 右键单击以在其中添加hello.py。
Step 3 - 编辑器中将出现一个空的hello.py。 编写Jython代码并保存。
Step 4 - 单击菜单栏上的“运行”按钮。 输出将显示在控制台窗口中,如下所示。
Jython - NetBeans Plugin and Project
可以通过nbPython plugin获得对NetBeans的Python和Jython支持。 从以下URL下载插件 - http://plugins.netbeans.org/plugin/56795 。 将下载的存档解压缩到某个文件夹中。 例如 - d:\nbplugin 。 要安装NetBeans插件,请按照下面给出的步骤操作。
Step 1 - 启动Netbeans IDE ,然后转到Tools/Plugin打开插件管理器。 选择“已下载”选项卡,然后浏览到已解压缩下载文件的文件夹。 NetBeans窗口将如下所示。
Step 2 - 下一步是选择所有.nbm文件,然后单击“打开”。
Step 3 - 单击“安装”按钮。
Step 4 - 接受以下许可协议以继续。
忽略有关不受信任的插件源的警告,然后重新启动IDE以继续。
NetBeans中的Jython项目
重新启动后,选择File/New启动一个新项目。 Python类别现在将在类别列表中提供。 选择它继续。
如果系统安装了Python,则会自动检测其版本/版本并显示在Python平台下拉列表中。 但是,Jython不会被列出。 单击“管理”按钮添加它。
单击“新建”按钮以添加平台名称和Jython可执行文件的路径。
Jython现在将在平台列表中提供。 从下拉列表中选择,如以下屏幕截图所示。
我们现在可以在下一个窗口中填写项目名称,位置和主文件。
项目结构将显示在NetBeans IDE的项目窗口中,并在编辑器窗口中显示模板Python代码。
构建并执行Jython项目以在NetBeans IDE的输出窗口中获取以下结果。
Jython - Servlets
Java servlet是使用最广泛的Web开发技术。 我们可以使用Jython编写servlet,除了Java提供的功能外,还增加了许多优点,因为现在我们也可以使用Python语言功能。
我们将使用NetBeans IDE开发带有Jython servlet的Java Web应用程序。 确保在NetBeans安装中安装了nbPython plugin 。 通过选择以下路径启动新项目以构建Web应用程序 - File → New Project → Java web → New Web Application 。
提供项目名称和位置。 IDE将创建项目文件夹结构。 在“项目”窗口的源包节点下添加Java servlet文件(ServletTest.java)。 这将在项目的lib文件夹中添加servlet-api.jar 。 另外,让IDE创建web.xml descriptor file 。 在ServletTest.java添加以下代码。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ServletTest extends HttpServlet {
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost (HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType ("text/html");
PrintWriter toClient = response.getWriter();
toClient.println (
"<html>
<head>
<title>Servlet Test</title>" + "
</head>
<body>
<h1>Servlet Test</h1>
</body>
</html>"
);
}
}
NetBeans创建的web.xml文件如下所示 -
<web-app>
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>ServletTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/ServletTest</url-pattern>
</servlet-mapping>
</web-app>
构建并运行项目以获取出现在浏览器窗口中“h1”标签中的文本Servlet Test 。 因此,我们在应用程序中添加了一个常规的Java servlet。
现在,我们将添加Jython Servlet。 Jython servlet通过中间Java servlet工作也称为PyServlet。 PyServlet.class存在于jython standalone.jar 。 将其添加到WEB-INF/lib文件夹中。
下一步是配置web.xml以在每次引发任何*.py file的请求时调用PyServlet。 这应该通过在其中添加以下xml代码来完成。
<servlet>
<servlet-name>PyServlet</servlet-name>
<servlet-class>org.python.util.PyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PyServlet</servlet-name>
<url-pattern>*.py</url-pattern>
</servlet-mapping>
完整的web.xml代码如下所示。
<web-app>
<servlet>
<servlet-name>ServletTest</servlet-name>
<servlet-class>ServletTest</servlet-class>
</servlet>
<servlet>
<servlet-name>PyServlet</servlet-name>
<servlet-class>org.python.util.PyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest</servlet-name>
<url-pattern>/ServletTest</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>PyServlet</servlet-name>
<url-pattern>*.py</url-pattern>
</servlet-mapping>
</web-app>
将以下Jython代码放在项目文件夹内的WEB-INF文件夹中,作为JythonServlet.py,它等同于之前的ServletTest.java。
from javax.servlet.http import HttpServlet
class JythonServlet1 (HttpServlet):
def doGet(self,request,response):
self.doPost (request,response)
def doPost(self,request,response):
toClient = response.getWriter()
response.setContentType ("text/html")
toClient.println (
"<html>
<head>
<title>Servlet Test</title>" + "
</head>
<body>
<h1>Servlet Test</h1>
</body>
</html>"
)
构建项目并在浏览器中打开以下URL -
http://localhost:8080/jythonwebapp/jythonservlet.py
浏览器将在“h1”标记中显示Servlet Test ,就像Java Servlet输出一样。
Jython - JDBC
Jython使用zxJDBC package ,它提供了一个易于使用的围绕JDBC的Python包装器。 zxJDBC构建了两个标准: JDBC是Java中数据库访问的标准平台, DBI是Python应用程序的标准数据库API。
ZxJDBC为JDBC提供了符合DBI 2.0标准的接口。 超过200个驱动程序可用于JDBC,它们都与zxJDBC一起使用。 所有主要关系数据库均可使用高性能驱动程序,包括 -
- DB2
- Derby
- MySQL
- Oracle
- PostgreSQL
- SQLite
- SQL Server和
- Sybase.
ZxJDBC软件包可以从https://sourceforge.net/projects/zxjdbc/或http://www.ziclix.com/zxjdbc/下载。 下载的存档包含ZxJDBC.jar,应将其添加到CLASSPATH环境变量中。
我们打算与MySQL数据库建立数据库连接。 为此,需要MySQL的JDBC驱动程序。 从以下链接下载MySQL J connector - https://dev.mysql.com/downloads/connector/j/并在CLASSPATH中包含mysql连接器java-5.1.42-bin.jar。
登录MySQL服务器并在测试数据库中创建具有以下结构的学生表 -
领域 | 类型 | 宽度 |
---|---|---|
Name | Varchar | 10 |
Age | Int | 3 |
Marks | Int | 3 |
在其中添加一些记录。
名称 | 年龄 | 分数 |
---|---|---|
Ravi | 21 | 78 |
Ashok | 20 | 65 |
Anil | 22 | 71 |
以dbconnect.py创建以下Jython脚本。
url = "jdbc:mysql://localhost/test"
user = "root"
password = "password"
driver = "com.mysql.jdbc.Driver"
mysqlConn = zxJDBC.connect(url, user, password, driver)
mysqlConn = con.cursor()
mysqlConn.execute(“select * from student)
for a in mysql.fetchall():
print a
从Jython提示符执行上面的脚本。 学生表中的记录将如下所示 -
(“Ravi”, 21, 78)
(“Ashok”, 20, 65)
(“Anil”,22,71)
这解释了在Jython中建立JDBC的过程。
Jython - Using the Swing GUI library
Jython的一个主要特性是它能够在JDK中使用Swing GUI库。 标准Python发行版(通常称为CPython)附带了Tkinter GUI library 。 其他GUI库如PyQt和WxPython也可以与它一起使用,但swing库提供了一个独立于平台的GUI工具包。
与在Java中使用它相比,在Jython中使用swing库要容易得多。 在Java中,必须使用匿名类来创建事件绑定。 在Jython中,我们可以简单地为同一目的传递一个函数。
通过声明JFrame class的对象并将其visible属性设置为true来创建基本顶级窗口。 为此,需要从swing包导入Jframe类。
from javax.swing import JFrame
JFrame类具有多个具有不同参数的构造函数。 我们将使用一个,它将一个字符串作为参数并将其设置为标题。
frame = JFrame(“Hello”)
在将visible属性设置为true之前,请设置框架的大小和位置属性。 将以下代码存储为frame.py 。
from javax.swing import JFrame
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setVisible(True)
从命令提示符运行上面的脚本。 它将显示以下显示窗口的输出。
swing GUI库以Java中的javax.swing包的形式提供。 它的主要容器类JFrame和JDialog分别来自AWT库中的Frame和Dialog类。 其他GUI控件(如JLabel, JButton, JTextField,等)派生自JComponent类。
下图显示了Swing Package Class层次结构。
下表总结了swing库中的不同GUI控件类 -
Sr.No. | 类和描述 |
---|---|
1 | JLabel JLabel对象是用于在容器中放置文本的组件。 |
2 | JButton 该类创建一个带标签的按钮。 |
3 | JColorChooser JColorChooser提供了一个控件窗格,旨在允许用户操作和选择颜色。 |
4 | JCheckBox JCheckBox是一个图形组件,可以处于on (true)或off (false)状态。 |
5 | JRadioButton JRadioButton类是一个图形组件,可以处于on(true)或off(false)状态。 在一组。 |
6 | JList JList组件向用户呈现文本项的滚动列表。 |
7 | JComboBox JComboBox组件向用户显示项目的下拉列表 |
8 | JTextField JTextField对象是一个文本组件,允许编辑单行文本。 |
9 | JPasswordField JPasswordField对象是专门用于输入密码的文本组件。 |
10 | JTextArea JTextArea对象是一个文本组件,允许编辑多行文本。 |
11 | ImageIcon ImageIcon控件是Icon界面的一个实现,它从图像绘制图标 |
12 | JScrollbar Scrollbar控件表示滚动条组件,以便用户可以从值范围中进行选择。 |
13 | JOptionPane JOptionPane提供了一组标准对话框,用于提示用户输入值或通知他们某些内容。 |
14 | JFileChooser JFileChooser控件表示用户可以从中选择文件的对话窗口。 |
15 | JProgressBar 随着任务进展完成,进度条显示任务的完成百分比。 |
16 | JSlider JSlider允许用户通过在有界区间内滑动旋钮以图形方式选择值。 |
17 | JSpinner JSpinner是单行输入字段,允许用户从有序序列中选择数字或对象值。 |
我们将在后续示例中使用其中一些控件。
Jython - Layout Management
Java中的布局管理器是那些管理容器对象(如Frame, Dialog或Panel中控件放置的类。 布局管理器保持控件在框架中的相对位置,即使分辨率更改或框架本身已调整大小。
这些类实现了Layout interface 。 AWT library中定义了以下布局管理器 -
- BorderLayout
- FlowLayout
- GridLayout
- CardLayout
- GridBagLayout
Swing library中定义了以下布局管理器 -
- BoxLayout
- GroupLayout
- ScrollPaneLayout
- SpringLayout
我们将在以下示例中使用AWT布局管理器以及swing布局管理器。
- 绝对布局
- 流程布局
- 网格布局
- 边框布局
- 框布局
- 组布局
现在让我们详细讨论其中的每一个。
绝对布局
在我们探索所有上述布局管理器之前,我们必须查看容器中控件的绝对定位。 我们必须将框架对象的布局方法设置为“无”。
frame.setLayout(None)
然后通过调用setBounds()方法放置控件。 它需要四个参数 - x位置,y位置,宽度和高度。
例如 - 将按钮对象放在绝对位置并使用绝对大小。
btn = JButton("Add")
btn.setBounds(60,80,60,20)
同样,可以通过正确分配位置和大小来放置所有控件。 此布局相对易于使用,但在调整窗口大小时或在屏幕分辨率更改时执行程序时无法保持其外观。
在下面的Jython脚本中,三个Jlabel对象分别用于显示文本“phy”,“maths”和“Total”。 在这三个前面放置了JTextField对象。 Button对象位于“Total”标签上方。
首先,创建JFrame窗口时将布局设置为none。
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setLayout(None)
然后根据它们的绝对位置和大小添加不同的控件。 完整的代码如下 -
from javax.swing import JFrame, JLabel, JButton, JTextField
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setLayout(None)
lbl1 = JLabel("Phy")
lbl1.setBounds(60,20,40,20)
txt1 = JTextField(10)
txt1.setBounds(120,20,60,20)
lbl2 = JLabel("Maths")
lbl2.setBounds(60,50,40,20)
txt2 = JTextField(10)
txt2.setBounds(120, 50, 60,20)
btn = JButton("Add")
btn.setBounds(60,80,60,20)
lbl3 = JLabel("Total")
lbl3.setBounds(60,110,40,20)
txt3 = JTextField(10)
txt3.setBounds(120, 110, 60,20)
frame.add(lbl1)
frame.add(txt1)
frame.add(lbl2)
frame.add(txt2)
frame.add(btn)
frame.add(lbl3)
frame.add(txt3)
frame.setVisible(True)
上述代码的输出如下。
Jython FlowLayout
FlowLayout是容器类的默认布局管理器。 它从左到右,然后从上到下排列控制。
在下面的示例中,Jlabel对象,JTextField对象和JButton对象将使用FlowLayout管理器显示在JFrame中。 首先,让我们从javax.swing包和java.awt包中导入所需的类。
from javax.swing import JFrame, JLabel, JButton, JTextField
from java.awt import FlowLayout
然后创建一个JFrame对象并设置其Location以及size属性。
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(200,200)
Set the layout manager for the frame as FlowLayout.
frame.setLayout(FlowLayout())
现在声明JLabel,JTextfield和JButton类的对象。
label = JLabel("Welcome to Jython Swing")
txt = JTextField(30)
btn = JButton("ok")
最后,通过调用JFrame类的add()方法在框架中添加这些控件。
frame.add(label)
frame.add(txt)
frame.add(btn)
要显示框架,请将其visible属性设置为true。 完整的Jython脚本及其输出如下 -
from javax.swing import JFrame, JLabel, JButton, JTextField
from java.awt import FlowLayout
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(200,200)
frame.setLayout(FlowLayout())
label = JLabel("Welcome to Jython Swing")
txt = JTextField(30)
btn = JButton("ok")
frame.add(label)
frame.add(txt)
frame.add(btn)
frame.setVisible(True)
Jython GridLayout
Gridlayout管理器允许将控件放置在矩形网格中。 一个控件放置在网格的每个单元中。
在下面的示例中,GridLayout应用于JFrame对象,将其分为4行和4列。 JButton对象将放置在网格的每个单元格中。
我们先导入所需的库 -
from javax.swing import JFrame, JButton
from java.awt import GridLayout
然后创建JFrame容器 -
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,400)
现在,通过将其尺寸指定为4乘4来应用GridLayout。
frame.setLayout(GridLayout(4,4))
我们现在应该使用两个FOR循环,每个循环从1到4,所以十六个JButton对象放在后续单元格中。
k = 0
frame.setLayout(GridLayout(4,4))
for i in range(1,5):
for j in range(1,5):
k = k+1
frame.add(JButton(str(k)))
最后将frame的可见性设置为true。 下面给出了完整的Jython代码。
from javax.swing import JFrame, JButton
from java.awt import GridLayout
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,400)
frame.setLayout(GridLayout(4,4))
k = 0
for i in range(1,5):
for j in range(1,5):
k = k+1
frame.add(JButton(str(k)))
frame.setVisible(True)
上述代码的输出如下 -
Jython BorderLayout
BorderLayout管理器将容器划分为五个地理区域和位置,每个区域中包含一个组件。 这些区域由定义的常数表示如下 -
- BorderLayout.NORTH
- BorderLayout.SOUTH
- BorderLayout.EAST
- BorderLayout.WEST
- BorderLayout.CENTER
让我们考虑以下示例 -
Jython BoxLayout
BoxLayout类在javax.swing package定义。 它用于垂直或水平安排容器中的组件。 方向由以下常数决定 -
- X_AXIS
- Y_AXIS
- LINE_AXIS
- PAGE_AXIS
整数常量指定应该布置容器组件的轴。 当容器具有默认组件方向时,LINE_AXIS指定组件从左到右布局,PAGE_AXIS指定组件从上到下布局。
在以下示例中,面板(JPanel类)添加在JFrame对象中。 垂直BoxLayout应用于它,并添加了另外两个面板,顶部和底部。 这两个内部面板有两个按钮,每个按钮都添加在水平Boxlayout中。
我们首先创建顶级JFrame窗口。
frame = JFrame()
frame.setTitle("Buttons")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setSize(300, 150)
声明JPanel对象具有垂直BoxLayout。 将其添加到顶级框架中。
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
frame.add(panel)
在此面板中,顶部和底部增加了两个面板。 它们中的每一个都有两个水平添加的JButton对象,其中25个像素的空间支架将它们分开。
###top panel
top = JPanel()
top.setLayout(BoxLayout(top, BoxLayout.X_AXIS))
b1 = JButton("OK")
b2 = JButton("Close")
top.add(Box.createVerticalGlue())
top.add(b1)
top.add(Box.createRigidArea(Dimension(25, 0)))
top.add(b2)
类似地,构造底板。
###bottom panel
bottom = JPanel()
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
b3 = JButton("Open")
b4 = JButton("Save")
bottom.add(b3)
bottom.add(Box.createRigidArea(Dimension(25, 0)))
bottom.add(b4)
bottom.add(Box.createVerticalGlue())
请注意, createRigidArea()函数用于在两个按钮之间创建25像素的空间。 此外, createVerticalGlue()函数占据布局中的前导或尾随空格。
首先,添加顶部和底部面板,并将框架的visibility属性设置为true。 完整的代码如下 -
from java.awt import Dimension
from javax.swing import JButton, JFrame,JPanel,BoxLayout,Box
frame = JFrame()
frame.setTitle("Buttons")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setSize(300, 150)
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
frame.add(panel)
###top panel
top = JPanel()
top.setLayout(BoxLayout(top, BoxLayout.X_AXIS))
b1 = JButton("OK")
b2 = JButton("Close")
top.add(Box.createVerticalGlue())
top.add(b1)
top.add(Box.createRigidArea(Dimension(25, 0)))
top.add(b2)
###bottom panel
bottom = JPanel()
bottom.setLayout(BoxLayout(bottom, BoxLayout.X_AXIS))
b3 = JButton("Open")
b4 = JButton("Save")
bottom.add(b3)
bottom.add(Box.createRigidArea(Dimension(25, 0)))
bottom.add(b4)
bottom.add(Box.createVerticalGlue())
panel.add(bottom)
panel.add(top)
frame.setVisible(True)
上面的代码将生成以下输出。
Jython GroupLayout
GroupLayout管理器以分层方式对组件进行分组。 分组由两个类完成,即SequentialGroup和ParallelGroup ,它们都在Java中实现Group接口。
布局过程分为两个步骤。 在一步中,组件与水平轴一起放置,并且沿垂直轴放置在第二轴上。 必须在布局中将每个组件定义两次。
有两种类型的排列,顺序和并行。 在两者中,我们可以顺序或并行地排列组件。 在水平排列中,行称为顺序组,列称为并行组。 另一方面,在并行排列中,元素行是并行组和列,称为顺序。
在下面的示例中,五个按钮以这样的方式排列,即每个按钮以行和列的形式出现。 首先,在JFrame窗口中添加Jpanel对象,并将其布局设置为Grouplayout。
frame = JFrame()
panel = JPanel()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
layout = GroupLayout(panel)
panel.setLayout(layout)
然后构造JButton对象 -
buttonD = JButton("D")
buttonR = JButton("R")
buttonY = JButton("Y")
buttonO = JButton("O")
buttonT = JButton("T")
接下来,我们创建一个名为LeftToRight的SequentialGroup ,其中添加了buttonD和buttonY。 在它们之间,放置了一个ParallelGroup ColumnMiddle(垂直添加了其他三个按钮)。
leftToRight = layout.createSequentialGroup()
leftToRight.addComponent(buttonD)
columnMiddle = layout.createParallelGroup()
columnMiddle.addComponent(buttonR)
columnMiddle.addComponent(buttonO)
columnMiddle.addComponent(buttonT)
leftToRight.addGroup(columnMiddle)
leftToRight.addComponent(buttonY)
现在出现了名为TopToBottom的垂直SequentialGroup的定义。 添加三个按钮的ParallelGroup行,然后垂直放置两个按钮。
topToBottom = layout.createSequentialGroup()
rowTop = layout.createParallelGroup()
rowTop.addComponent(buttonD)
rowTop.addComponent(buttonR)
rowTop.addComponent(buttonY)
topToBottom.addGroup(rowTop)
topToBottom.addComponent(buttonO)
topToBottom.addComponent(buttonT)
最后,将LeftToRight组水平设置,将TopToBottom组垂直设置为布局对象。 完整的代码如下 -
from javax.swing import JButton, JFrame,JPanel,GroupLayout
frame = JFrame()
panel = JPanel()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
layout = GroupLayout(panel)
panel.setLayout(layout)
buttonD = JButton("D")
buttonR = JButton("R")
buttonY = JButton("Y")
buttonO = JButton("O")
buttonT = JButton("T")
leftToRight = layout.createSequentialGroup()
leftToRight.addComponent(buttonD)
columnMiddle = layout.createParallelGroup()
columnMiddle.addComponent(buttonR)
columnMiddle.addComponent(buttonO)
columnMiddle.addComponent(buttonT)
leftToRight.addGroup(columnMiddle)
leftToRight.addComponent(buttonY)
topToBottom = layout.createSequentialGroup()
rowTop = layout.createParallelGroup()
rowTop.addComponent(buttonD)
rowTop.addComponent(buttonR)
rowTop.addComponent(buttonY)
topToBottom.addGroup(rowTop)
topToBottom.addComponent(buttonO)
topToBottom.addComponent(buttonT)
layout.setHorizontalGroup(leftToRight)
layout.setVerticalGroup(topToBottom)
frame.add(panel)
frame.pack()
frame.setVisible(True)
上述代码的输出如下 -
Jython - Event Handling
Java swing中的事件处理要求控件(如JButton或JList等)应该在相应的事件监听器中注册。 事件侦听器接口或相应的Adapter类需要通过覆盖事件处理方法来实现或子类化。 在Jython中,事件处理非常简单。 我们可以传递任何函数作为与控件对应的事件处理函数的属性。
让我们首先看看如何在Java中处理click事件。
首先,我们必须导入java.awt.event package 。 接下来,扩展JFrame的类必须实现ActionListener接口。
public class btnclick extends JFrame implements ActionListener
然后,我们必须声明JButton对象,将其添加到frame的ContentPane,然后通过addActionListener()方法将其注册到ActionListener。
JButton b1 = new JButton("Click here");
getContentPane().add(b1);
b1.addActionListener(this);
现在,必须重写ActionListener接口的actionPerformed()方法来处理ActionEvent。
以下是整个Java代码 -
import java.awt.event.*;
import javax.swing.*;
public class btnclick extends JFrame implements ActionListener {
btnclick() {
JButton b1 = new JButton("Click here");
getContentPane().add(b1);
b1.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked");
}
public static void main(String args[]) {
btnclick b = new btnclick();
b.setSize(300,200);
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.setVisible(true);
}
}
现在,我们将编写相当于相同代码的Jython代码。
首先,我们不需要导入ActionEvent或ActionListener,因为Jython的动态类型允许我们避免在代码中提及这些类。
其次,不需要实现或子类化ActionListener。 相反,任何用户定义的函数都是作为actionPerformed bean属性的值直接提供给JButton构造函数的。
button = JButton('Click here!', actionPerformed = clickhere)
clickhere()函数被定义为常规Jython函数,它处理按钮上的click事件。
def change_text(event):
print clicked!'
这是Jython等效代码。
from javax.swing import JFrame, JButton
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
def clickhere(event):
print "clicked"
btn = JButton("Add", actionPerformed = clickhere)
frame.add(btn)
frame.setVisible(True)
Java和Jython代码的输出完全相同。 单击该按钮时,它将在控制台上打印“单击”消息。
在下面的Jython代码中,JFrame窗口上提供了两个JTextField对象,用于输入'phy'和'maths'中的标记。 单击时,JButton对象执行add()函数。
btn = JButton("Add", actionPerformed = add)
add()函数通过getText()方法读取两个文本字段的内容,并将它们解析为整数,以便可以执行添加。 然后通过setText()方法将结果放在第三个文本字段中。
def add(event):
print "add"
ttl = int(txt1.getText())+int(txt2.getText())
txt3.setText(str(ttl))
完整的代码如下 -
from javax.swing import JFrame, JLabel, JButton, JTextField
from java.awt import Dimension
frame = JFrame("Hello")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,200)
frame.setLayout(None)
def add(event):
print "add"
ttl = int(txt1.getText())+int(txt2.getText())
txt3.setText(str(ttl))
lbl1 = JLabel("Phy")
lbl1.setBounds(60,20,40,20)
txt1 = JTextField(10)
txt1.setBounds(120,20,60,20)
lbl2 = JLabel("Maths")
lbl2.setBounds(60,50,40,20)
txt2 = JTextField(10)
txt2.setBounds(120, 50, 60,20)
btn = JButton("Add", actionPerformed = add)
btn.setBounds(60,80,60,20)
lbl3 = JLabel("Total")
lbl3.setBounds(60,110,40,20)
txt3 = JTextField(10)
txt3.setBounds(120, 110, 60,20)
frame.add(lbl1)
frame.add(txt1)
frame.add(lbl2)
frame.add(txt2)
frame.add(btn)
frame.add(lbl3)
frame.add(txt3)
frame.setVisible(True)
从命令提示符执行上述代码时,将显示以下窗口。 输入“Phy”,“Maths”的标记,然后单击“添加”按钮。 结果将相应显示。
Jython JRadioButton活动
JRadioButton类在javax.swing package定义。 它会创建一个具有开启或关闭状态的可选切换按钮。 如果在ButtonGroup中添加了多个单选按钮,则它们的选择是互斥的。
在以下示例中,JRadioButton类的两个对象和两个JLabel将添加到垂直BoxLayout中的Jpanel容器中。 在JRadioButton对象的构造函数中, OnCheck()函数被设置为actionPerformed属性的值。 单击单选按钮以更改其状态时,将执行此功能。
rb1 = JRadioButton("Male", True,actionPerformed = OnCheck)
rb2 = JRadioButton("Female", actionPerformed = OnCheck)
请注意,单选按钮的默认状态为false(未选中)。 创建按钮rb1,其起始状态为True(已选中)。
两个单选按钮被添加到单选按钮组以使它们互斥,因此如果选择了一个,则会自动取消选择其他按钮。
grp = ButtonGroup()
grp.add(rb1)
grp.add(rb2)
这两个单选按钮以及两个标签被添加到垂直布局中的面板对象,其中rb2和lbl2之间的高度为25像素的分隔符区域。
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
panel.add(Box.createVerticalGlue())
panel.add(lbl)
panel.add(rb1)
panel.add(rb2)
panel.add(Box.createRigidArea(Dimension(0,25)))
panel.add(lbl1)
此面板将添加到顶级JFrame对象,其可见属性最后设置为“True”。
frame = JFrame("JRadioButton Example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(250,200)
frame.setVisible(True)
The complete code of radio.py is given below:
from javax.swing import JFrame, JPanel, JLabel, BoxLayout, Box
from java.awt import Dimension
from javax.swing import JRadioButton,ButtonGroup
frame = JFrame("JRadioButton Example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(250,200)
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
frame.add(panel)
def OnCheck(event):
lbl1.text = ""
if rb1.isSelected():
lbl1.text = lbl1.text+"Gender selection : Male"
else:
lbl1.text = lbl1.text+"Gender selection : Female "
lbl = JLabel("Select Gender")
rb1 = JRadioButton("Male", True,actionPerformed = OnCheck)
rb2 = JRadioButton("Female", actionPerformed = OnCheck)
grp = ButtonGroup()
grp.add(rb1)
grp.add(rb2)
lbl1 = JLabel("Gender Selection :")
panel.add(Box.createVerticalGlue())
panel.add(lbl)
panel.add(rb1)
panel.add(rb2)
panel.add(Box.createRigidArea(Dimension(0,25)))
panel.add(lbl1)
frame.setVisible(True)
运行上面的Jython脚本并更改单选按钮选择。 选择将显示在底部的标签中。
Jython JCheckBox事件
与JRadioButton一样,JCheckBox对象也是一个可选按钮,除了标题之外还有一个矩形可检查框。 这通常用于为用户提供从项目列表中选择多个选项的机会。
在以下示例中,两个复选框和swing包中的标签将添加到垂直BoxLayout中的JPanel中。 底部的标签显示两个复选框的瞬时选择状态。
两个复选框都是使用构造函数声明的,其actionPerformed属性设置为OnCheck()函数。
box1 = JCheckBox("Check1", actionPerformed = OnCheck)
box2 = JCheckBox("Check2", actionPerformed = OnCheck)
OnCheck()函数验证每个复选框的选择状态,并在底部的标签上显示相应的消息。
def OnCheck(event):
lbl1.text = ""
if box1.isSelected():
lbl1.text = lbl1.text + "box1 selected "
else:
lbl1.text = lbl1.text + "box1 not selected "
if box2.isSelected():
lbl1.text = lbl1.text + "box2 selected"
else:
lbl1.text = lbl1.text + "box2 not selected"
这些框和JLabel对象被添加到JPanel中,并在它们之间添加了50像素高的空格。
panel = JPanel()
panel.setLayout(BoxLayout(panel, BoxLayout.Y_AXIS))
panel.add(Box.createVerticalGlue())
panel.add(box1)
panel.add(box2)
panel.add(Box.createRigidArea(Dimension(0,50)))
panel.add(lbl1)
面板本身被添加到顶级JFrame窗口,其可见属性最终设置为true。
frame = JFrame("JCheckBox Example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(250,150)
frame.add(panel)
frame.setVisible(True)
运行上面的代码并尝试选中复选框。 两个复选框的瞬时状态显示在底部。
Jython JList事件
swing包中的JList控件为用户提供了可滚动的项目列表供选择。 JComboBox提供了项目的下拉列表。 在Java中,通过在ListSelectionListener中实现valueChanged()方法来处理选择事件。 在Jython中,事件处理程序被分配给JList对象的valueChanged属性。
在以下示例中,JList对象和标签将添加到BorderLayout中的JFrame。 JList中填充了元组中的项集合。 它的valueChanged属性设置为listSelect()函数。
lang = ("C", "C++", "Java", "Python", "Perl", "C#", "VB", "PHP", "Javascript", "Ruby")
lst = JList(lang, valueChanged = listSelect)
事件处理程序函数获取所选项的索引,并从JList对象中提取相应的项以显示在底部的标签上。
def listSelect(event):
index = lst.selectedIndex
lbl1.text = "Hello" + lang[index]
使用BorderLayout将JList和JLabel对象添加到JFrame。
整个代码如下 -
from javax.swing import JFrame, JPanel, JLabel, JList
from java.awt import BorderLayout
frame = JFrame("JList Example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(300,250)
frame.setLayout(BorderLayout())
def listSelect(event):
index = lst.selectedIndex
lbl1.text = "Hello" + lang[index]
lang = ("C", "C++", "Java", "Python", "Perl", "C#", "VB", "PHP", "Javascript", "Ruby")
lst = JList(lang, valueChanged = listSelect)
lbl1 = JLabel("box1 not selected box2 not selected")
frame.add(lst, BorderLayout.NORTH)
frame.add(lbl1, BorderLayout.SOUTH)
frame.setVisible(True)
以下代码的输出如下。
Jython - Menus
大多数基于GUI的应用程序顶部都有一个菜单栏。 它位于顶层窗口的标题栏下方。 javax.swing包具有精心设置的功能来构建高效的菜单系统。 它是在JMenuBar, JMenu和JMenuItem类的帮助下构建的。
在以下示例中,顶级窗口中提供了菜单栏。 菜单栏中添加了一个由三个菜单项按钮组成的文件菜单。 现在让我们准备一个JFrame对象,其布局设置为BorderLayout。
frame = JFrame("JMenuBar example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,300)
frame.setLayout(BorderLayout())
现在,SetJMenuBar()方法激活JMenuBar对象。
bar = JMenuBar()
frame.setJMenuBar(bar)
接下来,声明具有“文件”标题的JMenu对象。 “文件”菜单中添加了三个JMenuItem按钮。 单击任何菜单项时,将执行ActionEvent处理程序OnClick()函数。 它使用actionPerformed属性定义。
file = JMenu("File")
newfile = JMenuItem("New",actionPerformed = OnClick)
openfile = JMenuItem("Open",actionPerformed = OnClick)
savefile = JMenuItem("Save",actionPerformed = OnClick)
file.add(newfile)
file.add(openfile)
file.add(savefile)
bar.add(file)
OnClick()事件处理程序通过gwtActionCommand()函数检索JMenuItem按钮的名称,并将其显示在窗口底部的文本框中。
def OnClick(event):
txt.text = event.getActionCommand()
“文件”菜单对象将添加到菜单栏中。 最后,在JFrame对象的底部添加了一个JTextField控件。
txt = JTextField(10)
frame.add(txt, BorderLayout.SOUTH)
menu.py的整个代码如下 -
from javax.swing import JFrame, JMenuBar, JMenu, JMenuItem, JTextField
from java.awt import BorderLayout
frame = JFrame("JMenuBar example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,300)
frame.setLayout(BorderLayout())
def OnClick(event):
txt.text = event.getActionCommand()
bar = JMenuBar()
frame.setJMenuBar(bar)
file = JMenu("File")
newfile = JMenuItem("New",actionPerformed = OnClick)
openfile = JMenuItem("Open",actionPerformed = OnClick)
savefile = JMenuItem("Save",actionPerformed = OnClick)
file.add(newfile)
file.add(openfile)
file.add(savefile)
bar.add(file)
txt = JTextField(10)
frame.add(txt, BorderLayout.SOUTH)
frame.setVisible(True)
使用Jython解释器执行上述脚本时,会出现一个带有File菜单的窗口。 单击它,它的三个菜单项将下拉。 如果单击任何按钮,其名称将显示在文本框控件中。
Jython - Dialogs
Dialog对象是一个窗口,显示在用户与之交互的基本窗口的顶部。 在本章中,我们将看到swing库中定义的预配置对话框。 它们是MessageDialog, ConfirmDialog和InputDialog 。 由于JOptionPane类的静态方法,它们可用。
在以下示例中,“文件”菜单有三个与上述三个对话框对应的JMenu项; 每个都执行OnClick事件处理程序。
file = JMenu("File")
msgbtn = JMenuItem("Message",actionPerformed = OnClick)
conbtn = JMenuItem("Confirm",actionPerformed = OnClick)
inputbtn = JMenuItem("Input",actionPerformed = OnClick)
file.add(msgbtn)
file.add(conbtn)
file.add(inputbtn)
OnClick()处理函数检索Menu Item按钮的标题并调用相应的showXXXDialog()方法。
def OnClick(event):
str = event.getActionCommand()
if str == 'Message':
JOptionPane.showMessageDialog(frame,"this is a sample message dialog")
if str == "Input":
x = JOptionPane.showInputDialog(frame,"Enter your name")
txt.setText(x)
if str == "Confirm":
s = JOptionPane.showConfirmDialog (frame, "Do you want to continue?")
if s == JOptionPane.YES_OPTION:
txt.setText("YES")
if s == JOptionPane.NO_OPTION:
txt.setText("NO")
if s == JOptionPane.CANCEL_OPTION:
txt.setText("CANCEL")
如果选择了菜单中的消息选项,则会弹出一条消息。 如果单击“输入”选项,则会弹出一个询问输入的对话框。 然后输入文本显示在JFrame窗口的文本框中。 如果选择了确认选项,则会出现一个包含三个按钮,YES,NO和CANCEL的对话框。 用户的选择记录在文本框中。
整个代码如下 -
from javax.swing import JFrame, JMenuBar, JMenu, JMenuItem, JTextField
from java.awt import BorderLayout
from javax.swing import JOptionPane
frame = JFrame("Dialog example")
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
frame.setLocation(100,100)
frame.setSize(400,300)
frame.setLayout(BorderLayout())
def OnClick(event):
str = event.getActionCommand()
if str == 'Message':
JOptionPane.showMessageDialog(frame,"this is a sample message dialog")
if str == "Input":
x = JOptionPane.showInputDialog(frame,"Enter your name")
txt.setText(x)
if str == "Confirm":
s = JOptionPane.showConfirmDialog (frame, "Do you want to continue?")
if s == JOptionPane.YES_OPTION:
txt.setText("YES")
if s == JOptionPane.NO_OPTION:
txt.setText("NO")
if s == JOptionPane.CANCEL_OPTION:
txt.setText("CANCEL")
bar = JMenuBar()
frame.setJMenuBar(bar)
file = JMenu("File")
msgbtn = JMenuItem("Message",actionPerformed = OnClick)
conbtn = JMenuItem("Confirm",actionPerformed = OnClick)
inputbtn = JMenuItem("Input",actionPerformed = OnClick)
file.add(msgbtn)
file.add(conbtn)
file.add(inputbtn)
bar.add(file)
txt = JTextField(10)
frame.add(txt, BorderLayout.SOUTH)
frame.setVisible(True)
执行上述脚本时,将显示以下窗口,其中包含菜单中的三个选项 -