2011-09-06 33 views
0

我想问你几个关于Gui的问题。了解Gui和听众

我看到了下面的例子:

public class ShellWithButton { 
    public static void main(String[] args) { 
    Display display = Display.getDefault(); 
    Shell shell = newShell (display); 
    Button ok = newButton (shell, SWT.PUSH); 
    ok.setText ("Push Me!"); 
    ok.addSelectionListener(new ButtonHandler()); 
    ok.setLocation(0,0); 
    ok.setSize(100,30); 
    shell.pack(); 
    shell.open(); 
    while(!shell.isDisposed()) { 
    if(!display.readAndDispatch()) 
     display.sleep(); 
      } 
     display.dispose(); 
     } 
    }  

public class ButtonHandler 
implements SelectionListener { 
    public void widgetSelected(SelectionEvent e) { 
     if(e.getSource() instanceofButton) { 
      Button b = (Button) e.getSource(); 
      b.setText("Thanks!"); 
     } 
    } 
public voidwidgetDefaultSelected(SelectionEvent e){ 
// TODO Auto-generated method stub 
    } 
} 

(I) - 有人推按钮 - 程序如何知道要激活widgetSelected? 我可以看到按钮添加了ButtonHandler监听器本身,但为什么按下按钮而不是单击该框会将事件发送到ButtonHandler? 我看不到只有推送发送给这个监听者的地方。 (ii) - 为什么我要将一个ButtonHandler的实例发送给监听器?那是什么意思? (iii) - 当我按下按钮时发生了什么?这个事件是什么?事件是按钮本身的一个实例?

(iv) - Button b = (Button) e.getSource();为什么我需要此源代码的投射?正如所写的那样,事件只能来自ok,这是按钮的实例。

(v) - 为什么原始按钮会改变它的标题?我们改变B.

非常感谢!

回答

2
  1. 当有人按下按钮,该按钮调用widgetSelected() ,因为这是该库是如何设计的;它需要调用一些 方法,所以你可以做一些事情,他们在这个方法上解决。 因为它叫你widgetSelected()是因为你给它你的 类为它打电话。该按钮知道您的班级有一个 widgetSelected()方法,因为您实施了 SelectionListener,并且需要您执行 widgetSelected()方法。这是接口的原因, ,我建议你阅读它们。只有点击该按钮, 才会获得按钮来调用您的方法,因为该按钮仅在点击时才知道 。当屏幕上有一个点击时,只有需要知道它的小部件才会被告知。

  2. 正如我上面提到的,您将您的处理程序发送到按钮,以便 知道如何处理它。

  3. 当按钮被按下时,它告诉你什么样的处理程序发生 ,等所有相关信息提供给您的 SelectionEvent。事件本身不是按钮,但事件 会告诉您哪个按钮被按下,以防您希望相同的处理程序 处理多个按钮。

  4. 您需要的造型,因为当事情发生时对各种GUI对象,不只是 按钮您widgetSelected()方法可以 调用。因此,源代码将作为某些超类共同的 提供给所有可以调用您的方法的小部件,并且当您确定它是您的按钮时,您需要将 转换回按钮。是的,在这个 程序中它只能被按钮调用,但这并不总是 的情况。

  5. 按钮的文本更改是因为B和您创建并显示的按钮是同一个对象。 Java中的对象(和数组)是“指针”,它们告诉你对象在哪里。当您将一个对象分配给另一个变量时,您不会复制该对象,而只是使用另一个变量指向同一个对象。

2

(I)GUI通常采用observer pattern,其中一个或多个对象订阅事件,每当这个事件发生是发送给所有订阅的对象,就像在你的按钮的情况下。

(II)你为了他们交往发送实例的听众,所以在适当的时候,他们可能会收到事件。

(III)什么情况是,该事件导致观察员收到您的按钮被按下的通知,最终导致正在执行一些代码。事件本身不是按钮的实例,而是处理事件的单独实例。

(IV)你需要转换,因为方法签名仅仅是通用的,因为它是用于多种类型的事件。

(V)它改变了它的标题,因为使用观察者模式,观察者在这种情况下,当其按下按钮事件发生的按钮被通报。

+0

谢谢奥斯卡。这个听众是否总是与按钮本身相关?假设我想更改外壳上的文本。我是否仍然需要将此侦听器添加到按钮?或者我可以添加到一个shell吗? – Numerator

+0

@Nir yes只要此按钮已注册此事件,此监听器就会将事件分派给按钮。我不知道你的Shell类是什么,但是如果你想改变它的文本,你将不得不将它添加为一个监听器,以便在事件发生时对其进行更改。 –

2

(i)“Listeners”背后的想法是,您希望提供将被通知事件的组件,对象,软件模块等的列表。按钮点击不仅仅是触发事件的原因是因为某些事情必须监听该事件才能对其做出反应。可以添加任何实现适当Listener接口的对象(取决于事件的类型),并因此处理该事件。 (ii)这是一个回调。你必须告诉监听者,“这是一个可以处理事件的对象实例,请将它添加到要通知的对象列表中。“这有点像订阅RSS订阅源,在某种意义上,列表中的每个人都会在发生更新时获得更新。

(iii)事件是一个单独的对象窗口系统(在某个深层,连接到底层操作系统的窗口库)创建事件对象,然后沿着已注册的监听器列表向下,通知每个监听器。这里有一些例外(例如,监听器可能吸收事件,阻止名单上的其他人听到它,但这是它自己的一个单独问题)

(iv)因为getSource()返回一个组件的实例如果你想能够访问Button特定的方法(在下面的行中完成,使用setText,你有要处理该方法调用的Button实例来知道该做什么(即,在哪个班上进行操作)。 (v)该按钮不改变它的标题 - ButtonHandler正在做它。所以,当widget被选中时,在ButtonHandler中调用“widgetSelected”方法。然后检查事件的来源(提供对原始按钮的引用),然后更新按钮的文本以反映它已被点击。