alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 */
package org.openide.util;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.EventListener;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import junit.textui.TestRunner;
import org.openide.util.Utilities;
import org.netbeans.junit.NbTestCase;
import org.netbeans.junit.NbTestSuite;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.util.AsyncGUIJob;

/**
 *
 * @author Dafe Simonek
 */
public class InitJobTest extends NbTestCase {
    /** testing dialog instance */
    Dialog dlg;
    /** arrays which hold calls history */
    ArrayList constructCalls, finishCalls, cancelCalls;
    /** event dispatch thread */
    Thread edThread;
    /** test component */
    SimpleInitComp comp;
    
    /** Creates a new instance of UtilProgressCursorTest */
    public InitJobTest(String testName) {
        super(testName);
    }

    public static void main(java.lang.String[] args) {
        TestRunner.run(new NbTestSuite(InitJobTest.class));
    }

    /** Basic testing of Utilities.attachInitJob, if calls to AsyncGUIJob
     * impl conforms to the API behaviour described in javadoc *
     */
    public void testInitJob () throws Exception {
        initializeSimple();
        comp = new SimpleInitComp();
        Utilities.attachInitJob(comp, comp);
        DialogDescriptor descriptor = new DialogDescriptor(comp, "Testing dialog");
        dlg = DialogDisplayer.getDefault().createDialog(descriptor);
        dlg.setVisible(true);
    }
    
    public void testCancelAbility () throws Exception {
        initializeSimple();
        initCancelResults();
        CancelInitComp comp = new CancelInitComp();
        Utilities.attachInitJob(comp, comp);
        DialogDescriptor descriptor = new DialogDescriptor(comp, "Testing init cancel dialog");
        dlg = DialogDisplayer.getDefault().createDialog(descriptor);
        dlg.setVisible(true);
    }
    
    
    /**********************************************************************/    
    
    private void constructCalled (Thread thread, long time) {
        constructCalls.add(new CallData(thread, time));
    }
    
    private void finishCalled (Thread thread, long time) {
        finishCalls.add(new CallData(thread, time));
    }
    
    private void cancelCalled () {
        cancelCalls.add(new CallData(Thread.currentThread(), System.currentTimeMillis()));
    }
    
    private void checkSimpleResults () {
        if (constructCalls.size() != 1) {
            fail("AsyncGUIJob.construct was called " + constructCalls.size() +
                 " times intead of just once.");
        }
        if (finishCalls.size() != 1) {
            fail("AsyncGUIJob.finish was called " + finishCalls.size() +
                 " times intead of just once.");
        }
        CallData constructCall = (CallData)constructCalls.get(0);
        CallData finishCall = (CallData)finishCalls.get(0);
        if (constructCall.thread.equals(edThread)) {
            fail("AsyncGUIJob.construct *was* called from event dispatch thread, " +
                 "which is wrong.");
        }
        if (!finishCall.thread.equals(edThread)) {
            fail("AsyncGUIJob.finish *was not* called from event dispatch thread, " +
                 "which is wrong.");
        }
        if (constructCall.time > finishCall.time) {
            fail("AsyncGUIJob.finish was called before AsyncGUIJob.construct, " +
                 "which is wrong.");
        }
        /** getAWTEventListeners exists only in jdk 1.4 and higher
        AWTEventListener[] awtListeners = 
            Toolkit.getDefaultToolkit().getAWTEventListeners(AWTEvent.PAINT_EVENT_MASK);
        for (int i = 0; i < awtListeners.length; i++) {
            if (awtListeners[i].getClass().equals(AsyncInitSupport.class)) {
                fail("Probable memory leak: AsyncInitSupport didn't detached " +
                     "from AWT toolkit.");
            }
        }
         **/
        EventListener[] listeners = comp.getListeners(AsyncInitSupport.class);
        if (listeners.length != 0) {
            fail("Probable memory leak: AsyncInitSupport didn't detached " +
                 "from component being inited " + comp);
        }
    }
    
    private void checkCancelResults () {
        if (cancelCalls.size() != 1) {
            fail("Cancellable.cancel was called " + cancelCalls.size() +
                 " times intead of just once.");
        }
        if (finishCalls.size() != 0) {
            fail("AsyncGUIJob.finish should not been called at all, but was called "
                  + finishCalls.size() + " times.");
        }
        
        
    }
    
    private void initializeSimple () throws Exception {
        constructCalls = new ArrayList();
        finishCalls = new ArrayList();
        SwingUtilities.invokeAndWait(new Runnable () {
            public void run () {
                edThread = Thread.currentThread();
            }
        });
    }
    
    private void initCancelResults () {
        cancelCalls = new ArrayList();
    }

    /** Structure for holding data of method call */
    private final static class CallData {
        Thread thread;
        long time;
        
        public CallData (Thread thread, long time) {
            this.thread = thread;
            this.time = time;
        }
    }
    
    private final class TimerListener implements ActionListener {
        /** true for cancel test, false otherwise */
        private boolean cancel;
        public TimerListener (boolean cancel) {
            this.cancel = cancel;
        }
        public void actionPerformed(ActionEvent e) {
            dlg.dispose();
            if (cancel) {
                checkCancelResults();
            } else {
                checkSimpleResults();
            }
        }
    }
    
    /** Testing component for asynchronous init 
     */
    private final class SimpleInitComp extends JPanel implements AsyncGUIJob {
        
        /** Worker method, can be called in any thread but event dispatch thread.
         * Implement your time consuming work here.
         * Always called and completed before {@link #finished} method.
         *
         */
        public void construct() {
            constructCalled(Thread.currentThread(), System.currentTimeMillis());
        }
        
        /** Method to update UI using given data constructed in {@link #construct}
         * method. Always called in event dispatch thread, after {@link #construct}
         * method completed its execution.
         *
         */
        public void finished() {
            finishCalled(Thread.currentThread(), System.currentTimeMillis());
        }
        
        public void paint(Graphics g) {
            super.paint(g);
            Timer timer = new Timer(1000, new TimerListener(false));
            timer.setRepeats(false);
            timer.start();
        }
        
    } // end of SimpleInitComp
    
    /** Testing component for cancel during asynchronous init 
     */
    private final class CancelInitComp extends JPanel implements AsyncGUIJob, Cancellable {
        
        /** Worker method, can be called in any thread but event dispatch thread.
         * Implement your time consuming work here.
         * Always called and completed before {@link #finished} method.
         *
         */
        public void construct() {
            // perform loooong task
            try {
                Thread.sleep(2000);
            } catch (InterruptedException exc) {
                // continue...
            }
        }
        
        /** Method to update UI using given data constructed in {@link #construct}
         * method. Always called in event dispatch thread, after {@link #construct}
         * method completed its execution.
         *
         */
        public void finished() {
            finishCalled(Thread.currentThread(), System.currentTimeMillis());
        }
        
        public void paint(Graphics g) {
            super.paint(g);
            Timer timer = new Timer(1000, new TimerListener(true));
            timer.setRepeats(false);
            timer.start();
        }
        
        /** Cancel processing of the job.
         *
         */
        public boolean cancel() {
            cancelCalled();
            return true;
        }
        
    } // end of SimpleInitComp

}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.