- Jython 教程
- Jython - 首頁
- Jython - 概述
- Jython - 安裝
- Jython - 匯入 Java 庫
- Jython - 變數和資料型別
- Jython - 使用 Java 集合型別
- Jython - 決策控制
- Jython - 迴圈
- Jython - 函式
- Jython - 模組
- Jython - 包
- Jython - Java 應用程式
- Jython - Eclipse 外掛
- Jython - Eclipse 中的專案
- Jython - NetBeans 外掛和專案
- Jython - Servlet
- Jython - JDBC
- Jython - 使用 Swing GUI 庫
- Jython - 佈局管理
- Jython - 事件處理
- Jython - 選單
- Jython - 對話方塊
- Jython 有用資源
- Jython 快速指南
- Jython - 有用資源
- Jython - 討論
Jython 快速指南
Jython - 概述
Jython 是 Python 程式語言的 JVM 實現。它旨在在 Java 平臺上執行。Jython 程式可以匯入和使用任何 Java 類。就像 Java 一樣,Jython 程式編譯成位元組碼。主要優勢之一是,用 Python 設計的使用者介面可以使用AWT、Swing 或SWT 包的 GUI 元素。
Jython 最初名為 JPython,後來改名為 Jython,它緊隨Guido Van Rossum建立的稱為CPython的標準 Python 實現。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 具有更豐富的內建資料結構(列表、字典、元組,所有內容都是物件)。
Python 和 Jython 之間的區別
以下是 Python 和 Jython 之間的區別:
稱為 CPython 的 Python 參考實現是用 C 語言編寫的。另一方面,Jython 完全是用 Java 編寫的,並且是 JVM 實現。
標準 Python 可用於多個平臺。Jython 可用於安裝了 JVM 的任何平臺。
標準 Python 程式碼編譯成.pyc檔案,而 Jython 程式編譯成.class檔案。
Python 擴充套件可以用 C 語言編寫。Jython 的擴充套件是用 Java 編寫的。
Jython 本質上是多執行緒的。但是,Python 使用全域性直譯器鎖 (GIL) 機制來實現此目的。
兩種實現具有不同的垃圾回收機制。
在下一章中,我們將學習如何在 Jython 中匯入 Java 庫。
Jython - 安裝
在安裝 Jython 2.7 之前,請確保系統已安裝JDK 7或更高版本。Jython 以可執行 jar 檔案的形式提供。從 - https://www.jython.org/download.html 下載它,然後雙擊其圖示或執行以下命令:
java -jar jython_installer-2.7.0.jar
安裝嚮導將開始,其中必須提供安裝選項。以下是系統的安裝過程。
嚮導的第一步要求您選擇語言。
第二步提示您接受許可協議。
在下一步中,選擇安裝型別。建議選擇標準安裝。
下一個螢幕會詢問您有關選項的確認,然後繼續完成安裝。
安裝過程可能需要一些時間才能完成。
安裝完成後,從目標目錄內的 bin 目錄中呼叫jython.exe。假設 Jython 安裝在C:\jython27中,請從命令列執行以下操作。
C:\jython27\bin\jython
將出現 Python 提示符 (>>>),在它前面可以執行任何 Python 語句或 Python 指令碼。
Jython - 匯入 Java 庫
Jython 最重要的功能之一是能夠在 Python 程式中匯入 Java 類。我們可以像在 Java 程式中一樣在 Jython 中匯入任何 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 庫要麼沒有它們的等效項,要麼不如它們好。
- Servlet
- JMS
- J2EE
- Javadoc
- Swing 被認為優於其他 GUI 工具包
任何 Java 包都可以在 Jython 指令碼中匯入。在這裡,以下 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呼叫此類中的方法。
from foo import HelloWorld
h = HelloWorld()
h.hello()
h.hello("TutorialsPoint")
儲存並從命令列執行上述指令碼以獲取以下輸出。
C:\jython27\bin>jython importex.py Hello World! Hello TutorialsPoint!
Jython - 變數和資料型別
變數是計算機記憶體中命名的儲存位置。每個變數可以在其中儲存一個數據。與 Java 不同,Python 是一種動態型別語言。因此,在使用 Jython 時也是如此;不會執行變數資料型別的預先宣告。與其說是變數的型別決定了可以在其中儲存哪些資料,不如說是資料決定了變數的型別。
在以下示例中,變數被分配了一個整數值。使用 type() 內建函式,我們可以驗證變數的型別是整數。但是,如果將相同的變數分配給字串,則 type() 函式將字串作為相同變數的型別。
> x = 10 >>> type(x) <class 'int'> >>> x = "hello" >>> type(x) <class 'str'>
這解釋了為什麼 Python 被稱為動態型別語言。
以下 Python 內建資料型別也可以在 Jython 中使用:
- 數字
- 字串
- 列表
- 元組
- 字典
Python 將數字資料識別為數字,它可以是整數、帶浮點數的實數或複數。字串、列表和元組資料型別稱為序列。
Jython 數字
在 Python 中,任何帶符號整數都被稱為型別“int”。要表示長整數,請在其後附加字母“L”。用小數點分隔整數部分和小數部分的數字稱為“float”。小數部分可以包含用“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 字串
字串是任何用單引號(例如“hello”)、雙引號(例如“hello”)或三引號(例如“““hello”””或“““hello”””)括起來的字元序列。如果字串的內容跨越多行,則三引號特別有用。
轉義序列字元可以在三引號字串中逐字包含。以下示例顯示了在 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 列表
列表是一種序列資料型別。它是用方括號儲存的逗號分隔專案的集合,這些專案不一定屬於相同型別。可以使用基於零的索引訪問列表中的單個專案。
以下程式碼塊總結了 Python 中列表的使用。
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) | 長度 |
| List[2]=10 | 更新 |
| Del List[1] | 刪除 |
| List.append(20) | 追加 |
| List.insert(1,15) | 插入 |
| List.sort() | 排序 |
Jython 元組
元組是用括號儲存的逗號分隔資料項的不可變集合。無法刪除或修改元組中的元素,也無法向元組集合中新增元素。以下程式碼塊顯示了元組操作。
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 字典類似於 Java 集合框架中的 Map 類。它是鍵值對的集合。用花括號括起來,逗號分隔的對。字典物件不遵循基於零的索引來檢索其中的元素,因為它們是透過雜湊技術儲存的。
同一個鍵不能在字典物件中出現多次。但是,多個鍵可以具有相同的關聯值。下面解釋了字典物件可用的不同函式:
dict = {'011':'New Delhi','022':'Mumbai','033':'Kolkata'}
print "dict[‘011’]: ",dict['011']
print "dict['Age']: ", dict['Age']
下表描述了一些與字典相關的最常見的 Jython 表示式。
| Jython 表示式 | 描述 |
|---|---|
| dict.get(‘011’) | 搜尋 |
| len(dict) | 長度 |
| dict[‘044’] = ‘Chennai’ | 追加 |
| del dict[‘022’] | 刪除 |
| dict.keys() | 鍵列表 |
| dict.values() | 值列表 |
| dict.clear() | 刪除所有元素 |
Jython - 使用 Java 集合型別
除了 Python 的內建資料型別之外,Jython 還可以透過匯入java.util 包來使用 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 物件,它允許在 Python 中構造 Java 陣列。為了使用 jarray,只需在 Jython 中定義一個序列型別並將其與包含在序列中的物件型別一起傳遞給 jarrayobject。jarray 中的所有值必須是相同型別。
下表顯示了與 jarray 一起使用的字元型別程式碼。
| 字元型別程式碼 | 相應的 Java 型別 |
|---|---|
| Z | 布林值 |
| C | 字元 |
| B | 位元組 |
| H | 短整型 |
| I | 整型 |
| L | 長整型 |
| F | 浮點型 |
| D | 雙精度浮點型 |
以下示例顯示了 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 字串序列構造的。上述指令碼jarray.py的輸出如下:
array('i', [1, 2, 3, 4, 5])
array('c', 'Hello Jython')
Jython - 決策控制
決策結構包含一個或多個條件,程式需要對其進行評估或測試,以及如果條件被判定為真則要執行的語句或語句組,並且可以選擇性地執行其他語句,如果條件被判定為假。
下圖顯示了大多數程式語言中常見的決策結構的通用形式。
Jython 不使用花括號來指示當條件為真或假時要執行的語句塊(如 Java 中那樣)。相反,使用統一縮排(從左邊緣的空格)來形成語句塊。這樣的統一縮排塊使得當“if”語句中給定的條件為真時要執行的條件程式碼。
一個類似的塊可能存在於可選的“else”語句之後。Jython 還提供了elif 語句,可以使用它來測試連續的條件。在這裡,else 子句將最後出現,並且僅當所有前面的條件都失敗時才會執行。使用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 - 迴圈
通常,程式中的語句按順序執行:函式中的第一個語句首先執行,然後是第二個語句,依此類推。可能存在您需要多次執行程式碼塊的情況。提供這種重複功能的語句稱為迴圈語句。
在 Jython 中,迴圈可以透過兩個語句形成,它們是:
while 語句和
for 語句
WHILE 迴圈
Jython 中的 while 迴圈語句類似於 Java 中的 while 迴圈語句。只要給定的條件為真,它就會重複執行語句塊。以下流程圖描述了while迴圈的行為。
while 語句的通用語法如下所示。
while expression: statement(s)
以下 Jython 程式碼使用 while 迴圈重複遞增和列印變數的值,直到它小於零。
count = 0 while count<10: count = count+1 print "count = ",count print "Good Bye!"
輸出 - 輸出將如下所示。
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 語句顯示字串中的每個字元,以及列表或元組中的每個專案,如下所示:
#each letter in string for letter in 'Python': print 'Current Letter :', letter
輸出 - 輸出將如下所示。
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
輸出 - 輸出將如下所示。
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
輸出 - 上述程式的輸出如下所示。
Current library : PyQt Current library : WxPython Current library : Tkinter
在 Jython 中,for 語句也用於迭代由 range() 函式生成的數字列表。range() 函式採用以下形式:
range[([start],stop,[step])
start 和 step 引數預設為 0 和 1。生成的最後一個數字是 stop step。FOR 語句遍歷由range() 函式形成的列表。例如:
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異常。
示例
#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)
輸出將如下所示:
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 - 模組
模組是 Jython 指令碼,其中定義了一個或多個相關的函式、類或變數。這允許 Jython 程式碼的邏輯組織。模組中定義的程式元素可以透過匯入模組或從中匯入特定元素(函式/類)在另一個 Jython 指令碼中使用。
在以下程式碼(hello.py)中,定義了一個函式SayHello()。
#definition of function defSayHello(str): print "Hello ", str return
要從另一個指令碼使用 SayHello() 函式,請在其中匯入hello.py 模組。
import hello
hello.SayHello("TutorialsPoint")
但是,這將匯入模組中定義的所有函式。為了從模組匯入特定函式,請使用以下語法。
from modname import name1[, name2[,... nameN]
例如,要僅匯入 SayHello() 函式,請將上述指令碼更改如下。
from hello import SayHello
SayHello("TutorialsPoint")
在呼叫函式時,無需為模組名稱新增字首。
Jython - 包
任何包含一個或多個 Jython 模組的資料夾都被識別為包。但是,它必須有一個名為__init__.py的特殊檔案,該檔案提供要使用的函式索引。
現在讓我們瞭解如何建立和匯入包。
步驟 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
步驟 2 - 在 package1 資料夾中建立並儲存__init__.py檔案,內容如下。
#__init__.py from fact import factorial from sum import add from mult import multiply
步驟 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
步驟 4 - 從 Jython 提示符執行 test.py。將獲得以下輸出。
factorial = 120 addition = 30 multiplication = 200
Jython - Java 應用程式
下載jython-standalone-2.7.0.jar - 用於從其官方下載頁面將 Jython 嵌入到 Java 應用程式中:http://www.jython.org/downloads.html並將此 jar 檔案包含在 Java CLASSPATH 環境變數中。
此庫包含PythonInterpreter類。使用此類的物件,可以使用execfile()方法執行任何 Python 指令碼。PythonInterpreter 使您能夠直接使用PyObjects。Jython 執行時系統已知的所有物件都由類 PyObject 或其子類的例項表示。
PythonInterpreter 類有一些常用的方法,在下表中解釋。
| 序號 | 方法和描述 |
|---|---|
| 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 獲取本地名稱空間中變數的值。該值將作為給定 Java 類的例項返回。 |
以下程式碼塊是一個 Java 程式,其中嵌入了 Jython 指令碼“hello.py”。使用 PythonInterpreter 物件的 execfile()方法。它還展示瞭如何使用 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 外掛
PyDev 是 Eclipse IDE 的一個開源外掛,用於啟用 Python、Jython 以及 IronPython 專案的開發。它託管在https://pydev.org。下面是將 PyDev 外掛安裝到 Eclipse IDE 中的分步過程。
步驟 1 - 開啟 Eclipse IDE 並從“幫助”選單中選擇“安裝新軟體”選項。
步驟 2 - 在“使用”標籤前面的文字框中輸入http://pydev.org/updates,然後單擊“新增”。選擇列表中的所有可用條目,然後單擊“下一步”。嚮導將花費幾分鐘來完成安裝,並且它將提示 IDE 重新啟動。
步驟 3 - 現在從“視窗”選單中選擇“首選項”選項。將開啟“首選項”對話方塊,如下所示。
步驟 4 - 展開“直譯器”節點,並在左側窗格中選擇“Jython 直譯器”。在右側窗格中,單擊“新建”以提供jython.jar 檔案的路徑。
現在我們準備使用 Eclipse 啟動 Jython 專案。
Jython - Eclipse 中的專案
要在 eclipse 中建立一個專案,我們應該按照以下步驟操作。
步驟 1 - 選擇“檔案”→“新建”→“專案”。從過濾器對話方塊中選擇PyDev。提供專案名稱、專案型別,然後單擊“完成”。
步驟 2 - Hello 專案現在將出現在左側的專案資源管理器中。右鍵單擊以在其中新增 hello.py。
步驟 3 - 一個空的 hello.py 將出現在編輯器中。編寫 Jython 程式碼並儲存。
步驟 4 - 單擊選單欄上的“執行”按鈕。輸出將出現在控制檯視窗中,如下所示。
Jython - NetBeans 外掛和專案
NetBeans 的 Python 和 Jython 支援可以透過 **nbPython 外掛** 獲得。從以下 URL 下載外掛 - http://plugins.netbeans.org/plugin/56795。將下載的壓縮檔案解壓到某個資料夾中。例如 - **d:\nbplugin**。要安裝 NetBeans 外掛,請按照以下步驟操作。
**步驟 1** - 啟動 **Netbeans IDE**,然後轉到 Tools/Plugin 以開啟外掛管理器。選擇“Downloaded”選項卡,然後瀏覽到已解壓縮下載檔案的資料夾。NetBeans 視窗將如下所示。
**步驟 2** - 下一步是選擇所有 **.nbm** 檔案並單擊開啟。
**步驟 3** - 單擊“Install”按鈕。
**步驟 4** - 接受以下許可協議以繼續。
忽略有關外掛不受信任來源的警告並重新啟動 IDE 以繼續。
NetBeans 中的 Jython 專案
重新啟動後,透過選擇 File/New 啟動一個新專案。Python 類別現在將在類別列表中可用。選擇它以繼續。
如果系統已安裝 Python,則其版本/版本將自動檢測到並在 Python 平臺下拉列表中顯示。但是,Jython 不會列出。單擊“Manage”按鈕新增它。
單擊“New”按鈕新增 Jython 可執行檔案的平臺名稱和路徑。
Jython 現在將在平臺列表中可用。從下拉列表中選擇,如下面的螢幕截圖所示。
我們現在可以在下一個視窗中填寫專案名稱、位置和主檔案。
專案結構將出現在 NetBeans IDE 的專案視窗中,並在編輯器視窗中顯示模板 Python 程式碼。
構建並執行 Jython 專案以在 NetBeans IDE 的輸出視窗中獲得以下結果。
Jython - Servlet
Java servlet 是最廣泛使用的 Web 開發技術。我們可以使用 Jython 編寫 servlet,這增加了 Java 無法提供的許多優勢,因為現在我們也可以利用 Python 語言的功能。
我們將使用 NetBeans IDE 開發一個包含 Jython servlet 的 Java Web 應用程式。確保 **nbPython 外掛** 已安裝在 NetBeans 安裝中。透過選擇以下路徑啟動一個新專案以構建 Web 應用程式 - **File → New Project → Java web → New Web Application**。
提供專案名稱和位置。IDE 將建立專案資料夾結構。在“Projects”視窗的源包節點下新增一個 Java servlet 檔案 (ServletTest.java)。這將在專案的 lib 資料夾中新增 **servlet-api.jar**。此外,讓 IDE 建立 web.xml **描述符檔案**。在 **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 檔案** 的請求時呼叫 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 -
https://:8080/jythonwebapp/jythonservlet.py
瀏覽器將顯示 <h1> 標記中的 **Servlet Test**,就像 Java Servlet 輸出一樣。
Jython - JDBC
Jython 使用 **zxJDBC 包**,它提供了一個易於使用的 Python 包裝器,圍繞 JDBC。zxJDBC 連線了兩個標準:**JDBC** 是 Java 中資料庫訪問的標準平臺,而 **DBI** 是 Python 應用程式的標準資料庫 API。
ZxJDBC 為 JDBC 提供了一個符合 DBI 2.0 標準的介面。JDBC 可用 200 多個驅動程式,它們都適用於 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 聯結器** - https://dev.mysql.com.tw/downloads/connector/j/ 並將 mysql connector java-5.1.42-bin.jar 包含在 CLASSPATH 中。
登入到 MySQL 伺服器並在測試資料庫中建立一個學生表,其結構如下 -
| 欄位 | 型別 | 寬度 |
|---|---|---|
| 姓名 | Varchar | 10 |
| 年齡 | Int | 3 |
| 分數 | Int | 3 |
在其中新增一些記錄。
| 姓名 | 年齡 | 分數 |
|---|---|---|
| Ravi | 21 | 78 |
| Ashok | 20 | 65 |
| Anil | 22 | 71 |
建立以下 Jython 指令碼作為 **dbconnect.py**。
url = "jdbc:mysql:///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 - 使用 Swing GUI 庫
Jython 的主要功能之一是能夠在 JDK 中使用 Swing GUI 庫。標準 Python 發行版(通常稱為 CPython)附帶了 **Tkinter GUI 庫**。其他 GUI 庫,如 **PyQt** 和 **WxPython** 也可以與之一起使用,但 swing 庫提供了一個平臺無關的 GUI 工具包。
與在 Java 中使用 Swing 庫相比,在 Jython 中使用它要容易得多。在 Java 中,必須使用匿名類來建立事件繫結。在 Jython 中,我們可以簡單地傳遞一個函式來實現相同的目的。
基本頂級視窗是透過宣告 **JFrame 類** 的物件並將其 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** 分別派生自 Frame 和 Dialog 類,它們位於 AWT 庫中。其他 GUI 控制元件,如 **JLabel、JButton、JTextField** 等,都派生自 JComponent 類。
下圖顯示了 Swing 包類層次結構。
下表總結了 swing 庫中不同的 GUI 控制元件類 -
| 序號 | 類和描述 |
|---|---|
| 1 | JLabel JLabel 物件是一個用於在容器中放置文字的元件。 |
| 2 | JButton 此類建立一個帶標籤的按鈕。 |
| 3 | JColorChooser JColorChooser 提供了一個控制元件面板,旨在允許使用者操作和選擇顏色。 |
| 4 | JCheckBox JCheckBox 是一個圖形元件,可以處於 **開啟** (true) 或 **關閉** (false) 狀態。 |
| 5 | JRadioButton JRadioButton 類是一個圖形元件,可以處於開啟 (true) 或關閉 (false) 狀態。在一個組中。 |
| 6 | JList JList 元件向用戶顯示一個包含文字專案的滾動列表。 |
| 7 | JComboBox JComboBox 元件向用戶顯示一個專案的下拉列表 |
| 8 | JTextField JTextField 物件是一個文字元件,允許編輯單行文字。 |
| 9 | JPasswordField JPasswordField 物件是一個專門用於密碼輸入的文字元件。 |
| 10 | JTextArea JTextArea 物件是一個文字元件,允許編輯多行文字。 |
| 11 | ImageIcon ImageIcon 控制元件是 Icon 介面的實現,它從 Images 繪製 Icons |
| 12 | JScrollbar Scrollbar 控制元件表示一個捲軸元件,以便使用者能夠從值範圍內進行選擇。 |
| 13 | JOptionPane JOptionPane 提供了一組標準對話方塊,這些對話方塊提示使用者輸入值或通知他們某些事情。 |
| 14 | JFileChooser JFileChooser 控制元件表示一個對話方塊視窗,使用者可以在其中選擇檔案。 |
| 15 | JProgressBar 隨著任務向完成方向發展,進度條顯示任務的完成百分比。 |
| 16 | JSlider JSlider 允許使用者透過在有界區間內滑動旋鈕以圖形方式選擇值。 |
| 17 | JSpinner JSpinner 是一個單行輸入欄位,允許使用者從有序序列中選擇數字或物件值。 |
我們將在後續示例中使用其中一些控制元件。
Jython - 佈局管理
Java 中的佈局管理器是管理控制元件在容器物件(如 **Frame、Dialog** 或 **Panel**)中的放置的類。即使解析度發生變化或框架本身調整大小,佈局管理器也會維護控制元件在框架中的相對位置。
這些類實現了 **Layout 介面**。以下佈局管理器在 **AWT 庫** 中定義 -
- BorderLayout
- FlowLayout
- GridLayout
- CardLayout
- GridBagLayout
以下佈局管理器在 **Swing 庫** 中定義 -
- BoxLayout
- GroupLayout
- ScrollPaneLayout
- SpringLayout
我們將在以下示例中使用 AWT 佈局管理器以及 swing 佈局管理器。
- 絕對佈局
- 流佈局
- 網格佈局
- 邊框佈局
- 盒子佈局
- 組佈局
現在讓我們詳細討論每一個。
絕對佈局
在我們探索所有上述佈局管理器之前,我們必須檢視控制元件在容器中的絕對定位。我們必須將框架物件的佈局方法設定為“None”。
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 是容器類的預設佈局管理器。它從左到右,然後從上到下排列控制元件。
在下面的示例中,需要在使用 FlowLayout 管理器的 JFrame 中顯示一個 Jlabel 物件、一個 JTextField 物件和一個 JButton 物件。首先,讓我們從 **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)
現在,透過指定其維度為 4x4 來應用 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)))
最後將框架的可見性設定為 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 包**中定義。它用於在容器中垂直或水平排列元件。方向由以下常量確定 -
- 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()** 函式佔用佈局中的前導或尾隨空間。
首先,新增頂部和底部面板,並將框架的可見性屬性設定為 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。在它們之間,放置了一個並行組 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。新增三個按鈕的行並行組,然後垂直新增其餘兩個按鈕。
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 - 事件處理
Java Swing 中的事件處理要求控制元件(如 JButton 或 JList 等)應向相應的事件偵聽器註冊。事件偵聽器介面或相應的介面卡類需要實現或子類化,並覆蓋其事件處理方法。在 Jython 中,事件處理非常簡單。我們可以將任何函式作為控制元件對應事件處理函式的屬性傳遞。
讓我們首先了解如何在 Java 中處理點選事件。
首先,我們必須匯入 **java.awt.event 包**。接下來,擴充套件 JFrame 的類必須實現 ActionListener 介面。
public class btnclick extends JFrame implements ActionListener
然後,我們必須宣告 JButton 物件,將其新增到框架的 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 函式,它處理按鈕上的點選事件。
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 程式碼的輸出相同。當單擊按鈕時,它將在控制檯上列印“clicked”訊息。
在下面的 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”的分數,然後單擊“Add”按鈕。結果將相應顯示。
Jython JRadioButton 事件
JRadioButton 類在 **javax.swing 包**中定義。它建立具有開啟或關閉狀態的可選擇切換按鈕。如果在 ButtonGroup 中新增多個單選按鈕,則它們的選中狀態是互斥的。
在下面的示例中,兩個 JRadioButton 類物件和兩個 JLabels 新增到垂直 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 物件中,其 visible 屬性最終設定為“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 視窗中,其 visible 屬性最終設定為 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]
JList 和 JLabel 物件使用 BorderLayout 新增到 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 - 選單
大多數基於 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()
“檔案”選單物件被新增到選單欄中。最後,一個 JTextField 控制元件被新增到 JFrame 物件的底部。
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 直譯器執行上述指令碼時,將出現一個帶有“檔案”選單的視窗。單擊它,其三個選單項將展開。如果單擊任何按鈕,其名稱將顯示在文字框控制元件中。
Jython - 對話方塊
對話方塊物件是一個視窗,它顯示在使用者與其互動的基本視窗的頂部。在本章中,我們將看到 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() 處理程式函式檢索選單項按鈕的標題,並呼叫相應的 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 視窗中的文字框中顯示輸入文字。如果選擇了“確認”選項,則會出現一個帶有三個按鈕的對話方塊:是、否和取消。使用者的選擇將記錄在文字框中。
完整的程式碼如下所示 -
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)
當執行上述指令碼時,將顯示以下視窗,選單中有三個選項:
訊息框
輸入框
確認對話方塊