SWT编程基础-Display和Shell

Display和Shell

首先我们来看一段代码:

package com.gujin.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class HelloSWT
{
   public static void main(String[] args)
   {
      Display display = Display.getDefault();
      Shell shell = new Shell(display);
      Label hello = new Label(shell, SWT.NONE);
      hello.setBounds(10, 10, 100, 30);
      hello.setText("Hello SWT");
      shell.open();
      shell.pack();
      while (!shell.isDisposed())
      {
         if (!display.readAndDispatch())
         {
            display.sleep();
         }
      }
      display.dispose();
   }
}

这是一段很简单的示例代码,我们可以将其分为三个部分:
第一部分:创建Display对象

Display display = Display.getDefault();

第二部分:创建并配置Shell

Shell shell = new Shell(display);
Label hello = new Label(shell, SWT.NONE);
hello.setBounds(10, 10, 100, 30);
hello.setText(“Hello SWT”);
shell.open();
shell.pack();

第三部分:进入一个循环

while (!shell.isDisposed())
{
    if (!display.readAndDispatch())
   {
       display.sleep();
    }
}

这三部分也是一个SWT程序都需要的三部分。

Dispaly的创建

所有的SWT程序在开始运行时都必须获取Display对象,没有Display,SWT程序就无法和操作系统交互,一个SWT程序中至少含有一个Display对象,创建Display对象的线程称为UI线程。
在SWT程序中,我们可以通过如下方式获取一个Display对象:

  • new Display:创建一个新的Display实例
  • Display.getDefault():第一次调用会创建一个Display对象,之后再次调用会获得之前创建的Display对象,需要注意的是,如果在调用之前已经通过new Display获得了Display对象,那么调用Display.getDefault()将获得之前新创建的Display对象

// 创建一个Display对象
Display create = Display.getDefault();
// 获得Display对象
Display display = Display.getDefault();
// 两次获得对象为同一个
System.out.println(create == display);

这段代码的输出结果为true,同样的下面这段代码也是一样的效果

// 创建一个Display对象
Display create = new Display();
// 获得Display对象
Display display = Display.getDefault();
// 两次获得对象为同一个
System.out.println(create == display);

一个线程中不能同时存在两个活动的Display,如果这样做的话,程序在运行时就会抛出一个SWT异常。如果确实需要创建多个同时活动的Display实例,则必须在不同的线程中创建。我们可以通过Display.getCurrent()函数来获取当前线程对应的Display实例,使用Display.findDisplay(Thread)则可以找到任意线程中的Display对象。
在多线程中,我们不应该使用Display.getDefault()来获得Display实例,这样很容易出现“非法线程访问”的异常,我们可以通过如下方法来获得Display实例:

public static Display getThreadDisplay()
{
   return Display.getCurrent() == null ? new Display() : Display.getCurrent();
}

Shell的创建

在SWT程序中,一个Shell就代表一个窗体,在SWT程序中,为了使资源管理更方便而做了规定,当父资源释放时,它要负责释放属于自己的子资源。从Display直接创建而来的Shell是Display的子资源,而从某个Shell(Shell A)创建而来的Shell B则是Shell A的子资源。当作为父资源的Shell被释放时,作为子资源的Shell也会同时被释放,而由于所有的Shell都是由Display直接或间接创建的,因此Display是所有Shell的最高层父资源,当一个Display被释放时,所有存在于这个UI线程中的Shell窗口都会被释放掉。

Display的事件队列和事件循环

当我们创建了一个窗口并打开它后,就进入事件循环

while (!shell.isDisposed())
{
    if (!display.readAndDispatch())
    {
       display.sleep();
    }
}

这段代码就是用于处理事件的循环。通过这段代码我们也可以发现,SWT是通过循环不断的从事件队列中获得信息并处理,所以当我们有耗时较长的事件要处理时,很容易造成程序堵塞,用户的体验度较低,我们通过一段代码来演示一下:

package com.gujin.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class HelloSWT
{
   public static void main(String[] args)
   {
      Display display = Display.getDefault();
      Shell shell = new Shell(display);
      final Label label = new Label(shell, SWT.NONE);
      label.setBounds(10, 10, 200, 30);
      label.setText("before");
      Button button = new Button(shell, SWT.BORDER);
      button.setBounds(10, 50, 200, 30);
      button.setText("deal");
      button.addSelectionListener(new SelectionAdapter() {
         @Override
         public void widgetSelected(SelectionEvent e)
         {
            try
            {
               Thread.sleep(10000);
            }
            catch (Exception e2)
            {
            }
            label.setText("after");
         }
      });
      shell.open();
      shell.pack();
      while (!shell.isDisposed())
      {
         if (!display.readAndDispatch())
         {
            display.sleep();
         }
      }
      display.dispose();
   }
}

