`
aqingsao
  • 浏览: 173231 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Swing中JColorChooser的Abbot单元测试

    博客分类:
  • Java
阅读更多

使用Abbot给Java Swing写单元测试,遇到这样一个问题:如果用到了showDialog(...)方法,由于是ModelDialog,系统执行到这里就被block了,无法通过Abbot写单元测试。

举个简单的例子来说:Frame中有个button,点击后会显示JColorChooser Dialog,选取颜色后点击OK或者Cancel按钮,Dialog消失,同时返回Color对象,然后就可以在frame中修改Label的颜色。

所以想象中的单元测试应该是这样:

    @Test
    public void testSelectColorRedAndClickOKButton() throws Exception {
        FrameDemo demo = new FrameDemo();
        demo.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        demo.pack();
        demo.setVisible(true);

        JButton colorButton = (JButton) getFinder().find(demo, new ClassMatcher(JButton.class))
        new JMenuItemTester().actionClick(colorButton);//1. Here will block after JColorChooser shows
        // 2. Some action to select color red: JColorChooserTester().actionSelectColor(Color.red)
        
        JLabel label = (JLabel) getFinder().find(demo, new ClassMatcher(JButton.class))
        assertEquals(Color.red, label.getForeground());
    }

类FrameDemo很简单:

      public class FrameDemo extends JFrame{
        public void FrameDemo(){
            JLabel label = new JLabel("Text color will change after you select new color");
            label.setForeground(Color.black);
            JButton colorButton = new JButton("Choose Color...");
            JPanel panel = new JPanel();
            panel.add(label);
            panel.add(colorButton);
            this.setContentPane(panel);
        }
    }
 

但是有两个问题:

1.注释1所在地方,当JColorChooser Dialog显示之后线程就被block了;

2.Abbot中没有类JColorChooserTester帮助选择颜色。

 

根据以上考虑,决定自己写一个JColorChooserTester,完成以下功能:

1.根据输入选择颜色,并点击OK按钮关闭对话框;

2.可以不选取颜色直接点击Cancel按钮关闭对话框;

3.应该在显示对话框之前就调用该方法。

根据这些分析,对上面的测试做了修改:

    @Test
    public void testSelectColorRedAndClickOKButton() throws Exception {
        FrameDemo demo = new FrameDemo();
        demo.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        demo.pack();
        demo.setVisible(true);

        JButton colorButton = (JButton) getFinder().find(demo, new ClassMatcher(JButton.class));
        new JColorChooserTester().actionSelectColor(demo, Color.red);// We want dialog to return red
        new JMenuItemTester().actionClick(colorButton);

        JLabel label = (JLabel) getFinder().find(demo, new ClassMatcher(JButton.class));
        assertEquals(Color.red, label.getForeground());
    }

 测试写完了,接下来就写JColorChooserTester类,上面的测试能够通过,并经过简单的重构后:

 

package com.tw.ui.tester;

import abbot.finder.BasicFinder;
import abbot.finder.Matcher;
import abbot.finder.ComponentNotFoundException;
import abbot.finder.MultipleComponentsFoundException;
import abbot.finder.matchers.ClassMatcher;
import abbot.tester.JComponentTester;
import abbot.tester.JMenuItemTester;

import javax.swing.*;
import java.awt.*;

import org.apache.log4j.Logger;

public class JColorChooserTester extends JComponentTester {
    private static final long DEFAULT_TIME_OUT_IN_MILLISECONDS = 5000;
    private long waitInMilliSeconds;
    private Logger logger = Logger.getLogger(JColorChooserTester.class);

    public JColorChooserTester() {
        this(DEFAULT_TIME_OUT_IN_MILLISECONDS);
    }

    public JColorChooserTester(long waitInMilliSeconds) {
        this.waitInMilliSeconds = waitInMilliSeconds;
    }

    public void actionClickCancel(final Container container) {
        final JColorChooserFinder chooserFinder = new JColorChooserFinder(container);
        Thread thread = new Thread(){
            public void run(){
                new JMenuItemTester().actionClick(chooserFinder.getCancelButton());
            }
        };
        thread.start();
    }

    public void actionSelectColor(Container container, final Color returnedColor) {
        final JColorChooserFinder chooserFinder = new JColorChooserFinder(container);
        Thread thread = new Thread(){
            public void run(){
                chooserFinder.getColorChooser().setColor(returnedColor);
                new JMenuItemTester().actionClick(chooserFinder.getOKButton());
            }
        };
        thread.start();
    }

    class JColorChooserFinder {
        JColorChooser colorChooser;
        JButton cancelButton;
        JButton okButton;
        private boolean shouldWaitForDialog = true;
        long start = System.currentTimeMillis();
                                      
        public JColorChooserFinder(Container container) {
            FindDialog(container);
        }

        private void FindDialog(final Container container) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    try {
                        JDialog dialog = waitAndFindDialog(container);
                        if (dialog != null) {
                            logger.debug("Find JColorChooser Dialog.");
                            cancelButton = findCancelButton(dialog);
                            okButton = findOKButton(dialog);
                            colorChooser = findColorChooser(dialog);
                        }
                    } catch (Exception e) {
                    }
                    finally {
                        shouldWaitForDialog = false;
                    }
                }
            });
        }

        private JDialog waitAndFindDialog(final Container container) {
            JDialog dialog = null;
            long waited = 0;
            while (dialog == null && shouldWaitMore(waited)) {
                try {
                    dialog = (JDialog) new BasicFinder().find(container, new ClassMatcher(JDialog.class));
                } catch (ComponentNotFoundException e) {
                } catch (MultipleComponentsFoundException e) {
                    logger.debug("Found multiple JDialogs");
                    break;
                }
                waited += waitMore(500);
            }
            return dialog;
        }

        public JButton getCancelButton() {
            long waited = 0;
            while (shouldWaitForDialog && shouldWaitMore(waited)) {
                waited += waitMore(500);
            }
            return cancelButton;
        }

        private long waitMore(long millis) {
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
            }
            return millis;
        }

        public JButton getOKButton() {
            long waited = 0;
            while (shouldWaitForDialog && shouldWaitMore(waited)) {
                waited += waitMore(500);
            }
            return okButton;
        }

        public JColorChooser getColorChooser() {
            long waited = 0;
            while (shouldWaitForDialog && shouldWaitMore(waited)) {
                waited += waitMore(500);
            }
            return colorChooser;
        }

        private JButton findCancelButton(JDialog dialog) {
            return findButtonByText(dialog, UIManager.getString("ColorChooser.cancelText"));
        }

        private JButton findOKButton(JDialog dialog) {
            return findButtonByText(dialog, UIManager.getString("ColorChooser.okText"));
        }

        private JColorChooser findColorChooser(JDialog dialog) {
            try {
                return (JColorChooser) new BasicFinder().find(dialog, new ClassMatcher(JColorChooser.class));
            } catch (Exception e) {
                return null;
            }
        }

        private JButton findButtonByText(JDialog dialog, final String cancelString) {
            try {
                return (JButton) new BasicFinder().find(dialog, new Matcher() {

                    public boolean matches(Component component) {
                        return component.getClass().equals(JButton.class) && ((JButton) component).getText().equals(cancelString);
                    }
                });
            } catch (Exception e) {
                return null;
            }
        }
        private boolean shouldWaitMore(long waited) {
            return waited < waitInMilliSeconds;
        }        
    }
}

JColorChooserTester的源码和测试代码请见附件。

分享到:
评论

相关推荐

    java swing-JColorChooser的使用

    JColorChooser是Swing库提供的一个颜色选择器组件。它允许用户通过图形界面选择颜色,用于设置和调整应用程序中的颜色值。

    Java Swing中的JButton、JComboBox、JList和JColorChooser组件使用案例

    主要介绍了Java Swing中的按钮(JButton)、组合框(JComboBox)、下拉列表(JList)和颜色选择器(JColorChooser)组件使用案例,需要的朋友可以参考下

    Swing组件下载(常用组件)

    Swing组件(javax.swing.-) 面板:JPanel 标签化窗格:JTabbedPane 拆分窗格:JSplitPane 滚动窗格:JScrollPane 工具栏:JToolBar 桌面窗格:JDesktopPane 内部框架:JInternalFrame 分层窗格:JLayeredPane ...

    oracle jdk自带swing 代码示例swingset3

    swing入门必看示例( oracle 官方swingset3示例) swingset3-oracle 运行包, 双击swingset3.bat 运行或者在jar包右键选择java运行. swingset3-src 源码包,感兴趣可以查看示例代码. ...选择器:JColorChooser/JOptionPane

    用java做的记事本

    import javax.swing.JColorChooser; public class Jishiben extends Frame implements ActionListener { MenuBar menuBar; //定义菜单条 TextArea textArea=new TextArea(20,50);//定义文本区 public OptionOfFile...

    JColorChooser_java_

    Java调色板颜色选择器代码,调用JFrame的构造函数,实例化颜色选择器

    2010年11月6日招聘会参会企业名单.xls

    JavaTM 编程语言进行服务器端...javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类

    实验九 图形用户界面GUI(文档中包含可执行源码)

    在Swing组件中,最常见的一个容器就是JFrame,它是一个独立存在的顶级容器(也叫窗口),不能放置在其他容器之中,JFrame支持通用窗口所有的基本功能,例如窗口最小化、设定窗口大小等。 JDialog是Swing的另

    JAVA_API1.6文档(中文)

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf ...

    java jdk-api-1.6 中文 chmd

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf ...

    JavaAPI1.6中文chm文档 part1

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf ...

    Java 1.6 API 中文 New

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf 提供...

    JavaAPI中文chm文档 part2

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf ...

    java api最新7.0

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf 提供...

    JDK_1_6 API

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf 提供...

    [Java参考文档]

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf ...

    [Java参考文档].JDK_API 1.6

    javax.swing.colorchooser 包含供 JColorChooser 组件使用的类和接口。 javax.swing.event 供 Swing 组件触发的事件使用。 javax.swing.filechooser 包含 JFileChooser 组件使用的类和接口。 javax.swing.plaf 提供...

Global site tag (gtag.js) - Google Analytics