基于SWT的窗口同步移动的实现

<o:p></o:p>

    这是一个基于SWT的类似于千千静听播放器窗口那种展现方式的简单实现,即相关联的窗口中,辅窗口会随着主窗口的移动而移动。运行环境是JDK<st1:chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False">1.4.2</st1:chsdate>+WinXP+SWT3.1.2IDE使用的是Eclipse3.1.2。代码已测试成功。

  下面的例子中我们会创建两个窗口类,MainGUIAssistantGUI,他们分别代表主窗口和辅窗口。点击主窗口上的按钮会弹出辅窗口,当移动主窗口的时候,辅窗口会依附在主窗口上移动。辅窗口上单击可以将其关闭。

我们先来看看程序的代码:

主窗口类<o:p></o:p>

package testshell;<o:p></o:p>

<o:p> </o:p>

import org.eclipse.swt.SWT;<o:p></o:p>

import org.eclipse.swt.events.MouseAdapter;<o:p></o:p>

import org.eclipse.swt.events.MouseEvent;<o:p></o:p>

import org.eclipse.swt.events.SelectionAdapter;<o:p></o:p>

import org.eclipse.swt.events.SelectionEvent;<o:p></o:p>

import org.eclipse.swt.graphics.Rectangle;<o:p></o:p>

import org.eclipse.swt.widgets.Button;<o:p></o:p>

import org.eclipse.swt.widgets.Display;<o:p></o:p>

import org.eclipse.swt.widgets.Event;<o:p></o:p>

import org.eclipse.swt.widgets.Listener;<o:p></o:p>

import org.eclipse.swt.widgets.Shell;<o:p></o:p>

/**<o:p></o:p>

 * @author lvpin<o:p></o:p>

 * 2007-2-6 10:43:24<o:p></o:p>

 */<o:p></o:p>

public class MainGUI extends Shell {<o:p></o:p>

       /**<o:p></o:p>

        * Launch the application<o:p></o:p>

        * @param args<o:p></o:p>

        */<o:p></o:p>

       private static MainGUI mainGUI;<o:p></o:p>

       private static Display display;<o:p></o:p>

       static AssistantGUI assistantGUI;<o:p></o:p>

       public static void main(String args[]) {<o:p></o:p>

              try {<o:p></o:p>

                     display = Display.getDefault();<o:p></o:p>

                     mainGUI = new MainGUI(display, SWT.SHELL_TRIM);<o:p></o:p>

                     mainGUI.setBounds(300,300,500,375);     <o:p></o:p>

                     mainGUI.addListener(SWT.Move,new Listener(){<o:p></o:p>

                            public void handleEvent(Event arg0) {<o:p></o:p>

                                   Rectangle r=mainGUI.getBounds();<o:p></o:p>

                                   if(assistantGUI!=null&&!assistantGUI.isDisposed()){<o:p></o:p>

                                          assistantGUI.setBounds(r.x+r.width,r.y,200,200);<o:p></o:p>

                                   }<o:p></o:p>

                            }      <o:p></o:p>

                     });<o:p></o:p>

                     mainGUI.open();<o:p></o:p>

                     mainGUI.layout();<o:p></o:p>

                     while (!mainGUI.isDisposed()) {<o:p></o:p>

                            if (!display.readAndDispatch())<o:p></o:p>

                                   display.sleep();<o:p></o:p>

                     }<o:p></o:p>

              } catch (Exception e) {<o:p></o:p>

                     e.printStackTrace();<o:p></o:p>

              }<o:p></o:p>

       }<o:p></o:p>

       /**<o:p></o:p>

        * Create the shell<o:p></o:p>

        * @param display<o:p></o:p>

        * @param style<o:p></o:p>

        */<o:p></o:p>

       public MainGUI(Display display, int style) {<o:p></o:p>

              super(display, style);<o:p></o:p>

              createContents();<o:p></o:p>

       }<o:p></o:p>

       /**<o:p></o:p>

        * Create contents of the window<o:p></o:p>

        */<o:p></o:p>

