使用Eclipse进行SWT编程

使用Eclipse进行SWT编程

1. 为什么要使用SWT?

SWTIBM开发一套跨平台的GUI开发框架。为什么IBM要创建另一种GUI呢?为什么他们不使用现有的Java GUI框架呢?要回答这些问题,我需要回到Java的早期时代。

Sun已经创建了一套跨平台的GUI框架 AWT (Abstract Windowing Toolkit) 这个AWT框架使用了本地窗口组件(native widgets)不过它存在LCD问题. 这个LCD问题导致了它失去主要的平台特性。换句话说,如果平台A有窗口组件140而平台B有窗口组件2025,那么这个跨平台的AWT框架只能提供这两个集合的交集。

为了解决这个问题,Sun创建了一个新的框架使用模拟窗口组件(emulated widgets)来代替本地窗口组件(native widgets)。这个方法解决了LCD问题同时提供了丰富的窗口组件,不过也产生了其他的问题。例如,Swing应用程序不再和本地程序在样子上一致。虽然JVM有了很大的改善, 但是Swing应用程序仍然存在它们本地配对物所没有的性能问题。而且,Swing应用程序消耗了太多的内存,故不适合用于PDA和移动电话等小型设备。

IBM发现这些方法都无法满足他们的需求。因此,IBM创建了新的GUI库叫做SWT,它解决了AWTSwing框架中的问题。SWT框架使用JNI访问本地窗口组件(native widgets),如果一个窗口组件在主机平台上不能获得,那么SWT会模拟这个不能获取的窗口组件。

2. 一个SWT应用程序的基础材料

Display, ShellWidgets是一个SWT应用程序的基础材料。Displays用于管理事件循环(event loops)和控制UI线程和其他线程之间的通讯。Shell是应用程序中由操作系统窗体管理器来管理的窗体。任何SWT应用程序都需要至少一个Display实例和1个或更多的Shell实例。

1.不同视角看的SWT程序

1 说明了一个SWT应用程序的不同看法。第一幅图是简化的UI对象的继承图。第二幅图是UI对象的包含结构。第三幅图就是创建了的UI

如果一个应用程序使用多个线程,每个线程使用自己的Display对象实例。那么你可以通过使用静态的Display.getCurent()方法得到当前活跃的Display对象实例。

一个Shell表示一个特别操作系统中的一个窗口。一个Shell可以最大化,正常化,和最小化。有两种类型的shell。一种是顶层(top-levelShell作为Display的主窗口创建的,另一种是依赖于其他shell的对话shell

Shell的类型是由传给Shell构造函数的style位决定的。Shell的默认值是对话Shell。也就是说,如果没有传递任何值给构造函数参数,那么创建的是默认的对话Shell。如果一个Display对象作为参数,那么它是顶层(top-levelShell

有些窗口组件(widget)的属性必须在创建时设定。这些窗口组件(widget)属性叫做style bitsStyle bits是在SWT类中定义的常量。如Button button = new Button( shell, <styleBits> )。当然可以通过或操作|来使用多个style bit。例如,要使用一个有边的按钮,你需要使用SWT.PUSH | SWT.BORDER作为style bit参数。

3. 环境设置

开发一个SWT应用程序与开发一个Swing应用程序不同。为了可以开始一个SWT应用程序的开发,你需要把SWT库加到classpath中,同时设置好对应的必要的环境变量。

第一个需要的库是swt.jar文件,它位于ECLIPSE_HOME/eclipse/plugins/org.eclipse.swt.win32_2.1.0/ws/win32目录。根据你使用的Eclipse版本,你可能需要使用不同的目录。这个swt.jar文件必须加到你的classpath中,为此到Project->Properies->JavaBuildPath->Libraries->Add Variable -> Eclipse Home ->Extend并按上述路径选择swt.jar库,然后单击OK

然后,你可以编译SWT应用程序,但是由于抛出下边所示的运行时异常,无法运行它,因为swt.jar使用了本地库。你需要设置java.library.path环境变量来在Java中使用本地库。

Console output

java.lang.UnsatisfiedLinkError: no swt-win32-2133 in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1403)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:832)
...
at org.eclipse.swt.widgets.Display.<init>(Display.java:287)
at Main.main(Main.java:25)
Exception in thread "main"

