Swing框架之Model之二

Swing框架之Model之二

轻量级通知

       下面Swing中的模型使用轻量级通知,它们是基于 ChangeListener、ChangeEvent接口的:

ModelListenerEvent
BoundedRangeModelChangeListenerChangeEvent
ButtonModelChangeListenerChangeEvent
SingleSelectionModelChangeListenerChangeEvent


      ChangeListener接口只有一个通用方法:

public void stateChanged(ChangeEvent e)

      ChangeEvent中仅有的状态是事件源,因为所有通知中 的事件源 都是相同的,单独一个事件实例可以用作所有来自该模型的通知。使用此机制的模型支持下面的方法来添加和删除ChangeListeners:

   public void addChangeListener(ChangeListenerl)
   public voidremoveChangeListener(ChangeListenerl)

        获知JSlider数据发生变化的代码可以使用如下代码实现:

JSlider slider = new JSlider();
BoundedRangeModelmodel =slider.getModel();           
model.addChangeListener(new ChangeListener() {
      public voidstateChanged(ChangeEvent e) {
            // need to query themodel
            // to getupdatedvalue...
            BoundedRangeModel m= (BoundedRangeModel)e.getSource();
            System.out.println("model changed: "+
            m.getValue());
      }
});

       为给不想和分离式模型交互的程序提供方便,一些Swing组件类提供了直接在组件上注册ChangeListener的方法(组件可在组件内部侦听模型的 数据变化,并将事件传播给任何注册在组件上的Listener),这些通知的唯一区别是,使用模型注册方式的事件源是该模型实例,而使用组件注册方式的事 件源是该组件。

        因此我们可以将前面的例子简化成:

JSlider slider = newJSlider();
slider.addChangeListener(new ChangeListener() {
     public void stateChanged(ChangeEvent e) {
           //the source will be
           // the slider this time..
           JSlider s=(JSlider)e.getSource();
           System.out.println("valuechanged: "+ s.getValue());
     }
});

状态化通知

       支持状态化通知的模型根据它们的目的提供不同的Listener接口和事件对象。下表是这些模型接口和事件对象的类:

ModelListenerEvent
ListModelListDataListenerListDataEvent
ListSelectionModelListSelectionListenerListSelectionEvent
ComboBoxModelListDataListenerListDataEvent
TreeModelTreeModelListenerTreeModelEvent
TreeSelectionModelTreeSelectionListenerTreeSelectionEvent
TableModelTableModelListenerTableModelEvent
TableColumnModelTableColumnModelListenerTableColumnModelEvent
DocumentDocumentListenerDocumentEvent
DocumentUndoableEditListenerUndoableEditEvent

       Listener 除了 可以直接查询事件对象来跟踪内容 改变 外,这些API的作用与轻量级通知相似。比如下面的代码动态的跟踪JList被选中的项:

Stringitems[] = {"One", "Two", "Three");
JList list = new JList(items);
ListSelectionModel sModel =list.getSelectionModel();
sModel.addListSelectionListener (new ListSelectionListener() {
       publicvoidvalueChanged(ListSelectionEvent e) {
             // get change information directly
             // fromtheevent instance...
             if (!e.getValueIsAdjusting()) {
                  System.out.println("selection changed: " +
                  e.getFirstIndex());
             }
       }
});


自动视图更新

        模型没有任何表现它视图的固有知识,相反模型只有关心其状态改变的Listener列表,这种需求对于同个模型多个视图的框架来说是至关重要的。 Swing组件负责将合适的模型Listener连接起来,以便于模型改变时能正确地重画出自己。如果你发现模型改变时,组件不能自动更新,说明组件的实 现就存在错误。

忽略模型

        正如前面提到的,大多数组件直接在Component类中提供模型定义的API,以方便组件能不用和模型交互就直接操作,这是相当可行的编程方法,尤其是对于GUI状态模型来说。比如下面的JSlider内部getValue的实现,它将调用代理给模型:

public int getValue(){
      return getModel().getValue();
}

         因此程序完全可以这样写:

JSlider slider = new JSlider();
int value=slider.getValue();

Swing模型总结

         虽然理解了Swing模型设计是如何工作的,但没有必要在所有Swing编程中都使用模型API。你需要注意考虑应用程序各自的需求,决定哪儿使用模型API能帮你提升代码,且不带来不必要的复杂性。

         我特别推荐在Swing中使用应用数据模型(如JTable和JTree等的模型),因为从长期来看,它们能极大地提高你的应用程序可扩展性和模块化度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值