运行这段代码,我们可以发现,当我们点击按钮后,窗口会堵塞无响应,直至事件处理结束,这在实际应用中肯定是不可取的,在Display中为我们提供了syncExec(Runnable r)和asyncExec(Runnable r)来向队列中插入事件,我们可以对上面的代码进行如下修改:

package com.gujin.swt;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class HelloSWT
{
   public static void main(String[] args)
   {
      final Display display = Display.getDefault();
      Shell shell = new Shell(display);
      final Label label = new Label(shell, SWT.NONE);
      label.setBounds(10, 10, 200, 30);
      label.setText("before");
      Button button = new Button(shell, SWT.BORDER);
      button.setBounds(10, 50, 200, 30);
      button.setText("deal");
      button.addSelectionListener(new SelectionAdapter() {
         @Override
         public void widgetSelected(SelectionEvent e)
         {
            new Thread() {
               @Override
               public void run()
               {
                  try
                  {
                     Thread.sleep(10000);
                  }
                  catch (Exception e2)
                  {
                  }
                  display.syncExec(new Runnable() {

                     @Override
                     public void run()
                     {
                        label.setText("after");
                     }
                  });
               }
            }.start();
         }
      });
      shell.open();
      shell.pack();
      while (!shell.isDisposed())
      {
         if (!display.readAndDispatch())
         {
            display.sleep();
         }
      }
      display.dispose();
   }
}

我们启动一个新的线程来处理耗时较多的逻辑,在处理完成后想时间队列中添加一个事件完成后续操作,这时候我们发现单击按钮后,窗口不会出现之前的阻塞现象,在事件处理完成后Label上的文本同样会被改变。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: swt-arm64.jar.zip是一个Java库文件,用于支持在ARM64架构的计算机上运行基于Java的桌面应用程序。SWT是一个Java GUI工具包,全称为Standard Widget Toolkit。它提供了一组UI组件,用于构建跨平台的桌面应用程序。 ARM64是一种64位的ARM架构,目前被广泛应用于移动设备和服务器等领域。由于ARM64架构与传统的x86架构不同,因此需要专门的Java库文件来支持在ARM64架构的设备上运行Java应用程序。而swt-arm64.jar.zip就是为此而生的一个Java库文件,在ARM64架构的设备上可以很好地支持Java应用程序的运行。 下载和使用swt-arm64.jar.zip非常简单,只需要将其下载并引入到Java项目中即可。对于使用Eclipse等开发环境的用户来说,可以直接将swt-arm64.jar.zip添加到项目的Java Build Path中并引用该库文件。一旦添加并引入成功,就可以在ARM64架构的设备上愉快地运行Java应用程序了。 ### 回答2: swt-arm64.jar.zip是一个Java的库文件,主要用于ARM64架构的处理器上工作。SWT是一个标准部件工具箱库,它提供了丰富的GUI控件,可以用于Java应用程序的创建和开发。ARM64是一种64位的ARM处理器架构,主要用于在移动设备和服务器上提供高性能计算和处理能力。 swt-arm64.jar.zip库文件包含了一些特定于ARM64架构的SWT控件和方法,可以在这种处理器的设备上使用。如果您的Java应用程序需要在ARM64设备上运行,并且您的应用程序使用了SWT工具箱库,那么您需要使用swt-arm64.jar.zip文件来确保您的应用程序能够在ARM64设备上正常运行。 总之,swt-arm64.jar.zip是Java应用程序开发中的标准库文件,它提供了在ARM64架构处理器上使用的SWT控件和方法。如果您需要编写和开发适用于ARM64设备的Java应用程序,并且想使用SWT工具箱库,swt-arm64.jar.zip将是一个非常有用的资源。 ### 回答3: swt-arm64.jar.zip是一种被压缩的Java桌面应用程序包,它适用于64位的ARM处理器。SWT代表标准窗口工具包,它是一种用于创建本机GUI(图形用户界面)的Java工具包。 SWT提供了一个易于使用且具有高度定制性的开发环境,可以支持各种平台的GUI构建,包括Windows,Linux和Mac OS X。 swt-arm64.jar.zip包含Java代码和SWT库的二进制文件,可以快速部署Java应用程序到ARM64平台。大多数情况下,这种程序在嵌入式或物联网设备上运行,例如智能手机、平板电脑、智能家居控制器等。 因为ARM64是新型的处理器架构,一些老式的Java应用程序可能不能直接在ARM64平台上运行,需要重新编写或者优化才能适配。使用swt-arm64.jar.zip能够让开发者更加迅速地适配ARM64平台,并且提供一种便捷的途径来创建功能强大的嵌入式GUI应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值