要设置java.library.path变量,Run-> Run...-> Java Applicaton-> New ->Arguments -> VM Arguments。然后,如何需要,如下修改path,把它粘贴到VM Arguments部分。-Djava.library.path=c:/eclipse/plugins/org.eclipse.swt.win32_ 2.1.0 /os/win32/x86

装载本地库

如果你需要装载应用程序使用的任何本地库,你可以使用Runtime.getPlatform.loadLibrary("libraryname")方法。

完成这些步骤,你就可以在你的eclipse环境下运行SWT程序了。

4. 你的第一个SWT应用程序

创建一个典型的SWT应用程序需要一下步骤:

  • 创建一个Display
  • 创建一个或多个Shells
  • 设置ShellLayout manager
  • 创建Shell中的widgets
  • 开启Shell窗口
  • 写一个事件转发循环
  • 销毁display

你可以使用下边的代码模板来快速的运行本文中的代码片断。你可以复制粘贴这些代码至合适的区域。如源代码1所示:

源代码 1. SWT应用程序模板

import org.eclipse.swt.layout.RowLayout;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

 

public class SliderExample

{

  public static void main(String args[])

  {

 Display display = new Display();

 Shell shell = new Shell(display);

 shell.setLayout( new RowLayout());

    // ------------------------

    // Your code comes to here.

    // ------------------------

    shell.pack();

 shell.open();

 while( !shell.isDisposed())

    {

      if(!display.readAndDispatch())

      display.sleep();

    }

 display.dispose();

  }

}

这个例子显示了一个空的窗口。你可以加widget到上边的模板。任何SWT应用程序需要 一个Display和一个或多个 Shells。这个Shell是个合成对象;它可以容纳其他的合成对象。如果没有设置shell layout,加到Shellwidget是不能看见的。Shell窗口必须 打开才能显示。 事件处理循环读取并转发GUI事件。如果没有事件处理循环应用程序窗口是无法显示的。即使通过open()方法来打开Shell窗口。让后,需要在Shell被丢弃的时候销毁 Display

 

导入需要的库

你可以使用Source->Organize Imports菜单或者Ctrl+Shift+O来自动导入需要的库。

5. Eclipse外运行SWT应用程序

要在不使用Eclipse的环境下运行SWT应用程序,swt.jar库必须在classpath,并且java.library.path环境变量必须正确设置。根据主机平台,必须有合适的本地库存在。对于Windows平台,你可以根据如下来完成本地库的配置:

  1. swt.dll放在和程序相同的文件夹下。
  2. swt.dll放在JAVA_HOME/bin/文件夹下。
  3. swt.dll放在c:/windows/system32文件夹下。

javac -classpath c:/swt/swt.jar HelloWorld.java
Java -classpath c:/swt/swt.jar;. -Djava.library.path=c:/swt HelloWorld
java.library.path
JNI必需的环境变量。如果你没有设置这个环境变量。你的DLL 类是不能访问的。在这种情况下,应用程序不能正常的运行,并会抛出异常。

SWT

Swt库存在于Eclipseplug-in目录下。如果你想不下载整个Eclipse包而获得SWT库,你可以在http://www.eclipse.org/downloads目录下单独下载这个SWT库。

