/* * Copyright (c) 2011, Nikolaus Moll, Michael Grossmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.api.test; import java.util.LinkedList; import java.util.List; import org.jowidgets.api.controller.IDisposeListener; import org.jowidgets.api.toolkit.Toolkit; import org.jowidgets.api.widgets.IActionMenuItem; import org.jowidgets.api.widgets.IButton; import org.jowidgets.api.widgets.IComposite; import org.jowidgets.api.widgets.IContainer; import org.jowidgets.api.widgets.IControl; import org.jowidgets.api.widgets.IFrame; import org.jowidgets.api.widgets.IMainMenu; import org.jowidgets.api.widgets.IMenuBar; import org.jowidgets.api.widgets.IMenuItem; import org.jowidgets.api.widgets.ITabFolder; import org.jowidgets.api.widgets.ITabItem; import org.jowidgets.api.widgets.ITree; import org.jowidgets.api.widgets.ITreeNode; import org.jowidgets.api.widgets.IWidget; import org.jowidgets.api.widgets.blueprint.IActionMenuItemBluePrint; import org.jowidgets.api.widgets.blueprint.ITabItemBluePrint; import org.jowidgets.api.widgets.blueprint.factory.IBluePrintFactory; import org.jowidgets.common.application.IApplication; import org.jowidgets.common.application.IApplicationLifecycle; import org.jowidgets.common.widgets.descriptor.IWidgetDescriptor; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class WidgetDisposeTest { private static final IBluePrintFactory BPF = Toolkit.getBluePrintFactory(); private List<DisposeListener> disposeListeners; @Before public void before() { disposeListeners = new LinkedList<DisposeListener>(); } @After public void after() { disposeListeners = null; } @Test public void testAddAndDispose() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final IButton button = createWidget(frame, BPF.button()); final int sizeBefore = frame.getChildren().size(); button.dispose(); Assert.assertEquals(sizeBefore - 1, frame.getChildren().size()); Assert.assertFalse(frame.getChildren().contains(button)); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testMultipleDisposal() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final IButton button = createWidget(frame, BPF.button()); button.dispose(); button.dispose(); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testChildWindowDisposal() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final IFrame childWindow = frame.createChildWindow(BPF.frame()); childWindow.addDisposeListener(new DisposeListener(childWindow)); createWidget(childWindow, BPF.button()); createWidget(childWindow, BPF.textLabel()); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testMenuBarDisposal() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.setVisible(true); frame.addDisposeListener(new DisposeListener(frame)); final IMenuBar menuBar = frame.createMenuBar(); menuBar.addDisposeListener(new DisposeListener(menuBar)); final IMainMenu menu1 = createMenu(menuBar, "Menu 1"); final IMainMenu menu2 = createMenu(menuBar, "Menu 2"); final IMenuItem item1 = createMenuItem(menu1, BPF.menuItem("Item 1")); // TODO MG,NM don't know how to create a cascaded menu without models menu1.dispose(); Assert.assertTrue(item1.isDisposed()); Assert.assertFalse(menu2.isDisposed()); menuBar.dispose(); Assert.assertTrue(menu2.isDisposed()); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testDisposeMenuItem() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.setVisible(true); final IMenuBar menuBar = frame.createMenuBar(); final IMainMenu menu = menuBar.addMenu("menu"); Assert.assertTrue(menuBar.getMenus().contains(menu)); final IActionMenuItem item = menu.addItem(BPF.menuItem()); Assert.assertTrue(menu.getChildren().contains(item)); item.dispose(); Assert.assertFalse(menu.getChildren().contains(item)); menu.dispose(); Assert.assertFalse(menuBar.getMenus().contains(menu)); frame.dispose(); } }); } @Test public void testMenuModel() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.setVisible(true); frame.addDisposeListener(new DisposeListener(frame)); // TODO MG,NM don't know how to add a model and dispose the items then: // add model several times, dispose one menu, check if other menus still work frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testManyWidgetsDisposal() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); createWidget(frame, BPF.button()); createWidget(frame, BPF.calendar()); createWidget(frame, BPF.checkBox()); createWidget(frame, BPF.comboBox()); createWidget(frame, BPF.composite()); createWidget(frame, BPF.inputFieldDate()); createWidget(frame, BPF.label()); createWidget(frame, BPF.scrollComposite()); final ITabFolder tabFolder = createWidget(frame, BPF.tabFolder()); final ITabItem tabItem1 = createTabItem(tabFolder, BPF.tabItem()); createTabItem(tabFolder, BPF.tabItem()); createTabItem(tabFolder, BPF.tabItem()); createTabItem(tabFolder, BPF.tabItem()); tabItem1.dispose(); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testMultiContainerDisposal() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final IComposite parentComposite = frame.add(BPF.composite()); parentComposite.addDisposeListener(new DisposeListener(parentComposite)); final IComposite childComposite = parentComposite.add(BPF.composite()); childComposite.addDisposeListener(new DisposeListener(childComposite)); childComposite.dispose(); Assert.assertFalse(parentComposite.getChildren().contains(childComposite)); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testTree() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final ITree tree = createWidget(frame, BPF.tree()); final ITreeNode rootNode = createNode(tree); createNode(createNode(rootNode)); createNode(createNode(rootNode)); createNode(createNode(rootNode)); final ITreeNode subNode1 = createNode(rootNode); final ITreeNode subSubNode1 = createNode(subNode1); final ITreeNode subSubSubNode1 = createNode(subSubNode1); subNode1.dispose(); Assert.assertTrue(subSubNode1.isDisposed()); Assert.assertTrue(subSubSubNode1.isDisposed()); frame.dispose(); testDisposeListenerCount(); } }); } @Test public void testTabFolder() { Toolkit.getApplicationRunner().run(new IApplication() { @Override public void start(final IApplicationLifecycle lifecycle) { final IFrame frame = Toolkit.createRootFrame(BPF.frame(), lifecycle); frame.addDisposeListener(new DisposeListener(frame)); frame.setVisible(true); final ITabFolder tabFolder = createWidget(frame, BPF.tabFolder()); final ITabItem tabItem1 = createTabItem(tabFolder, BPF.tabItem()); createTabItem(tabFolder, BPF.tabItem()); createTabItem(tabFolder, BPF.tabItem()); final IControl control = createWidget(tabItem1, BPF.button()); Assert.assertFalse(control.isDisposed()); tabItem1.dispose(); Assert.assertTrue(control.isDisposed()); frame.dispose(); testDisposeListenerCount(); } }); } private <WIDGET_TYPE extends IControl> WIDGET_TYPE createWidget( final IContainer container, final IWidgetDescriptor<? extends WIDGET_TYPE> descriptor) { final WIDGET_TYPE result = container.add(descriptor); result.addDisposeListener(new DisposeListener(result)); return result; } private ITabItem createTabItem(final ITabFolder tabFolder, final ITabItemBluePrint descriptor) { final ITabItem result = tabFolder.addItem(descriptor); result.addDisposeListener(new DisposeListener(result)); return result; } private ITreeNode createNode(final ITree tree) { final ITreeNode result = tree.addNode(); result.addDisposeListener(new DisposeListener(result)); return result; } private ITreeNode createNode(final ITreeNode treeNode) { final ITreeNode result = treeNode.addNode(); result.addDisposeListener(new DisposeListener(result)); return result; } private IMainMenu createMenu(final IMenuBar menuBar, final String text) { final IMainMenu result = menuBar.addMenu(text); result.addDisposeListener(new DisposeListener(result)); return result; } private IMenuItem createMenuItem(final IMainMenu menu1, final IActionMenuItemBluePrint menuItemBp) { final IMenuItem result = menu1.addItem(menuItemBp); result.addDisposeListener(new DisposeListener(result)); return result; } private void testDisposeListenerCount() { for (final DisposeListener disposeListener : disposeListeners) { Assert.assertEquals(1, disposeListener.disposeCount); } } final class DisposeListener implements IDisposeListener { private final IWidget widget; private int disposeCount; DisposeListener(final IWidget widget) { disposeListeners.add(this); this.widget = widget; this.disposeCount = 0; } @Override public void onDispose() { Assert.assertFalse(widget.isDisposed()); disposeCount++; } } }