       protected void createContents() {<o:p></o:p>

              setText("MainGUI");<o:p></o:p>

              final Button button = new Button(this, SWT.NONE);<o:p></o:p>

              button.addSelectionListener(new SelectionAdapter() {<o:p></o:p>

                     public void widgetSelected(final SelectionEvent e) {<o:p></o:p>

                            ininitAssistantGUI();                 <o:p></o:p>

                     }<o:p></o:p>

              });<o:p></o:p>

              button.setText("assistant");<o:p></o:p>

              button.setBounds(120, 220, 120, 30);<o:p></o:p>

       }<o:p></o:p>

       public static void ininitAssistantGUI(){<o:p></o:p>

              if(assistantGUI==null||assistantGUI.isDisposed())<o:p></o:p>

                     assistantGUI=new AssistantGUI(display,SWT.SHELL_TRIM);<o:p></o:p>

              assistantGUI.setBounds(mainGUI.getBounds().x+mainGUI.getBounds().width,<o:p></o:p>

                             mainGUI.getBounds().y,200,200);<o:p></o:p>

              assistantGUI.addMouseListener(new MouseAdapter(){<o:p></o:p>

                     public void mouseDown(MouseEvent e){<o:p></o:p>

                            assistantGUI.stop();<o:p></o:p>

                     }<o:p></o:p>

              });<o:p></o:p>

              assistantGUI.open();<o:p></o:p>

              assistantGUI.layout();<o:p></o:p>

       }<o:p></o:p>

       protected void checkSubclass() {<o:p></o:p>

              // Disable the check that prevents subclassing of SWT components<o:p></o:p>

       }<o:p></o:p>

}<o:p></o:p>

辅窗口类<o:p></o:p>

package testshell;<o:p></o:p>

<o:p> </o:p>

import org.eclipse.swt.widgets.Display;<o:p></o:p>

import org.eclipse.swt.widgets.Shell;<o:p></o:p>

/**<o:p></o:p>

 * @author lvpin<o:p></o:p>

 * 2007-2-6 10:45:52<o:p></o:p>

 */<o:p></o:p>

public class AssistantGUI extends Shell {<o:p></o:p>

       public AssistantGUI(Display display, int style) {<o:p></o:p>

              super(display, style);<o:p></o:p>

              createContents();<o:p></o:p>

       }<o:p></o:p>

       protected void createContents() {<o:p></o:p>

              setText("AssistantGUI");<o:p></o:p>

       }<o:p></o:p>

       public void stop(){<o:p></o:p>

              this.dispose();<o:p></o:p>

       }<o:p></o:p>

       protected void checkSubclass() {<o:p></o:p>

              // Disable the check that prevents subclassing of SWT components<o:p></o:p>

       }<o:p></o:p>

}<o:p></o:p>

<o:p> </o:p>

<o:p> </o:p>

    我们截取主要的几段分别来说:

1)在主窗口上添加一个按钮,用来打开辅窗口。<o:p></o:p>

final Button button = new Button(this, SWT.NONE);<o:p></o:p>

button.addSelectionListener(new SelectionAdapter() {<o:p></o:p>

       public void widgetSelected(final SelectionEvent e) {<o:p></o:p>

              ininitAssistantGUI();                 <o:p></o:p>

       }<o:p></o:p>

});<o:p></o:p>

button.setText("button");<o:p></o:p>

button.setBounds(120, 220, 120, 30);<o:p></o:p>

    在按钮上添加了一个SelectionListener当点击按钮时会触发SelectionEvent事件,调用ininitAssistantGUI()方法来生成AssistantGUI的实例。

<o:p> </o:p>

2ininitAssistantGUI()方法。<o:p></o:p>

