Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 270|回复: 0

[Swing学习]Swing应用程序框架API绪论(JSR-296)之二

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-5 23:56:04 | 显示全部楼层 |阅读模式
    用 @Action 标注定义动作     @Action标注标记打算作为Action的ctionPerformed方法的方法。ApplicationContext.getActionMap方法建立了包含由某些类定义的每个@Action的Action对象的ActionMap。ActionMap将父类链接起来,并且每个Application的子类都有父类。这样,所有的应用程序继承了从Application基类定义的cut,copy,paste,delete和quit动作。 SingleFrameExample4.java定义了两个@Actions,open和close:

    /**

      * Load the specified file into the textPane or popup an error
      * dialog if something goes wrong.  
      
    */

    @Action
    public
      
    void
      open() {
         JFileChooser chooser
    =
      
    new
      JFileChooser();
         
    int
      option
    =
      chooser.showOpenDialog(getMainFrame());
         
    if
      (option
    ==
      JFileChooser.APPROVE_OPTION) {
         File file
    =
      chooser.getSelectedFile();
         textPane.setPage(file.toURI().toURL());
         
    //
      error handling omitted for clarity


         }
    }

    /**

      * Replace the contents of the textPane with the value of the
      * "defaultText" resource.  
      
    */

    @Action
    public
      
    void
      close() {
         ApplicationContext ac
    =
      ApplicationContext.getInstance();
         String ac.getResourceMap(getClass()).getString(
    "
    defaultText
    "
    );
         textPane.setText(defaultText);
    }
      
        使用ApplicationContext的getActionMap方法来建立包含open和close的ActionMap。为了简化查询,通过建立一个私有的工具方法来完成,这和上面的查询app类的ResourceMap相似。

    private
      javax.swing.Action getAction(String actionName) {
         ApplicationContext ac
    =
      ApplicationContext.getInstance();
         
    return
      ac.getActionMap(getClass(),
    this
    ).get(actionName);
    }

    /*
      We use getAction to set the action property of menu items
      * and buttons and so on:

    */

    openMenuItem.setAction(getAction(
    "
    open
    "
    ));
    closeMenuItem.setAction(getAction(
    "
    close
    "
    ));
         
        以这种方法定义的Action的缺省表示特性当从类的ResourceBundle载入时初始化。这样,Action的text, mnemonic, tooltip (shortDescription), and shortcut被定义在SingleFrameExample4.properties的ResourceBundle里:  
    [blockquote]
    open.Action.text = &Open...
    open.Action.accelerator = control O
    open.Action.shortDescription = open a document
    close.Action.text = &Close
    close.Action.shortDescription = close the document  
    [/blockquote] 如果运行,将看见Action及其所有资源。   SingleFrameExample4 屏幕截图      编写动作可能困难的一个方面是处理那些潜在占用漫长时间或者阻塞的任务,比如文件系统或者网络访问。应用程序必须在后台线程里完成这些任务,让Swing事件分派线程(EDT)不会阻塞。在本例中,由JTextPane类处理异步文件载入。在许多情况下,应用程序开发者必须直接处理在后台上的运行任务。应用程序框架Task类(基于SwingWorker)简化了异步执行的动作的编写。 产生后台任务的动作     SwingWorker类在后台线程上计算数值,然后在事件分派线程上调用完成方法。应用程序通过覆盖SwingWorker done方法,或者增加一个PropertyChangeListener,或者覆盖process方法,能够监视SwingWorker并安全刷行GUI。它们当后台线程调用publish()方法时收到中间结果。能够测量它们自己进度的SwingWorker,设置进度特性通知PropertyChangeListener已经完成工作的百分比。     应用程序框架定义一个叫做Task的SwingWorker的子类,Task加入了一些特性让后台线程比较容易监视和管理。任务自动初始化从ResourceBundle载入的描述性特性。@Action方法能够返回一个Task对象,而框架将执行后台线程的Task。例如,这里的Task只是睡眠大约150毫秒。

    class
      DoNothingTask
    extends
      Task {
         @Override
    protected
      Void doInBackground()
    throws
      InterruptedException {
         
    for
    (
    int
      i
    =
      
    0
    ; i
    <
      
    10
    ; i
    ++
    ) {
             setMessage(
    "
    Working [
    "
      
    +
      i
    +
      
    "
    ]
    "
    );
             Thread.sleep(
    150L
    );
             setProgress(i,
    0
    ,
    9
    );
         }
         Thread.sleep(
    150L
    );
         
    return
      
    null
    ;
         }
         @Override
    protected
      
    void
      done() {
         setMessage(isCancelled()
    ?
      
    "
    Canceled.
    "
      :
    "
    Done.
    "
    );
         }
    }
         尽管DoNothingTask产生一个消息并周期地更新进度特性,但是大多数情况下它只是睡眠。显而易见,这类事情不必在事件分派线程上执行。启动在后台线程上DoNothingTask的@Action可能像这样编写:  @Action Task JustDoNothing() {
    return new DoNothingTask();
    }      ActionExample4.java提供了一个孵化Task的@Action的有趣示例。它使用一个遍历枚举目录里所有文件的Task(ListFileTask),每次发布大约10个文件。Task使用publish方法将中间结果交付给运行在EDT上的process方法。ActionExample4.java通过建立一个覆盖process方法的应用程序的子类使用ListFilesTask来更新GUI:

    private
      
    class
      DoListFiles
    extends
      ListFilesTask {
         
    public
      DoListFiles(File root) {  
    //
      ctor runs on the EDT


         
    super
    (root);
         listModel.clear();
         }
         @Override
    protected
      
    void
      process(List files) {
         
    if
      (
    !
    isCancelled()) {
             listModel.addAll(files);
         }
         }
    }


    private
      Task doListFiles
    =
      
    null
    ;

    @Action

    public
      Task go() {
         stop();  
    //
      stop the pending DoListFiles task (if any)


         setStopEnabled(
    true
    );
         File root
    =
      
    new
      File(rootTextField.getText());
         
    return
      
    new
      DoListFiles(root);
    }

    @Action(enabledProperty
    =
      
    "
    stopEnabled
    "
    )

    public
      
    void
      stop() {
         
    if
      ((doListFiles
    !=
      
    null
    )
    &&
      
    !
    doListFiles.isCancelled()) {
         
    if
      (doListFiles.cancel(
    true
    )) {
             doListFiles
    =
      
    null
    ;
             setStopEnabled(
    false
    );
         }
         }
    }
         
         如果运行ActionExample4,将会注意到当应用程序后台正忙于枚举文件时,GUI依然保持可响应状态。本例以PropertyChangeListener监视由后台Task产生的消息并在窗口底部将它们显示出来(这段代码在上面未列出)。监视后台任务的状态典型地由TaskMonitor类处理。SingleFrameExample5使用TaskMonitor类,它是下节的主题。 ActionExample4 屏幕截图     本例也引入了绑定启用@Action状态为特性当前特性值的enabledProperty的标注参数。也存在一个指示GUI在后台任务运行时应当阻塞的block标注参数(演示未体现)。对示例中@Action(block = Block.ACTION)意味着当后台任务正运行时Action对象自身应当禁止。为了用模态对话框阻塞全部GUI,通过指定block = lock.APPLICATION来替代。ActionExample5.java演示了所有的可能性。 一个小而全的应用程序      SingleFrameExample5.java是迄今为止提供的最接近完整的应用程序。通过从JPL photojournal网址上下载某些非常巨大的火星探测器的图像,它打算突出后台任务的重要性。应用程序允许用户一步一步下载图像,并且抢先或者取消当前的下载/显示任务。应用程序的结构是典型的,包括了用将通用任务和应用程序GUI连接的子类(ShowImageTask)特化通用Task类(本例中的LoadImageTask)。 在前一节描述了Task管理大多数基础。几个额外的细节值得在此强调:

    StatusBar使用共享的TaskMonitor来显示当前"前台”任务。
    通过显式终止图像读取操作(如果操作正在进行),LoadImageTask需要特别处理取消任务。通过覆盖Task.done(不是cancel,它是最终结构)方法来处理。
    正如@Action所为,通过缺省的TaskService执行一个Task的ready()方法,显示第一幅图像。  
      SingleFrameExample5屏幕截图: Mars Rover(火星探测器)的着陆视图


      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 13:04 , Processed in 0.359713 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表