6. SWT包(Packages

SWT主要由下列包组成。这些包的定义是从EclipseAPI文档上得到的。你可以在Eclipse的网站上获得整个API文档。
org.eclipse.swt:
包含了定义了SWT需要使用的常量和异常的类。这个包由三个类组成:SWT, SWTExceptionSWTErrorSWT类可能是最受欢迎的类,因为它包含了SWT库所需要的常量如键盘、错误、颜色、布局、文本样式、按钮等常量。
org.eclipse.swt.widgets:
包含了大多数核心SWT窗口组件,包括支持的接口和类。
org.eclipse.swt.events:
定义了SWT组件使用的typed events, listenersevents。这个包有三组不同的类:Listener接口,Adapter类和Event类。
org.eclipse.swt.dnd:
包含了对SWT窗口组件拖放(drag-and-drop)支持的类。
org.eclipse.swt.layout:
包含了提供对SWT窗口组件自动安置和大小控制的类。
org.eclipse.swt.print:
包含了对SWT窗口组件提供打印支持的类。
org.eclipse.swt.graphics:
这个包提供了实现基本绘图操作需要的点,长方形、区域,颜色,光标,字体,图像上下文(GC)等的类和包含了显示图像代码和载入/保存他们的公有API的图像类。

7. 对话框

对话框的实现是本地的。也就是说,对话框像窗口组件一样是平台组件。SWTDialogs是从Dialog抽象类继承的。对话框不是窗口组件但是他可以容纳窗口组件。

2. Dialog类层次图.

SWT有不同类型的对话框。有些对话框具有特殊的属性。Dialog类可以如源代码 2中使用

源代码2. MessageBox例子

MessageBox messageBox =

  new MessageBox(shell, SWT.OK|SWT.CANCEL);

if (messageBox.open() == SWT.OK)

{

  System.out.println("Ok is pressed.");

}

每个对话框的open()方法返回不同的类型。例如, MessageBox对话框从open()方法返回int类型。因此,需要编写不同的条件来处理每一个对话框的返回值。

ColorDialog显示一个色彩选择调色板。它从return方法返回一个RGB对象。

DirectoryDialog使你可以选择一个目录。它从open()方法返回一个字符串。返回值就是选择的目录。当然,也可以设置额外的过滤器来过滤有些目录。

FontDialog使用户能够从系统所有的字体中选择一种字体。它从open()方法返回一个FontData对象。

FileDialog使用户能够选择一个文件。另外,可以设置扩展名过滤器,路径过滤器和文件名过滤器。对话框有如表1所示的样式:

1. SWT对话框style bit常量

SWT.OPEN

Shows Open button in the dialog

SWT.SAVE

Shows Save button in the dialog

PrintDialog使用户在打印之前选择打印机。它从open()方法返回一个PrinterData对象。

MessageBox用于给用户回馈信息。你可以使用或(|)操作来联合不同的样式,如源代码3所示:

源代码3. MessageBox例子

 MessageBox messageBox =

   new MessageBox(shell,

    SWT.OK|

    SWT.CANCEL|

    SWT.ICON_WARNING);

 messageBox.setMessage("www.korayguclu.de");

 messageBox.open();

3就是上边例子的运行消息框。

3. MessageBox对话框

可用的按钮常量如下所列。使或操作可以完成不同按钮的联合。SWT框架按照style bits创建对话框。按钮常量有:SWT.ABORT SWT.OK SWT.CANCEL SWT.RETRY SWT.IGNORESWT.YESSWT.NO

2 显示了对话框可以使用的图标。

2. SWT图标style bit常量

SWT.ICON_ERROR

SWT.ICON_INFORMATION

SWT.ICON_QUESTION

SWT.ICON_WARNING

SWT.ICON_WORKING

 

8. Widgets

SWT GUI对象是从WidgetControl类继承而来的。Widget对象是基类定义了GUI类的通用方法。Control类是所有窗口GUI类的基类也就是说从Control类继承的组件需要一个窗口或者对话框来显示。

Menu对象也需要一个窗口来显示,但是这个需求间接得到了满足。一个Menu对象需要一个Control对象。

4. Widget类层次图

4 显示了Widget的类层次图。WidgetItemScrollBarControl类是抽象类。

8.1. Widget事件

Widget事件总结表3。简化起见,表中只包含了事件名称。我们可以很容易的使用<EventName>Event 想出事件类的名称。同样地,使用<Listener Name>Listener得到相关联地Listener地名称。并不是每一事件都有相配地Adapter类。所以,有adapter地事件用粗体表明。我们可以通过<EventName>Adaptor 来得到对应地adapter名字。
例子:
事件名称是Control,事件类就是ControlEventlistener类是ControlListeneradaptor 类是ControlAdaptor

3. SWT Events

事件名称

窗口组件

产生的时间

Arm

MenuItem

一个菜单项加亮时

Control

Control, TableColumn, Tracker

一个控件被改变大小或者移动时

Dispose

Widget

窗口组件被销毁时

Focus

Control

一个控件得到或者失去焦点时

Help

Control, Menu, MenuItem

用户需要帮助时(例如按F1)

Key

Control

当控件得到键盘焦点并且一个键按下或者释放时

Menu

Menu

菜单显示或者隐藏时

Modify

Combo, Text

窗口组件的文本被修改时

Mouse

Control

在控件范围内鼠标被按下,释放或者双击时

MouseMove

Control

鼠标越过控件

MouseTrack

Control

鼠标进入,离开或者盘旋在控件上方

Paint

Control

控件需要被重绘时

Selection

Button, Combo, CoolItem, List, MenuItem, Sash, Scale, ScrollBar, Slider, StyledText, TabFolder, Table, TableColumn, TableTree, Text, ToolItem, Tree

一个Item在控件中被选择时

Shell

Shell

Shell被最小化,最大化,激活,钝化或者关闭时

Traverse

Control

控件被遍历(tabbed)

Tree

Tree, TableTree

一个tree item被收缩或者展开时

Verify

Text, StyledText

窗口组件的文本将要被修改时

8.2. 有用的窗口组件

5. Control类层次图

所有的Control类都可以有边框。你可以使用SWT.BORDER常量来给控件类增加边框。

SWT style常量

一般都需要标明样式常量 (style bit).如果你不知道用哪个常量或者你不想要标明它,你可以使用SWT.NULL

8.2.1 . 按钮

按钮可以具有不同的样式。按钮的样式由style bit决定。表4显示了按钮列表和他们的样式常量。

Table 4. SWT按钮style bit常量和例子

常量

例子

描述

SWT.ARROW

一个按钮用于显示弹出对话框。箭头的方向由alignment常量决定。

SWT.CHECK

选择框,可以是图像。

SWT.PUSH

一个按钮

SWT.RADIO

group中可以使用的单选按钮

SWT.TOGGLE

SWT.PUSH类似, 但是它可以保持按下状态直到第二次单击。

 

8.2.2 . 滑块(Slider, 标尺(Scale)和进度条(ProgressBar)窗口组件

标尺(Scale)表示一段可选择的连续值。范围可以用Scale类的setMinimum() setMaximum()方法设定。并可以使用getSelection()方法得到所选择的值。标尺在一次只有一个选择的值。也就是说,没有多选的可能。

6. 包含在一起的滑块和标尺

根据传递给构造函数的参数值的不同,我们可以创建不同的滑块和标尺。滑块和标尺常量如表5所示:

5. SWT滑块和标尺的样式常量

SWT.HORIZONTAL
SWT.VERTICAL

显示水平或者垂直组件

随意地,你可以使用SWT.BORDER常量来在标尺周围创建边框。这个常量对滑块没有作用。

 Source 4. Slider widget example

 final Slider slider =   new Slider(shell,SWT.VERTICAL);

 slider.setMinimum(0);

 slider.setMaximum(100);

 slider.setIncrement(5);

 slider.setPageIncrement(10);

 slider.setSelection(25);

 slider.addSelectionListener(

  new SelectionAdapter()

  {

    public void widgetSelected(SelectionEvent e)

    {

      System.out.println("Selection:"+ slider.getSelection());

    }

  }

 );

进度条组件类似于滑块和标尺组件,但是它不能被选择。它用于显示一个任务的进度。你可以对进度条组件使用SWT.SMOOTH and SWT.INTERMINATE常量。

8.2.3 . 文本窗口组件

一个文本窗口组件可以用于显示或者编辑文本。另外,你可以使用StyledText窗口组件来用不同的字体和颜色显示文本。StyledText窗口组件允许设置前景、背景色和指定范围文本块的字体。

7. Text窗口组件

我们可以使用6所列的常量来创建Text窗口组件。因此,SWT.H_SCROLLSWT.V_SCROLL常量可用于对Text窗口组件增加滚动条。

6. SWT Text style bit常量

SWT.MULTI
SWT.SINGLE

显示单行还是多行窗口组件

SWT.READ_ONLY

创建只读的组件

SWT.WRAP

文本自动换行

源代码 5是一个简单的使用Text组件的例子.

Source 5. Text widget example

 Text text =

   new Text(shell, SWT.MULTI|SWT.WRAP);

8.2.4 . 列表(List)窗口组件

List窗口组件可用于显示可选择的字符串列表。在选择的情况下,List对象会发送事件通告给它的listeners。这种类型的选择可以是单选,也可以是多选。选择的类型是由SWT.SINGLESWT.MULTI常量决定的。List窗口组件是可滚动的组件。因此SWT.H_SCROLLSWT.V_SCROLL常量可用于给Text窗口组件增加滚动条。

8. List 窗口组件

下边的代码片断显示了一个简单的List窗口组件。

Source 6. List example

 final List list = new List(shell,SWT.MULTI);

 for (int i = 1; i < 11; i++)

 {

   list.add(i+".)www.korayguclu.de");

 }

 list.addSelectionListener(

   new SelectionAdapter()

   {

     public void widgetSelected(SelectionEvent e)

     {

       List list = (List) e.getSource();

       String[] str = list.getSelection();

       for (int i = 0; i < str.length; i++)

       {

         System.out.println("Selection: "+str[i]);

       }

     }

  }

 );

8.2.5 . 窗框组件

窗框组件可用于在可改变的区域里显示组合窗口组件。下图就是一个窗框组件例子。

9. 窗框组件

下边是一个基本的窗框组件例子:

Source 7. Sash example

 Button button = new Button(shell,SWT.PUSH);

 Sash sash = new Sash(shell, SWT.VERTICAL);

 Button button1 = new Button(shell,SWT.PUSH);

 

8.3. 组合窗口组件Composite Widgets

组合窗口组件可以容纳其他的组合窗口组件。Composite类是组合窗口组件的父类。

10. Composite可以容纳其他的组合类

组合类可以容纳其他的组合类。这种容纳关系是用一个组合窗口组件类的构造函数来建造的。与Swing相比,SWT没有add() 方法;作为代替,你必须使用构造函数来建立包容关系结构。

正如图10中所看到的,Shell类也是一个组合类。也就是说,Shell对象,可以容纳其他的组合类。

组合类是可以卷起的,也就是说可以使用SWT.H_SCROLLSWT.V_SCROLL常量给组合窗口组件加上滚动条。

8.3.1 . Table窗口组件

Table窗口组件可以显示一批字符串项或者图片。与其他的组合窗口组件相比,不能给table窗口组件增加组合控件。Table窗口组件的子构件必须是TableItem类型的。

11. Table窗口组件

7中的常量可以用于table窗口组件

7. SWT Table style bit常量

SWT.MULTI
SWT.SINGLE

使能够进行单一或者多项选择

SWT.FULL_SELECTION

使能够进行行全选

SWT.CHECK

在每一行的开始显示一个选择框

源代码 8 中的代码片断表明了含有两列的table组件的使用方法

源代码 8. Table窗口组件例子

  final Table table =

    new Table(shell,SWT.SINGLE);

  TableColumn col1  =

    new TableColumn(table,SWT.LEFT);

  col1.setText("Coloumn 1");

  col1.setWidth(80);

  TableColumn col2  =

    new TableColumn(table,SWT.LEFT);

  col2.setText("Coloumn 2");

  col2.setWidth(80);

 

  TableItem item1 = new TableItem(table,0);

  item1.setText(new String[]{"a","b"});

  TableItem item2 = new TableItem(table,0);

  item2.setText(new String[]{"a","b"});

 

  table.setHeaderVisible(true);

  table.setLinesVisible(true);

8.3.2 . Combo(组合框)窗口组件

Combo窗口组件允许用户从值列表中选择一个值或者随意输入一个新值。组合框(combo)类似于列表组件,却使用了有限的空间。

虽然组合框是组合性质的,但是对它增加子元素是没有意义的。它的元素必须是String类型。一元素可以使用Combo类中定义的add(String element)方法来添加到组合框中。

     

12. 不同样式的组合框

下边的SWT常量可以用于Combo窗口组件:

Table 8. SWT Combo style bit constants

SWT.DROP_DOWN

下拉式组合框

SWT.READ_ONLY

只读组合框

SWT.SIMPLE

简单的组合框(非下拉式组合框)。如图11所示

下边的例子说明了Combo组件的使用:

Source 9. Combo example

 final Combo combo =

   new Combo(shell,SWT.DROP_DOWN);

 for (int i = 1; i < 11; i++)

 {

   combo.add(i+".) element ");

 }

 combo.setText("Text");

 combo.addSelectionListener(

  new SelectionAdapter()

  {

    public void widgetSelected(SelectionEvent e)

    {

      System.out.println("Selection:"+

                         combo.getText());

    }

  }

 );

8.3.3 . Tree窗口组件

Tree窗口组件描绘了树中项的可选择层次结构。虽然Tree类是组合的,但是不能对它增加组合类对象。Tree类的子项必须是ThreeItem类型。

     

13. 不同样式的Tree窗口组件

下表是Tree组件常量的列表。

9. SWT Tree style bit 常量

SWT.SINGLE
SWT.MULTI

允许单选或者多选

SWT.CHECK

在每个节点的开始显示一个选择框。

下边是一个简单的Tree组件例子。

源代码 10. Tree例子

 final Tree tree =

   new Tree(shell,SWT.SINGLE);

 for (int i = 1; i < 11; i++)

 {

   final TreeItem item1  =

    new TreeItem(tree,SWT.NULL);

   item1.setText("node "+i);

   for (int j = 1; j < 6; j++)

   {

     final TreeItem item11 =

      new TreeItem(item1,SWT.NULL);

     item11.setText("node "+i+"."+j);

   }

 }

 

 tree.addSelectionListener(

  new SelectionAdapter()

  {

   public void widgetSelected(SelectionEvent e)

   {

     System.out.println("Selection:"+

                   tree.getSelection()[0]);

   }

  }

 );

 

8.3.4 . TabFolder

TabFolder组件允许用户从一些页面中选择一页。虽然它是组合的,但是它不能增加其他的组合窗口组件。加到TabFolder的组件必须是TabItem类型。Tab的内容可以使用TabItemsetControl(Control control) 方法来设置。

14. TabFolder窗口组件

一个简单的TabFolder例子:

源代码 11. TabFolder例子

 final TabFolder tabFolder =

   new TabFolder( shell, SWT.BORDER);

 for (int i=1; i<5; i++)

 {

   // create a TabItem

   TabItem item =

     new TabItem( tabFolder, SWT.NULL);

   item.setText( "TabItem " + i);

   // create a control

   Label label  =

     new Label( tabFolder, SWT.BORDER);

   label.setText( "Page " + i);

   // add a control to the TabItem

   item.setControl( label );

 }

8.3.5 . CoolBar窗口组件

CoolBar窗口组件提供了一个可以在动态摆放空间上增加项的区域。你可以增加一个或多个ToolBar组件到CoolBar上。一个CoolBar可一容纳一个或多个CoolItems。虽然是一个组合窗口组件,但是不能把其他组合类加到它上。CoolBar的子元素必须是CoolItem类型。

15. Coolbar窗口组件

CoolBar窗口组件使用的例子:

Source 12. CoolBar example

  CoolBar coolBar =

    new CoolBar(shell, SWT.BORDER);

  coolBar.setLayoutData(

    new FillLayout());

  // create a tool bar which it

  // the control of the coolItem

  for (int k = 1; k <3; k++)

  { 

    ToolBar toolBar =

      new ToolBar(coolBar, SWT.FLAT);

    for (int i = 1; i < 5; i++)

    {

      ToolItem item =

        new ToolItem(toolBar, SWT.NULL);

      item.setText("B"+k+"."+i);

    }

    // Add a coolItem to a coolBar

    CoolItem coolItem =

      new CoolItem(coolBar, SWT.NULL);

    // set the control of the coolItem

    coolItem.setControl(toolBar);

    // You have to specify the size

    Point size =

      toolBar.computeSize( SWT.DEFAULT,

                           SWT.DEFAULT);

    Point coolSize =

      coolItem.computeSize (size.x, size.y);

    coolItem.setSize(coolSize);

  }

8.4. 具有子项控件的概述

有些控件接受子组件作为子项。如,一个组合组件接受组合组件。有些组件只需要item(项)这样的组件如表10所列:

10. 有项的组件

窗口组件

描述

CoolBar

CoolItem

项是可选择的,动态的摆放在CoolBar的区域上。

Menu

MenuItem

项是菜单下的选择。

TabFolder

TabItem

项是TabFolder中的Tab

Table

TableItem
TableColumn

项是表中的行。

ToolBar

ToolItem

项是工具栏上的按钮。

Tree

TreeItem

项是树上的节点。

结论

SWTEclipse用户接口的核心部分。Eclipse平台基于SWT库。要扩展你的SWT知识,你可以下载SWT网站上的SWT例子。

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值