public static void ininitAssistantGUI(){<o:p></o:p>

       if(assistantGUI==null||assistantGUI.isDisposed())<o:p></o:p>

              assistantGUI=new AssistantGUI(display,SWT.SHELL_TRIM);<o:p></o:p>

       assistantGUI.setBounds(mainGUI.getBounds().x+mainGUI.getBounds().width,<o:p></o:p>

                         mainGUI.getBounds().y,200,200);<o:p></o:p>

       assistantGUI.addMouseListener(new MouseAdapter(){<o:p></o:p>

              public void mouseDown(MouseEvent e){<o:p></o:p>

                     assistantGUI.stop();<o:p></o:p>

              }<o:p></o:p>

       });<o:p></o:p>

       assistantGUI.open();<o:p></o:p>

       assistantGUI.layout();<o:p></o:p>

}<o:p></o:p>

            if(assistantGUI==null||assistantGUI.isDisposed())这句首先对assistantGUI进行判断,如果为空或者已经关闭则创建一个新的assistantGUI实例。然后对辅窗口的初始位置和大小进行设置,setBounds()方法有四个int型参数,分别代表窗口左上角的x,y值和窗口的宽(width)和高(height)。需要注意的是x,y值所对应的平面直角坐标系的原点在屏幕的左上角位置,向右x值为正且递增,向下y值为正且递增。由setBounds()的参数我们可以看出:

第一个参数:mainGUI.getBounds().x+mainGUI.getBounds().width<o:p></o:p>

                        说明辅窗口的x值为主窗口的x值加上主窗口的宽度,即辅窗口位于主窗口的右侧。

第二个参数:mainGUI.getBounds().y<o:p></o:p>

                        说明辅窗口的y值同主窗口的y值相同,与第一个参数共同定位的辅窗口位置很明显了,即辅窗口位于并列于主窗

            口的右侧。

第三个参数:200 说明辅窗口的宽(width)为200

第四个参数:200 说明辅窗口的高(height)为200

<o:p> </o:p>

3)移动主窗口时触发事件<o:p></o:p>

     前面的2段代码实现了点击按钮实例化一个辅窗口,下面就来介绍一下移动主窗口时相应的使辅窗口跟随移动。实现的方法就是为主窗口添加一个“监听移动事件的内部匿名Listener”,当然你也可以用外部类实现,在此主要为了简化代码。

mainGUI.addListener(SWT.Move,new Listener(){<o:p></o:p>

       public void handleEvent(Event arg0) {<o:p></o:p>

              Rectangle r=mainGUI.getBounds();<o:p></o:p>

              if(assistantGUI!=null&&!assistantGUI.isDisposed()){<o:p></o:p>

                     assistantGUI.setBounds(r.x+r.width,r.y,200,200);<o:p></o:p>

              }<o:p></o:p>

        }    <o:p></o:p>

});   <o:p></o:p>

     首先通过addListener()方法给主窗口添加一个通用监听器,该监听器对应窗口移动事件(SWT.Move)。Listener只有一个方法handleEvent,这个方法里你可以处理任何事件。需要注意的是,我们用的是一种untyped event机制,与untyped event相联系的两个类就是代码中的ListenerEvent。在此称其为untyped event是因为其对应的不是一个特定的Listener(前面点击按钮代码中用的则是特定的Listener——SelectionListener,所它采用的是typed event机制)。

          Rectangle是一个矩形类,在此它对应了主窗口的形状(如宽、高、起始位置等)。最后我们还是通过setBounds()方法来改变辅窗口的位置,使它跟随着主窗口移动。

<v:shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype>

     到此,一个基于SWT的窗口同步移动的程序就实现了,代码很简单,逻辑也不复杂。我认为它值得学习的地方主要是为窗口组件添加untyped event机制的事件监听,因为好多时候在使用SWT中我们想要完成的功能并没有对应特定的监听器,它给我们提供一个解决类似问题的途径。

     我也是刚刚接触SWT不长时间,还处于不断地摸索学习中。上面的内容共享给同样处在SWT学习阶段的朋友,希望对您的学习和使用有所帮助。

<o:p> </o:p>

 

<o:p></o:p>

你可能感兴趣的:(eclipse,jdk,ext,F#,ide)