`
aqingsao
  • 浏览: 174987 次
  • 性别: 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库提供的一个颜色选择器组件。它允许用户通过图形界面选择颜色,用于设置和调整应用程序中的颜色值。

    JColorChooser_java_

    在Java程序中使用 `JColorChooser`,首先需要导入`javax.swing.JColorChooser` 和 `javax.swing.JFrame` 类。例如: ```java import javax.swing.JColorChooser; import javax.swing.JFrame; ``` 2. **实例化...

    swing中自定义对话框的几种实际用法

    在Swing中,对话框是一种特殊的窗口,用于向用户提供临时信息或者需要用户进行交互的情况。自定义对话框则允许开发者根据需求定制对话框的外观和行为,以满足特定的应用场景。 一、Swing中的对话框类型 Swing提供了...

    精通java-swing开发.doc

    Swing中的组件大多数是从`JComponent`类派生出来的,这意味着它们是轻量级组件(Lightweight Components)。轻量级组件是由纯Java代码实现的,它们不依赖于底层操作系统提供的窗口系统资源,从而提高了性能和跨平台...

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

    在Java Swing中,UI设计和交互是通过各种组件来实现的。本文主要关注四个关键组件:JButton(按钮)、JComboBox(组合框)、JList(下拉列表)和JColorChooser(颜色选择器)。这些组件提供了丰富的用户界面功能,...

    颜色对话框 swing (过期了)

    首先,Swing中的`JColorChooser`类是用来创建颜色选择对话框的核心。开发者可以使用`JColorChooser.showDialog()`方法来显示一个预设的颜色选择对话框。这个对话框包含了一个调色板,用户可以在其中选取或自定义颜色...

    精通 JAVASWING中文版

    在Java Swing中,你可以创建各种窗口应用程序,包括按钮、文本框、菜单、滚动面板等交互元素。Java Swing 提供了一种模型-视图-控制器(MVC)架构,使得开发桌面应用变得更加简单和灵活。 Java Swing 包含了大量的...

    Swing 扩展组件 Swing 扩展组件

    在Swing中,扩展组件是指那些超越了标准组件功能的类,它们提供了更复杂的行为或者更丰富的视觉效果。这些组件通常是基于Java基础组件,如JButton、JLabel和JTable等进行增强,以满足特定的用户需求。 例如,"Table...

    swing学习

    在Swing中,你可以创建复杂的、功能丰富的桌面应用程序,包括窗口、菜单、按钮、文本框等组件。Swing提供了丰富的可定制性,允许开发者通过调整外观和行为来满足特定需求。 Swing的学习主要涵盖以下几个核心知识点...

    Java-GUI编程之Swing组件.doc

    Border对象是Swing中的一种基本组件,用于设置组件的边框。Border对象可以是各种不同的边框样式,例如BevelBorder、LineBorder、EmptyBorder、EtchedBorder、TitledBorder等。这些边框可以单独使用,也可以组合使用...

    Java_Swing,2ndEdition

    2. **布局管理器**:如FlowLayout、BorderLayout、GridLayout、CardLayout以及各种复合布局的使用,帮助理解如何在Swing中组织组件。 3. **模型-视图-控制器(MVC)**:Swing是如何遵循这一设计模式的,以及如何...

    java颜色选择面板

    至于标签"水平",在Java Swing中,我们可以使用`BoxLayout`布局管理器来实现水平排列的组件。例如,如果你希望在颜色选择面板旁边还有其他组件,并保持水平排列,可以这样做: ```java JPanel panel = new JPanel...

    JavaSwing界面设计(所有控件及示例)

    Java Swing 是Java编程语言中用于构建图形用户界面(GUI)的一个强大的工具包。它是对早期的Abstract Window Toolkit (AWT) 的扩展,提供了更丰富的功能和更好的平台独立性。Swing 包含了大量的组件,使得开发者可以...

    Swing学习系列 -- Swing读书笔记目录

    Swing学习系列是Java开发中的一个重要部分,它是一种用于构建桌面应用程序的图形用户界面(GUI)工具包。这篇Swing读书笔记目录旨在帮助开发者更好地理解和掌握Swing的相关知识,通过阅读和学习,可以提升在Java GUI...

    Java写的Swing界面系统

    2. **容器与布局管理器**:在Swing中,JFrame是主窗口,它可包含多个组件。容器(如JPanel)用于组织和管理这些组件,而布局管理器(如FlowLayout、BorderLayout、GridLayout、CardLayout和GridBagLayout)则负责...

    swing界面设计文档

    Swing提供了诸如JOptionPane、JFileChooser和JColorChooser等对话框,方便进行警告、确认、选择文件或颜色等操作。 9. **Swing工具包(Swing Utilities)**: 提供了一些实用方法,如静态方法`SwingUtilities....

    Swing教程Swing教程下载

    2. **事件处理**:Swing中的事件模型基于观察者模式,事件监听器接口(如ActionListener、MouseListener和KeyListener)用于响应用户的交互操作。学习如何添加监听器并编写事件处理方法是Swing编程的关键。 3. **...

    java swing 2nd源码

    3. **Chapter05**:可能会讨论Swing中的菜单和工具栏设计,包括JMenu、JMenuBar、JMenuItem和JToolBar的用法。 4. **Chapter06**:可能涉及对话框(JOptionPane)、文件选择对话框(JFileChooser)和颜色选择对话框...

    swing学 习 资 料

    5. **对话框和通知**:Swing提供了各种对话框(JOptionPane)和通知组件(JOptionPane、JFileChooser、JColorChooser等)来增强用户交互。 6. **国际化支持**:Swing内置了对多语言支持的功能,开发者可以通过...

    Swing读书笔记

    - `JFrame`、`JDialog`、`JWindow`和`JApplet`等属于此类,它们是Swing中的特殊组件,虽然也继承自`JRootPane`,但它们的绘制需要使用本地系统资源。这是因为它们代表了窗口级别的组件,必须与底层操作系统进行交互...

Global site tag (gtag.js) - Google Analytics