75、Jython GUI开发全解析

Jython GUI开发全面解析与示例

Jython GUI开发全解析

1. Jython GUI开发概述

在Jython中开发图形用户界面(GUI),主要的工具包是Java的抽象窗口工具包(AWT)和Swing类。这是因为Jython是用Java编写的,能很好地在Python语法中使用Java类。不过,AWT和Swing并非实现GUI的唯一选择,越来越多与其他工具包的绑定也允许Java和Jython使用这些工具包。

1.1 Java与Jython GUI对比

编写Jython GUI与Java非常相似,大多数Java GUI能轻松转换为Jython代码并按预期工作。以下是一个简单的Java GUI示例:

// file SimpleJavaGUI.java 
import java.awt.*; 
import java.awt.event.*; 

class SimpleJavaGUI implements ActionListener {
    private Button mybutton = new Button("OK"); 
    private Label mylabel = new Label("A Java GUI", Label.CENTER); 
    public SimpleJavaGUI() {
        Frame top_frame = new Frame(); 
        Panel panel = new Panel(); 
        top_frame.setTitle("A Basic Jython GUI"); 
        top_frame.setBackground(Color.yellow); 
        top_frame.addWindowListener(
            new WindowAdapter() {
                public void windowClosing(windowEvent e) {
                    System.exit(0); 
                } 
            }); 
        mybutton.addActionListener(this); 
        panel.add(mylabel); 
        panel.add(mybutton); 
        top_frame.add(panel); 
        top_frame.pack(); 
        Dimension winSz = Toolkit.getDefaultToolkit().getScreenSize(); 
        top_frame.setLocation(winSz.width/2 - top__frame.getWidth()/2, 
                              winSz.height/2 - top__frame.height()/2); 
        top_frame.setVisible(true); 
    } 
    public static void main(String[] args)) {
        SimpleJavaGUI s = new SimpleJavaGUI(); 
    } 
    public void actionPerformed(ActionEvent event) {
        System.exit(0); 
    } 
} 

将相同的GUI在Jython中实现,语法上有明显变化。Java的类型声明、访问修饰符、分号和大括号在Jython中不存在。例如,Java中按钮组件的实例化:

import java.awt.*; 
private Button mybutton = new Button("OK"); 

在Jython中变为:

from java import awt 
mybutton = awt.Button("OK") 

Jython会自动进行Java类型和Python类型之间的转换。例如, setVisible 方法需要Java布尔参数,Jython会将 PyInteger 的1转换为布尔值 true ,0转换为布尔值 false 。而且,Jython不需要使用 setVisible 方法,可直接将1赋值给 visible 属性。

以下是对应的Jython代码:

# File: simpleJythonGUI.py 
import java 
from java import awt 
def exit(e): 
    java.lang.System.exit(0) 
top_frame = awt.Frame(title="A Basic Jython GUI", 
                      background = awt.Color.yellow, 
                      windowClosing=exit) 
panel = awt.Panel() 
mylabel = awt.Label("A Jython GUI", awt.Label.CENTER) 
mybutton = awt.Button("OK", actionPerformed=exit) 
panel.add(mylabel) 
panel.add(mybutton) 
top_frame.add(panel) 
top_frame.pack() 
toolkit = awt.Toolkit.getDefaultToolkit() 
winSz = toolkit.screenSize 
top_frame.setLocation(winSz.width/2 - top__frame.size.width/2, 
                      winSz.height/2 - top__frame.height/2) 
top_frame.visible = 1 

1.2 Bean属性和事件

在介绍Jython的自动Bean属性之前,先回顾一下Bean的概念。Bean是遵循方法、属性和事件相关约定的类。Bean的方法是类中所有被指定为公共的方法,属性是通过 get set 方法操作的数据对象,事件通过 add remove 方法指定监听器对象来定义。

例如,以下Java类可看作“具有只读属性 name 的Bean A”:

public class A {
    private String name; 
    public String getName() {
        return name; 
    } 
} 

在Java中,会直接使用 getName() 方法来获取属性值:

import A; 
bean = new A(); 
String name = bean.getName(); 

而在Jython中,可以将 name 属性当作实例属性来访问:

>>> import A 
>>> b = A() 
>>> name = b.name 

对于 set 方法也是如此。Java中使用 setName 方法:

import A; 
A bean = new A(); 
bean.setName("new name"); 

在Jython中,只需进行属性赋值:

import A 
bean = A() 
bean.name = "new name" 

