注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

千鸟

本blog所有日志均系原创 转载请注明出处

 
 
 

日志

 
 

Swing Application Framework 3 . 编写后台任务  

2007-12-21 21:51:53|  分类: J2SE |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 1. SwingWorker<T,V>

在专用线程中执行长时间 GUI 交互任务的抽象类。

T - 此 SwingWorker 的 doInBackground 和 get 方法返回的结果类型

V - 用于保存此 SwingWorker 的 publish 和 process 方法的中间结果的类型

要处理过程的中间结果,作为publish(V... chunks) 的参数,这样会异步的执行

process(List<V> chunks) 

setProgress(i); 会以"progress" 为绑定名,通知PropertyChangeListener。i 应该在 0 到 100 之间。 主要目的是指出完成的进度(i%)

          

工作流 

SwingWorker 的生命周期中包含三个线程: 

当前 线程:在此线程上调用 execute() 方法。它调度 SwingWorker 以在 worker 线程上执行并立即返回。可以使用 get 方法等待 SwingWorker 完成。 

Worker 线程:在此线程上调用 doInBackground() 方法。所有后台活动都应该在此线程上发生。要通知 PropertyChangeListeners 有关绑定 (bound) 属性的更改,请使用 firePropertyChange 和 getPropertyChangeSupport() 方法。默认情况下,有两个可用的绑定属性:state 和 progress。 

事件指派线程:所有与 Swing 有关的活动都在此线程上发生。SwingWorker 调用 process 和 done() 方法,并通知此线程的所有 PropertyChangeListener。 

SwingWorker 被设计为只执行一次。多次执行 SwingWorker 将不会调用两次 doInBackground 方法。

 

package test.ui.APITest;

/**

 *

 * @author: liuke

 * @email:  soulnew@gmail.com

 */

import java.awt.LayoutManager;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.beans.PropertyChangeEvent;

import java.beans.PropertyChangeListener;

import java.util.List;

import javax.swing.BoxLayout;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JProgressBar;

import javax.swing.JScrollPane;

import javax.swing.JTextArea;

import javax.swing.SwingWorker;

public class SwingWorkerDemo {

  public static void main(String[] args) {

    JTextArea textArea = new JTextArea(10, 20);

    final JProgressBar progressBar = new JProgressBar(0, 10);

    final CounterTask task = new CounterTask();

    task.addPropertyChangeListener(new PropertyChangeListener() {

      public void propertyChange(PropertyChangeEvent evt) {

        if ("progress".equals(evt.getPropertyName())) {

          progressBar.setValue((Integer) evt.getNewValue());

        }

      }

    });

    JButton startButton = new JButton("Start");

    startButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        task.execute();

      }

    });

    JButton cancelButton = new JButton("Cancel");

    cancelButton.addActionListener(new ActionListener() {

      public void actionPerformed(ActionEvent e) {

        task.cancel(true);

      }

    });

    JPanel buttonPanel = new JPanel();

    buttonPanel.add(startButton);

    buttonPanel.add(cancelButton);

    JPanel cp = new JPanel();

    LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS);

    cp.setLayout(layout);

    cp.add(buttonPanel);

    cp.add(new JScrollPane(textArea));

    cp.add(progressBar);

    JFrame frame = new JFrame("SwingWorker Demo");

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setContentPane(cp);

    frame.pack();

    frame.setVisible(true);

  }

}

class CounterTask extends SwingWorker<Integer, Integer> {

  private static final int DELAY = 1000;

  public CounterTask() {

  }

  @Override

  protected Integer doInBackground() throws Exception {

    int i = 0;

    int count = 10;

    while (!isCancelled() && i < count) {

      i++;

      publish(new Integer[] { i });

      setProgress(i );

      Thread.sleep(DELAY);

    }

    return count;

  }

   

  protected void process(List<Integer> chunks) {

    for (int i : chunks)

      System.out.println(i);

  }

  @Override

  protected void done() {

    if (isCancelled())

      System.out.println("Cancelled !");

    else

      System.out.println("Done !");

  }

}

2.Task

abstract class Task<T, V> extends SwingWorker<T, V> 

setMessage(String message)

会以"message" 为绑定名,通知PropertyChangeListener。绑定内容为String message

另外的一些常用绑定名。看名字也知道什么时候发出的。

"started" 

"done"

"progress"

3.TaskMonitor

TaskMonitor(ApplicationContext context) 

当一个Application 内部有很多Task,显然一个一个的添加监听相当辛苦的,所以你可以简化下,这么做:

ApplicationContext ac = ApplicationContext.getInstance();

TaskMonitor taskMonitor =ac.getTaskMonitor()

taskMonitor.addPropertyChangeListener(this);

那么这个PropertyChangeListener,就可以监听所有的Task发出的广播事件。

4.

用 @Action 给Task 赋值

Action 标记的有这么个属性:

@Retention(RetentionPolicy.RUNTIME) 意味着在运行时可用

@Action(block = BlockingScope.WINDOW)

    public Task blockMy() {

 return new DoNothing();

    }

 

 

这个框架是怎么读取@Action  这个标签中的设置了?

ApplicationActionMap 中是这样处理的。注意红色的 BlockingScope

  private void addAnnotationActions(ResourceMap resourceMap) {

 Class<?> actionsClass = getActionsClass();

 // @Action 

 for (Method m : actionsClass.getDeclaredMethods()) {

     Action action = m.getAnnotation(Action.class);

     if (action != null) {

  String methodName = m.getName();

  String enabledProperty = aString(action.enabledProperty(), null);

  String selectedProperty = aString(action.selectedProperty(), null);

  String actionName = aString(action.name(), methodName);

  Task.BlockingScope block = action.block();

  ApplicationAction appAction = 

      new ApplicationAction(this, resourceMap, actionName, m, enabledProperty, selectedProperty, block);

  putAction(actionName, appAction);

     }

 }

 // @ProxyActions

 ProxyActions proxyActionsAnnotation = actionsClass.getAnnotation(ProxyActions.class);

 if (proxyActionsAnnotation != null) {

     for(String actionName : proxyActionsAnnotation.value()) {

  ApplicationAction appAction = new ApplicationAction(this, resourceMap, actionName);

  appAction.setEnabled(false); // will track the enabled property of the Action it's bound to

  putAction(actionName, appAction);

  proxyActions.add(appAction);

     }

 }

    }

 

 

后记: Swing Application Framework 的demo中的BlockingExample1.java 是

@author Hans Muller (Hans.Muller@Sun.COM)写的

,他是Sun desktop 的CTO(首席技术官)

 blog:  http://weblogs.java.net/blog/hansmuller/

  评论这张
 
阅读(1691)| 评论(1)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017