这种方式同样适用于事件。以下是Jython使用关键字参数在构造函数中设置组件属性的示例:

top_frame = awt.Frame(title="A Basic Jython GUI", 
                      background = awt.Color.yellow, 
                      windowClosing=exit) 
mybutton = awt.Button("OK", actionPerformed=exit) 

1.3 Bean属性的详细分析

Bean属性大多遵循一定的命名约定。例如,名为 extent 的Bean属性,其对应的访问器和修改器方法为 getExtent setExtent 。如果Java类中有一个名为 setAMultiWordName 的方法,Jython会自动添加一个名为 aMultiWordName 的Bean属性。

Bean属性可以是只读的(仅定义 get 方法)、只写的(仅定义 set 方法)或读写的(同时定义 get set 方法)。 get set 方法的签名需要相互匹配,否则会出现问题。例如,以下Java Bean的 setName 方法参数设置错误:

public class A {
    private String name = ""; 
    public String getName() {
        System.out.println("Getting name"); 
        return name; 
    } 
    public void setName(Object s) {
        name = (String)s; 
        System.out.println("Setting name"); 
    } 
} 

在Jython中使用该Bean时会出现错误:

>>> import A 
>>> b = A() 
>>> b.name 
Getting name 
'' 
>>> b.name = "this" 
Traceback (innermost last): 
  File "<console>", line 1, in ? 
AttributeError: read-only attr: name 

如果将类重写为具有正确匹配的签名:

public class A {
    private String name = "'; 
    public String getName() {
        System.out.println("Getting name"); 
        return name; 
    } 
    public void setName(String s) {
        name = s; 
        System.out.println("Setting name"); 
    } 
} 

在Jython中就能正常进行读写操作:

>>> import A 
>>> b = A() 
>>> b.name = "New name" 
Setting name 
>>> b.name 
Getting name 
'New name' 

Bean属性也可以是序列。要实现对序列的完整读写访问,需要四个访问器方法:
- setProperty([]) :设置整个序列
- setProperty(int, Object) :设置特定索引的值
- getProperty() :获取整个序列
- getProperty(int) :获取特定索引的值

但Jython的自动Bean属性只使用 getProperty() setProperty([]) 方法。以下是一个具有索引属性 items 的Java Bean:

// file: ItemBean.java 
public class ItemBean {
    private String[] data = {"A", "B", "C"}; 
    public ItemBean() { ; } 
    public String[] getItems(() {
        return data; 
    } 
    public String getItems(int i) {
        return data[i]; 
    } 
    public void setItems(String[] items)) {
        data = items; 
    } 
    public void setItems(int index, String item) {
        data[index] = item; 
    } 
} 

在Jython中与该属性的交互如下:

>>> import ItemBean 
>>> ib = ItemBean() 
>>> ib.items 
array(['A', 'B', 'C'], java.lang.String) 
>>> ib.items = ["1", "2", "3"] 

1.4 Bean属性和元组

Jython会自动将分配给Bean属性的元组解释为要设置的属性类型的构造函数。例如,分配给 background 属性的三元组会自动成为 Java.awt.Color 类的构造函数值,因为该Bean属性类型是 java.awt.Color ;分配给 bounds 属性的元组会自动成为 Rectangle 类型。

以下是Java和Jython代码的对比:

// In Java (pseudo-code) 
import java.awt.*; 
Frame f = new Frame(); 
Label L = new Label("This is a Label"); 
L.setBackground( new Color(50, 160, 40)); 
L.setForeground( new Color(50, 255, 50)); 
L.setFont(new Font("Helvetica Bold", 18, 24)); 
f.add(L); 
f.setVisible(true); 
# In Jython 
from java import awt 
f = awt.Frame() 
L = awt.Label("This is a Label", background=(50, 160, 40), 
              foreground=(50, 255, 50), font=("Helvetica Bold", 18, 24)) 
f.add(L) 
f.visible = 1 

1.5 Bean事件

Bean事件是通过 addEventListener removeEventListener 注册的事件。例如, java.awt.Window 类通过 addWindowListener 方法注册窗口事件,该方法需要一个实现 WindowListener 接口的类作为参数。

在Java中处理事件,需要添加一个实现相应事件监听器接口的类。例如,处理 windowClosing 事件,Java应用程序必须使用 addWindowListener 方法添加一个实现 WindowListener 接口的类或扩展一个这样的类,并实现 windowClosing 方法。Java也允许使用匿名内部类来满足接口要求。

而在Jython中,使用自动事件属性作为属性。可以将任何可调用的Jython对象分配给事件的Bean名称。例如,实现 windowClosing 事件,只需将一个可调用对象分配给容器的 windowClosing 属性:

>>> def wclose(e): 
...     print "Processing the windowClosing Event" 
...     e.getSource().dispose() 
... 
>>> def wopen(e): 
...     print "Processing the windowOpened Event" 
... 
>>> def wact(e): 
...     print "Processing the windowActivated event" 
... 
>>> import java 
>>> f = java.awt.Frame("Jython AWT Example") 
>>> f.windowClosing = wclose 
>>> f.windowOpened = wopen 
>>> f.windowActivated = wact 
>>> f.visible = 1 

所有事件属性分配也可以作为关键字参数包含在构造函数中:

f = java.awt.Frame("Jython AWT Example", windowOpened=wopen, 
                   windowClosing=wclose, windowActivated=wact) 

1.6 名称优先级

Jython支持实例方法、类静态字段、Bean属性和Bean事件属性,这可能会导致潜在的命名冲突。Jython通过分配优先级来解决名称冲突,优先级顺序如下:
1. 方法
2. 类静态属性
3. 事件属性
4. Bean属性

1.7 pawt包

Jython的 pawt 包为在Jython中使用AWT和Swing提供了一些便利模块,包括 GridBag colors test swing

1.7.1 GridBag

pawt.GridBag 类是一个包装类,用于帮助处理 java.awt.GridBagLayout java.awt.GridBagConstraints 。该类有两个方法: add addRow

以下是使用 pawt.GridBag 类简化布局设置的示例:

from java import awt 
import pawt 
top_frame = awt.Frame("GridBag frame") 
bag = pawt.GridBag(top_frame) 

pawt.GridBag 类的实例化可以选择接受关键字参数作为默认约束:

bag = pawt.GridBag(top_frame, fill="VERTICAL") 

使用 pawt.GridBag 类添加组件的示例:

from java import awt 
from pawt import GridBag 
pane = awt.Panel() 
bag = GridBag(pane, fill='HORIZONTAL') 
nameLabel = awt.Label("Name: ") 
nameField = awt.TextField(25) 
bag.add(nameLabel, anchor="WEST", fill="NONE", gridwidth=1) 
bag.addRow(nameField, anchor="WEST", fill="HORIZONTAL", gridwidth=3) 
1.7.2 colors

pawt.colors 模块定义了许多命名颜色,方便人们使用。例如, papayawhip 颜色比其RGB值 (255, 239, 213) 更容易记忆。要获取 pawt.colors 中定义的所有颜色列表,可以执行以下操作:

>>> import pawt 
>>> dir(pawt.colors) 
1.7.3 test

pawt 包中的 test 函数允许对图形组件进行简单测试。例如,测试按钮颜色:

>>> import java 
>>> import pawt 
>>> b = java.awt.Button("help", background=(212,144,100)) 
>>> pawt.test(b) 

test 函数还可以接受一个大小参数:

>>> from java.awt import Label 
>>> import pawt 
>>> L = Label("Test", background=(255,10,10), foreground=(10, 10, 100)) 
>>> pawt.test(L, (200,140)) 
1.7.4 pawt.swing

pawt.swing 模块有两个功能:选择适合JDK的Swing库,并提供一个专门用于Swing组件的测试函数。

以下是使用 pawt.swing 模块测试Swing组件的示例:

>>> import pawt 
>>> cb = pawt.swing.JCheckBox("Test Check Box") 
>>> myframe = pawt.swing.test(cb) 

1.8 开发流程总结

以下是使用Jython开发GUI的一般流程:
1. 选择工具包 :根据需求选择AWT或Swing工具包。
2. 创建组件 :使用相应工具包的类创建各种组件,如按钮、标签等。
3. 设置属性和事件 :利用Jython的自动Bean属性和事件属性,通过简单的属性赋值和函数分配来设置组件的属性和处理事件。
4. 布局管理 :使用合适的布局管理器来安排组件的位置,对于复杂的 GridBagLayout ,可以使用 pawt.GridBag 类简化操作。
5. 测试和调试 :使用 pawt.test 函数对组件进行简单测试,确保其功能正常。

1.9 工具和资源

  • 开发环境 :可以使用任何支持Python和Jython的集成开发环境(IDE),如PyCharm等。
  • 文档和教程 :Jython官方文档提供了详细的使用说明和示例,同时可以参考Java的AWT和Swing相关文档,加深对工具包的理解。

1.10 注意事项和其他补充说明

  • 类型转换 :虽然Jython会自动进行Java类型和Python类型之间的转换,但在处理一些特殊类型时,仍需要注意类型的匹配。
  • 命名冲突 :在使用Jython的自动Bean属性和事件属性时,要注意名称优先级,避免出现命名冲突导致的意外结果。
  • pawt.swing 模块的局限性 :该模块是一个动态模块,在编译Jython应用程序时可能会出现问题,因此在子类化Swing组件或编译应用程序时,建议直接使用 javax.swing

2. Jython GUI开发示例

2.1 简单AWT图形

以下示例展示了如何在 java.awt.Canvas paint 方法中绘制一个简单的横幅。该示例使用了Jython的自动Bean属性来设置画布的高度和宽度属性,以及图形的字体和颜色属性,还使用自动事件属性在 Frame 的构造函数中设置 windowClosing 事件。

# file: jythonBanner.py 
from java import awt 
import java 

class Banner(awt.Canvas): 
    def paint(self, g): 
        g.color = 204, 204, 204 
        g.fillRect(15, 15, self.width - 30, self.height - 30) 
        g.color = 102, 102, 153 
        g.font = "Helvetica Bold", awt.Font.BOLD, 28 
        message = ">>> Jython" 
        g.drawString(message, self.width // 2 - len(message) * 10, self.height // 2 + 14) 

top_frame = awt.Frame("Jython Banner", size=(350, 150), windowClosing=lambda e: java.lang.System.exit(0)) 
top_frame.add(Banner()) 
top_frame.visible = 1 

2.2 添加事件

下面的示例实现了一个极坐标图,当鼠标在图形画布上移动时,显示鼠标位置的半径(r)和角度(theta)坐标。该示例展示了如何使用 java.awt.event.MouseListener java.awt.event.MouseMotionListener 接口定义的鼠标事件,通过Jython的自动事件属性来处理这些事件。

# file: PolarGraph.py 
import java 
from java.lang import System 
from java import awt 
from java.lang import Math 

class Main(awt.Frame): 
    def __init__(self): 
        self.background = awt.Color.gray 
        self.bounds = 50, 50, 400, 400 
        self.windowClosing = lambda e: System.exit(0) 
        self.r = awt.Label("r:          ") 
        self.theta = awt.Label("theta:          ") 
        infoPanel = awt.Panel() 
        infoPanel.add(self.r) 
        infoPanel.add(self.theta) 
        self.graph = PolarCanvas() 
        self.add("North", infoPanel) 
        self.add("Center", self.graph) 
        self.visible = 1 
        self.graph.mouseMoved = self.updateCoords 

    def updateCoords(self, e): 
        limit = self.graph.limit 
        width = self.graph.width 
        height = self.graph.height 
        x = (2 * e.x * limit) // width - limit 
        y = limit - (2 * e.y * limit) // height 
        r = Math.sqrt(x ** 2 + y ** 2) 
        if x == 0: 
            theta = 0 
        else: 
            theta = Math.atan(Math.abs(y) / Math.abs(x)) 
        if x < 0 and y > 0: 
            theta = Math.PI - theta 
        elif x < 0 and y <= 0: 
            theta = theta + Math.PI 
        elif x > 0 and y < 0: 
            theta = 2 * Math.PI - theta 
        self.r.text = "r: %0.2f" % r 
        self.theta.text = "theta: %0.2f" % theta 

class PolarCanvas(awt.Canvas): 
    def __init__(self, interval=100, limit=400): 
        self.background = awt.Color.white 
        self.mouseReleased = self.onClick 
        self.interval = interval 
        self.limit = limit 
        self.points = [] 

    def onClick(self, e): 
        x = (2 * e.x * self.limit) // self.width - self.limit 
        y = self.limit - (2 * e.y * self.limit) // self.height 
        self.points.append(awt.Point(x, y)) 
        self.repaint() 

    def paint(self, g): 
        rings = self.limit // self.interval 
        step = (self.width // (rings * 2), self.height // (rings * 2)) 
        # Draw rings 
        for x in range(1, rings + 1): 
            r = awt.Rectangle(x * step[0], x * step[1], step[0] * (rings - x) * 2, step[1] * (rings - x) * 2) 
            g.color = (max(140 - x * 20, 10), max(200 - x * 20, 10), max(240 - x * 20, 10)) 
            g.fillOval(r.x, r.y, r.width, r.height) 
            g.color = awt.Color.black 
            g.drawOval(r.x, r.y, r.width, r.height) 
            g.drawString(str((rings * self.interval) - (x * self.interval)), r.x - 8, self.height // 2 + 12) 
        # draw center dot 
        g.fillOval(self.width // 2 - 2, self.height // 2 - 2, 4, 4) 
        # draw points 
        g.color = awt.Color.red 
        for p in self.points: 
            x = (p.x * self.width) // (2 * self.limit) + self.width // 2 
            y = self.height // 2 - (p.y * self.height) // (2 * self.limit) 
            g.fillOval(x, y, 4, 4) 

if __name__ == '__main__': 
    app = Main() 

2.3 图像显示

以下示例展示了如何在AWT框架中显示图像。该示例使用 awt.Toolkit.getDefaultToolkit().getImage 方法加载图像,并使用 awt.MediaTracker 确保图像完全加载后再进行绘制。

# file jyimage.py 
from java.lang import System 
from java import awt 

class jyimage(awt.Frame): 
    def __init__(self, im): 
        self.im = awt.Toolkit.getDefaultToolkit().getImage(im) 
        self.bounds = 100, 100, 200, 200 
        self.title = "Jython Image Display" 
        self.windowClosing = lambda e: System.exit(0) 
        mt = awt.MediaTracker(self) 
        mt.addImage(self.im, 0) 
        mt.waitForID(0) 
        self.addNotify() 
        i = self.insets 
        self.resize(self.im.width + i.left + i.right, self.im.height + i.top + i.bottom) 

    def paint(self, g): 
        g.drawImage(self.im, self.insets.left, self.insets.top, self) 

if __name__ == '__main__': 
    f = jyimage("jython-new-small.gif") 
    f.visible = 1 

2.4 菜单和菜单事件

在Jython中添加菜单和处理菜单事件非常简单。以下示例展示了如何创建菜单并为菜单项分配操作。

# file: jythonmenus.py 
from java import awt 
from java.awt import event 
from java.lang import System 

menus = [
    ('File', ['New', 'Open', 'Save', 'Saveas', 'Close']), 
    ('Edit', ['Copy', 'Cut', 'Paste']) 
] 

class MenuTest(awt.Frame): 
    def __init__(self): 
        bar = awt.MenuBar() 
        for menu, menuitems in menus: 
            menu = awt.Menu(menu) 
            for menuitem in menuitems: 
                method = getattr(self, 'on%s' % menuitem) 
                item = awt.MenuItem(menuitem, actionPerformed=method) 
                menu.add(item) 
            bar.add(menu) 
        self.menuBar = bar 
        self.windowClosing = lambda e: System.exit(0) 
        self.eventLabel = awt.Label("Event: ") 
        self.bounds = 100, 100, 200, 100 
        self.add(self.eventLabel) 

    def onNew(self, e): 
        self.eventLabel.text = "Event: onNew" 

    def onOpen(self, e): 
        self.eventLabel.text = "Event: onOpen" 

    def onSave(self, e): 
        self.eventLabel.text = "Event: onSave" 

    def onSaveas(self, e): 
        self.eventLabel.text = "Event: onSaveas" 

    def onClose(self, e): 
        self.eventLabel.text = "Event: onClose" 
        System.exit(0) 

    def onCopy(self, e): 
        self.eventLabel.text = "Event: onCopy" 

    def onCut(self, e): 
        self.eventLabel.text = "Event: onCut" 

    def onPaste(self, e): 
        self.eventLabel.text = "Event: onPaste" 

f = MenuTest() 
f.visible = 1 

2.5 拖放功能

在Jython中实现拖放(DnD)功能与Java类似,需要实现 DragGestureListener DragSourceListener DropTargetListener 接口。以下示例展示了如何实现两个列表之间的拖放功能。

# file: ListDnD.py 
from java import awt 
from java.awt import dnd 
from java.lang import System 
from java.awt import datatransfer 

class JythonDnD(awt.Frame, dnd.DragSourceListener, dnd.DragGestureListener): 
    def __init__(self): 
        self.title = "Jython Drag -n- Drop Implementation" 
        self.bounds = 100, 100, 300, 200 
        self.windowClosing = lambda e: System.exit(0) 
        self.draglist = awt.List() 
        list(map(self.draglist.add, ["1", "2", "3", "4", "5"])) 
        self.droplist = droplist([]) 
        self.dropTarget = dnd.DropTarget(self, dnd.DnDConstants.ACTION_COPY_OR_MOVE, self.droplist) 
        self.layout = awt.GridLayout(1, 2, 2, 2) 
        self.add(self.draglist) 
        self.add(self.droplist) 
        self.dragSource = dnd.DragSource() 
        self.recognize = self.dragSource.createDefaultDragGestureRecognizer(
            self.draglist, 
            dnd.DnDConstants.ACTION_COPY_OR_MOVE, 
            self 
        ) 

    def dragGestureRecognized(self, e): 
        item = self.draglist.getSelectedItem() 
        e.startDrag(self.dragSource.DefaultCopyDrop, datatransfer.StringSelection(item), self) 

    def dragEnter(self, e): 
        pass 

    def dragOver(self, e): 
        pass 

    def dragExit(self, e): 
        pass 

    def dragDropEnd(self, e): 
        pass 

    def dropActionChanged(self, e): 
        pass 

class droplist(awt.List, dnd.DropTargetListener): 
    def __init__(self, datalist): 
        list(map(self.add, datalist)) 
        self.dropTarget = dnd.DropTarget(self, 3, self) 

    def drop(self, e): 
        transfer = e.getTransferable() 
        data = transfer.getTransferData(datatransfer.DataFlavor.stringFlavor) 
        self.add(data) 
        e.dropComplete(1) 

    def dragEnter(self, e): 
        e.acceptDrag(dnd.DnDConstants.ACTION_COPY_OR_MOVE) 

    def dragExit(self, e): 
        pass 

    def dragOver(self, e): 
        pass 

    def dropActionChanged(self, e): 
        pass 

win = JythonDnD() 
win.visible = 1 

2.6 Swing应用

使用Swing类开发GUI与使用AWT类似,Jython的自动Bean属性和事件属性同样适用于Swing组件。以下示例展示了如何创建一个简单的Swing树显示。

# file: SwingTree.py 
from javax import swing 
from javax.swing import tree 
import sys 

top_frame = swing.JFrame("A Simple Tree in Jython and Swing", 
                         windowClosing=lambda e: sys.exit(0), 
                         background=(180, 180, 200)) 
data = tree.DefaultMutableTreeNode("Root") 
data.add(tree.DefaultMutableTreeNode("a leaf")) 
childNode = tree.DefaultMutableTreeNode("a node") 
childNode.add(tree.DefaultMutableTreeNode("another leaf")) 
data.add(childNode) 
t = swing.JTree(data) 
t.putClientProperty("JTree.lineStyle", "Angled") 
top_frame.contentPane.add(t) 
top_frame.bounds = 100, 100, 200, 200 
top_frame.visible = 1 

2.7 总结

通过以上示例可以看出,Jython在GUI开发中具有很多优势:
- 语法简洁 :Jython的语法比Java更简洁,减少了代码量,提高了开发效率。
- 自动属性和事件处理 :利用自动Bean属性和事件属性,使属性设置和事件处理更加简单直观。
- 与Java集成 :由于Jython基于Java,能够很好地与Java的AWT和Swing工具包集成,充分利用Java的强大功能。

2.8 常见问题及解决方案

问题 解决方案
类型转换问题 虽然Jython会自动进行类型转换,但在处理特殊类型时,需要手动确保类型匹配。
命名冲突 注意Jython的名称优先级,避免因命名冲突导致意外结果。
pawt.swing 模块问题 在子类化Swing组件或编译Jython应用程序时,直接使用 javax.swing

2.9 未来趋势和发展方向

随着Python和Java技术的不断发展,Jython在GUI开发领域有望继续发挥重要作用。未来可能会有更多的工具和库支持Jython,进一步简化开发流程,提高开发效率。同时,随着跨平台开发需求的增加,Jython的跨平台特性将使其在多平台GUI开发中更具优势。

2.10 流程图:Jython GUI开发流程

graph LR
    A[选择工具包] --> B[创建组件]
    B --> C[设置属性和事件]
    C --> D[布局管理]
    D --> E[测试和调试]

2.11 总结表格

开发内容 关键点
简单AWT图形 使用 Canvas paint 方法,利用自动Bean属性设置图形属性。
添加事件 利用自动事件属性处理鼠标事件,如 mouseMoved mouseReleased
图像显示 使用 Toolkit 加载图像, MediaTracker 确保图像加载完成。
菜单和菜单事件 通过 MenuBar MenuItem 创建菜单,使用 getattr 方法绑定事件处理函数。
拖放功能 实现 DragGestureListener DragSourceListener DropTargetListener 接口。
Swing应用 与AWT开发类似,利用自动Bean属性和事件属性简化开发。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值