0001: /*
0002: * Copyright (c) 2002-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * o Redistributions of source code must retain the above copyright notice,
0008: * this list of conditions and the following disclaimer.
0009: *
0010: * o Redistributions in binary form must reproduce the above copyright notice,
0011: * this list of conditions and the following disclaimer in the documentation
0012: * and/or other materials provided with the distribution.
0013: *
0014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
0015: * its contributors may be used to endorse or promote products derived
0016: * from this software without specific prior written permission.
0017: *
0018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
0022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
0025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
0028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029: */
0030:
0031: package com.jgoodies.binding.tests;
0032:
0033: import java.beans.PropertyChangeEvent;
0034: import java.beans.PropertyChangeListener;
0035: import java.beans.PropertyVetoException;
0036: import java.util.ArrayList;
0037: import java.util.Arrays;
0038: import java.util.Collections;
0039: import java.util.List;
0040:
0041: import javax.swing.*;
0042: import javax.swing.event.ListDataEvent;
0043: import javax.swing.table.TableModel;
0044:
0045: import junit.framework.TestCase;
0046:
0047: import com.jgoodies.binding.adapter.AbstractTableAdapter;
0048: import com.jgoodies.binding.adapter.BasicComponentFactory;
0049: import com.jgoodies.binding.adapter.SingleListSelectionAdapter;
0050: import com.jgoodies.binding.beans.BeanAdapter;
0051: import com.jgoodies.binding.beans.Model;
0052: import com.jgoodies.binding.beans.PropertyAdapter;
0053: import com.jgoodies.binding.list.ArrayListModel;
0054: import com.jgoodies.binding.list.LinkedListModel;
0055: import com.jgoodies.binding.list.ObservableList;
0056: import com.jgoodies.binding.list.SelectionInList;
0057: import com.jgoodies.binding.tests.beans.VetoableChangeRejector;
0058: import com.jgoodies.binding.tests.event.ListDataReport;
0059: import com.jgoodies.binding.tests.event.PropertyChangeReport;
0060: import com.jgoodies.binding.tests.value.ValueHolderWithOldValueNull;
0061: import com.jgoodies.binding.value.AbstractValueModel;
0062: import com.jgoodies.binding.value.ValueHolder;
0063: import com.jgoodies.binding.value.ValueModel;
0064:
0065: /**
0066: * A test case for class {@link SelectionInList}.
0067: *
0068: * @author Karsten Lentzsch
0069: * @version $Revision: 1.44 $
0070: */
0071: public final class SelectionInListTest extends TestCase {
0072:
0073: private static final Object[] AN_ARRAY = { "one", "two", "three" };
0074:
0075: private DefaultListModel listModel;
0076:
0077: // Initialization *********************************************************
0078:
0079: @Override
0080: protected void setUp() throws Exception {
0081: super .setUp();
0082: listModel = createListModel(AN_ARRAY);
0083: }
0084:
0085: // Testing Constructors ***************************************************
0086:
0087: public void testConstructorRejectsNullListModelHolder() {
0088: try {
0089: new SelectionInList<Object>((ValueModel) null);
0090: fail("The SelectionInList must reject a null list holder.");
0091: } catch (NullPointerException e) {
0092: // The expected behavior.
0093: }
0094: }
0095:
0096: public void testConstructorRejectsNonIdentityCheckingValueHolder() {
0097: try {
0098: new SelectionInList<Object>(new ValueHolder(listModel));
0099: fail("The SelectionInList must reject list holders that have the idenity check is disabled.");
0100: } catch (IllegalArgumentException e) {
0101: // The expected behavior.
0102: }
0103: }
0104:
0105: public void testConstructorRejectsInvalidListHolderContent() {
0106: try {
0107: new SelectionInList<Object>(new ValueHolder("Hello", true));
0108: fail("The SelectionInList must reject list holder content other than List or ListModel.");
0109: } catch (ClassCastException e) {
0110: // The expected behavior.
0111: }
0112: }
0113:
0114: // Testing Setup **********************************************************
0115:
0116: public void testRejectNullSelectionIndex() {
0117: ValueHolder indexHolder = new ValueHolder(0);
0118: SelectionInList<String> sil = new SelectionInList<String>(
0119: listModel);
0120: sil.setSelectionIndexHolder(indexHolder);
0121: try {
0122: indexHolder.setValue(null);
0123: fail("The SelectionInList must reject null selection index values.");
0124: } catch (Exception e) {
0125: // The expected behavior.
0126: }
0127: }
0128:
0129: public void testRejectNewNullSelectionHolder() {
0130: SelectionInList<String> sil = new SelectionInList<String>(
0131: listModel);
0132: try {
0133: sil.setSelectionHolder(null);
0134: fail("The SelectionInList must reject a null selection holder.");
0135: } catch (Exception e) {
0136: // The expected behavior.
0137: }
0138: }
0139:
0140: public void testRejectNewNullSelectionIndexHolder() {
0141: SelectionInList<String> sil = new SelectionInList<String>(
0142: listModel);
0143: try {
0144: sil.setSelectionIndexHolder(null);
0145: fail("The SelectionInList must reject a null selection index holder.");
0146: } catch (Exception e) {
0147: // The expected behavior.
0148: }
0149: }
0150:
0151: public void testRejectNewSelectionIndexHolderWithNullValue() {
0152: SelectionInList<String> sil = new SelectionInList<String>(
0153: listModel);
0154: try {
0155: sil.setSelectionIndexHolder(new ValueHolder(null));
0156: fail("The SelectionInList must reject selection index holder with null values.");
0157: } catch (Exception e) {
0158: // The expected behavior.
0159: }
0160: }
0161:
0162: public void testSelectionIndexAfterInitialization() {
0163: Object value = "two";
0164: ValueModel selectionHolder = new ValueHolder(value);
0165: SelectionInList<String> sil = new SelectionInList<String>(
0166: listModel, selectionHolder);
0167: int initialSelectionIndex = sil.getSelectionIndex();
0168: assertEquals(
0169: "The initial selection index reflects the index of the selection holder's initial value.",
0170: listModel.indexOf(value), initialSelectionIndex);
0171: selectionHolder.setValue(null);
0172: assertEquals(
0173: "The selection index has been updated to indicate no selection.",
0174: -1, sil.getSelectionIndex());
0175: }
0176:
0177: public void testSelectionIndexValid() {
0178: SelectionInList<String> sil = new SelectionInList<String>(
0179: listModel);
0180: sil.setSelectionIndex(-1);
0181: for (int i = 0; i < sil.getSize() - 1; i++) {
0182: sil.setSelectionIndex(i);
0183: }
0184: sil.setList(null);
0185: sil.setSelectionIndex(-1);
0186: }
0187:
0188: public void testSelectionIndexLowerBound() {
0189: SelectionInList<String> sil = new SelectionInList<String>(
0190: listModel);
0191: try {
0192: sil.setSelectionIndex(-2);
0193: fail("A selection index < -1 must be rejected.");
0194: } catch (IndexOutOfBoundsException e) {
0195: // The expected behavior
0196: }
0197: }
0198:
0199: public void testSelectionIndexUpperBound() {
0200: SelectionInList<String> sil = new SelectionInList<String>(
0201: listModel);
0202: try {
0203: sil.setSelectionIndex(sil.getSize());
0204: fail("A selection index > list size must be rejected.");
0205: } catch (IndexOutOfBoundsException e) {
0206: // The expected behavior
0207: }
0208: sil.setList(null);
0209: try {
0210: sil.setSelectionIndex(0);
0211: fail("A selection index of 0 must be rejected for an empty or absent list.");
0212: } catch (IndexOutOfBoundsException e) {
0213: // The expected behavior
0214: }
0215: }
0216:
0217: public void testDefaultSelectionHolderChecksIdentity() {
0218: SelectionInList<String> sil = new SelectionInList<String>(
0219: listModel);
0220: // The following line will fail if the default selection holder
0221: // doesn't check the identity.
0222: BeanAdapter<String> adapter = new BeanAdapter<String>(sil
0223: .getSelectionHolder());
0224: assertEquals("The BeanAdapter's bean is the selection.", sil
0225: .getSelection(), adapter.getBean());
0226: }
0227:
0228: // Testing Bean Spec Compliance *******************************************
0229:
0230: public void testAcceptsNullOldValueInSelectionIndexPropertyChangeEvent() {
0231: int selectionIndex = 0;
0232: ValueHolder indexHolder = new ValueHolder(selectionIndex);
0233: SelectionInList<String> sil = new SelectionInList<String>(
0234: listModel);
0235: sil.setSelectionIndexHolder(indexHolder);
0236: indexHolder.fireValueChange(null, new Integer(selectionIndex));
0237: assertEquals("Selection index", selectionIndex, sil
0238: .getSelectionIndex());
0239: Object selection = listModel.get(selectionIndex);
0240: assertEquals("Selection", selection, sil.getSelection());
0241: }
0242:
0243: public void testAcceptsNullNewValueInSelectionIndexPropertyChangeEvent() {
0244: int selectionIndex = 0;
0245: ValueHolder indexHolder = new ValueHolder(selectionIndex);
0246: SelectionInList<String> sil = new SelectionInList<String>(
0247: listModel);
0248: sil.setSelectionIndexHolder(indexHolder);
0249: indexHolder.fireValueChange(new Integer(selectionIndex), null);
0250: assertEquals("Selection index", selectionIndex, sil
0251: .getSelectionIndex());
0252: Object selection = listModel.get(selectionIndex);
0253: assertEquals("Selection", selection, sil.getSelection());
0254: }
0255:
0256: public void testAcceptsNullOldAndNewValueInSelectionIndexPropertyChangeEvent() {
0257: int selectionIndex = 0;
0258: ValueHolder indexHolder = new ValueHolder(selectionIndex);
0259: SelectionInList<String> sil = new SelectionInList<String>(
0260: listModel);
0261: sil.setSelectionIndexHolder(indexHolder);
0262: indexHolder.fireValueChange(null, null);
0263: assertEquals("Selection index", selectionIndex, sil
0264: .getSelectionIndex());
0265: Object selection = listModel.get(selectionIndex);
0266: assertEquals("Selection", selection, sil.getSelection());
0267: }
0268:
0269: // ************************************************************************
0270:
0271: public void testFiresSelectionChangeOnlyForSelectionChanges() {
0272: int selectionIndex = 0;
0273: ValueHolder indexHolder = new ValueHolder(selectionIndex);
0274: SelectionInList<String> sil = new SelectionInList<String>(
0275: listModel);
0276: sil.setSelectionIndexHolder(indexHolder);
0277:
0278: // Create change reports.
0279: PropertyChangeReport valueReport = new PropertyChangeReport();
0280: PropertyChangeReport selectionReport = new PropertyChangeReport();
0281: PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
0282: PropertyChangeReport selectionIndexReport = new PropertyChangeReport();
0283:
0284: // Register change reports for value, selection, selection index,
0285: // and selectionEmpty
0286: sil.addValueChangeListener(valueReport);
0287: sil
0288: .addPropertyChangeListener(
0289: SelectionInList.PROPERTYNAME_SELECTION,
0290: selectionReport);
0291: sil.addPropertyChangeListener(
0292: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0293: selectionEmptyReport);
0294: sil.addPropertyChangeListener(
0295: SelectionInList.PROPERTYNAME_SELECTION_INDEX,
0296: selectionIndexReport);
0297:
0298: indexHolder.fireValueChange(null, new Integer(selectionIndex));
0299: indexHolder.fireValueChange(new Integer(selectionIndex), null);
0300: indexHolder.fireValueChange(null, null);
0301: assertEquals("No value change event fired", 0, valueReport
0302: .eventCount());
0303: assertEquals("No selection change event fired", 0,
0304: selectionReport.eventCount());
0305: assertEquals("No selectionEmpty change event fired", 0,
0306: selectionEmptyReport.eventCount());
0307: assertEquals("No selectionIndex change event fired", 0,
0308: selectionIndexReport.eventCount());
0309: }
0310:
0311: public void testIndexChangeFiresChangesWithNonNullOldValue() {
0312: int initialSelectionIndex = 0;
0313: int newSelectionIndex = 1;
0314: AbstractValueModel indexHolder = new ValueHolderWithOldValueNull(
0315: initialSelectionIndex);
0316: SelectionInList<String> sil = new SelectionInList<String>(
0317: listModel);
0318: sil.setSelectionIndexHolder(indexHolder);
0319:
0320: // Create change reports.
0321: PropertyChangeReport valueReport = new PropertyChangeReport();
0322: PropertyChangeReport selectionReport = new PropertyChangeReport();
0323: PropertyChangeReport selectionIndexReport = new PropertyChangeReport();
0324:
0325: // Register change reports for value, selection, selection index,
0326: // and selectionEmpty
0327: sil.addValueChangeListener(valueReport);
0328: sil
0329: .addPropertyChangeListener(
0330: SelectionInList.PROPERTYNAME_SELECTION,
0331: selectionReport);
0332: sil.addPropertyChangeListener(
0333: SelectionInList.PROPERTYNAME_SELECTION_INDEX,
0334: selectionIndexReport);
0335:
0336: // We change the selection index holder's value to the new index.
0337: // The ValueModel used for the selectionIndexHolder fires no old value.
0338: indexHolder.setValue(newSelectionIndex);
0339: Object oldValue = valueReport.lastOldValue();
0340: Object oldSelection = selectionReport.lastOldValue();
0341: Object oldSelectionIndex = selectionIndexReport.lastOldValue();
0342: assertTrue("Non-null old value in value change event",
0343: oldValue != null);
0344: assertTrue("Non-null old value in selection change event",
0345: oldSelection != null);
0346: assertTrue("Non-null old value in selectionIndex change event",
0347: oldSelectionIndex != null);
0348: }
0349:
0350: public void testSelectionForDirectSelectionIndexChanges() {
0351: SelectionInList<String> sil = new SelectionInList<String>(
0352: listModel);
0353:
0354: // Create change reports.
0355: PropertyChangeReport valueReport = new PropertyChangeReport();
0356: PropertyChangeReport selectionReport = new PropertyChangeReport();
0357: PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
0358: PropertyChangeReport selectionIndexReport = new PropertyChangeReport();
0359:
0360: // Register change reports for value, selection, selection index,
0361: // and selectionEmpty
0362: sil.addValueChangeListener(valueReport);
0363: sil
0364: .addPropertyChangeListener(
0365: SelectionInList.PROPERTYNAME_SELECTION,
0366: selectionReport);
0367: sil.addPropertyChangeListener(
0368: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0369: selectionEmptyReport);
0370: sil.addPropertyChangeListener(
0371: SelectionInList.PROPERTYNAME_SELECTION_INDEX,
0372: selectionIndexReport);
0373:
0374: assertEquals("The initial value is null.", null, sil.getValue());
0375: assertEquals("The initial selection is null.", null, sil
0376: .getSelection());
0377: assertTrue("The initial selection is empty.", sil
0378: .isSelectionEmpty());
0379: assertEquals("The initial selection index is -1.", -1, sil
0380: .getSelectionIndex());
0381:
0382: sil.setSelectionIndex(0);
0383: assertEquals("The new value is the first list element.",
0384: listModel.getElementAt(0), sil.getValue());
0385: assertEquals("The new selection is the first list element.",
0386: listModel.getElementAt(0), sil.getSelection());
0387: assertFalse("The selection is not empty.", sil
0388: .isSelectionEmpty());
0389: assertEquals("The new selection index is 0.", 0, sil
0390: .getSelectionIndex());
0391:
0392: assertEquals("selectionEmpty changed from true to false.", 1,
0393: selectionEmptyReport.eventCount());
0394: assertTrue("1) selectionEmpty change event oldValue == true.",
0395: selectionEmptyReport.lastOldBooleanValue());
0396: assertFalse(
0397: "1) selectionEmpty change event newValue == false.",
0398: selectionEmptyReport.lastNewBooleanValue());
0399:
0400: sil.setSelectionIndex(1);
0401: assertFalse("The selection index is 1 and not empty.", sil
0402: .isSelectionEmpty());
0403:
0404: assertEquals("No selectionEmpty change event fired", 1,
0405: selectionEmptyReport.eventCount());
0406:
0407: sil.clearSelection();
0408: assertTrue("The selection index is empty.", sil
0409: .isSelectionEmpty());
0410:
0411: assertEquals("selectionEmpty changed from false to true.", 2,
0412: selectionEmptyReport.eventCount());
0413: assertFalse(
0414: "2) selectionEmpty change event oldValue == false.",
0415: selectionEmptyReport.lastOldBooleanValue());
0416: assertTrue("2) selectionEmpty change event newValue == true.",
0417: selectionEmptyReport.lastNewBooleanValue());
0418:
0419: }
0420:
0421: public void testSelectionForIndirectSelectionIndexChanges() {
0422: SelectionInList<String> sil = new SelectionInList<String>(
0423: listModel);
0424: ValueHolder selectionIndexHolder = new ValueHolder(-1);
0425: sil.setSelectionIndexHolder(selectionIndexHolder);
0426: PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
0427: sil.addPropertyChangeListener(
0428: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0429: selectionEmptyReport);
0430:
0431: assertTrue("The initial selection is empty.", sil
0432: .isSelectionEmpty());
0433:
0434: selectionIndexHolder.setValue(0);
0435: assertFalse("The selection index is 0 and not empty.", sil
0436: .isSelectionEmpty());
0437:
0438: assertEquals("selectionEmpty changed from true to false.", 1,
0439: selectionEmptyReport.eventCount());
0440: assertTrue("1) selectionEmpty change event oldValue == true.",
0441: selectionEmptyReport.lastOldBooleanValue());
0442: assertFalse(
0443: "1) selectionEmpty change event newValue == false.",
0444: selectionEmptyReport.lastNewBooleanValue());
0445:
0446: selectionIndexHolder.setValue(1);
0447: assertFalse("The selection index is 1 and not empty.", sil
0448: .isSelectionEmpty());
0449:
0450: assertEquals("No selectionEmpty change event fired", 1,
0451: selectionEmptyReport.eventCount());
0452:
0453: selectionIndexHolder.setValue(-1);
0454: assertTrue("The selection index is empty.", sil
0455: .isSelectionEmpty());
0456:
0457: assertEquals("selectionEmpty changed from false to true.", 2,
0458: selectionEmptyReport.eventCount());
0459: assertFalse(
0460: "2) selectionEmpty change event oldValue == false.",
0461: selectionEmptyReport.lastOldBooleanValue());
0462: assertTrue("2) selectionEmpty change event newValue == true.",
0463: selectionEmptyReport.lastNewBooleanValue());
0464:
0465: }
0466:
0467: public void testSelectionForDirectSelectionChanges() {
0468: SelectionInList<String> sil = new SelectionInList<String>(
0469: listModel);
0470: PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
0471: sil.addPropertyChangeListener(
0472: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0473: selectionEmptyReport);
0474:
0475: sil.setSelection((String) listModel.getElementAt(0));
0476: assertFalse("The selection index is 0 and not empty.", sil
0477: .isSelectionEmpty());
0478:
0479: assertEquals("selectionEmpty changed from true to false.", 1,
0480: selectionEmptyReport.eventCount());
0481: assertTrue("1) selectionEmpty change event oldValue == true.",
0482: selectionEmptyReport.lastOldBooleanValue());
0483: assertFalse(
0484: "1) selectionEmpty change event newValue == false.",
0485: selectionEmptyReport.lastNewBooleanValue());
0486:
0487: sil.setSelection((String) listModel.getElementAt(1));
0488: assertFalse("The selection index is 1 and not empty.", sil
0489: .isSelectionEmpty());
0490:
0491: assertEquals("No selectionEmpty change event fired", 1,
0492: selectionEmptyReport.eventCount());
0493:
0494: sil.setSelection(null);
0495: assertTrue("The selection index is empty.", sil
0496: .isSelectionEmpty());
0497:
0498: assertEquals("selectionEmpty changed from false to true.", 2,
0499: selectionEmptyReport.eventCount());
0500: assertFalse(
0501: "2) selectionEmpty change event oldValue == false.",
0502: selectionEmptyReport.lastOldBooleanValue());
0503: assertTrue("2) selectionEmpty change event newValue == true.",
0504: selectionEmptyReport.lastNewBooleanValue());
0505:
0506: }
0507:
0508: public void testSelectionForIndirectSelectionChanges() {
0509: ValueModel selectionHolder = new ValueHolder();
0510: SelectionInList<String> sil = new SelectionInList<String>(
0511: new ValueHolder(listModel, true), selectionHolder);
0512: PropertyChangeReport selectionEmptyReport = new PropertyChangeReport();
0513: sil.addPropertyChangeListener(
0514: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0515: selectionEmptyReport);
0516:
0517: assertTrue("The selection index is -1 and empty.", sil
0518: .isSelectionEmpty());
0519: selectionHolder.setValue(listModel.getElementAt(0));
0520: assertFalse("The selection index is 0 and not empty.", sil
0521: .isSelectionEmpty());
0522:
0523: assertEquals("selectionEmpty changed from true to false.", 1,
0524: selectionEmptyReport.eventCount());
0525: assertTrue("1) selectionEmpty change event oldValue == true.",
0526: selectionEmptyReport.lastOldBooleanValue());
0527: assertFalse(
0528: "1) selectionEmpty change event newValue == false.",
0529: selectionEmptyReport.lastNewBooleanValue());
0530:
0531: selectionHolder.setValue(listModel.getElementAt(1));
0532: assertFalse("The selection index is 1 and not empty.", sil
0533: .isSelectionEmpty());
0534:
0535: assertEquals("No selectionEmpty change event fired", 1,
0536: selectionEmptyReport.eventCount());
0537:
0538: selectionHolder.setValue(null);
0539: assertTrue("The selection index is empty.", sil
0540: .isSelectionEmpty());
0541:
0542: assertEquals("selectionEmpty changed from false to true.", 2,
0543: selectionEmptyReport.eventCount());
0544: assertFalse(
0545: "2) selectionEmpty change event oldValue == false.",
0546: selectionEmptyReport.lastOldBooleanValue());
0547: assertTrue("2) selectionEmpty change event newValue == true.",
0548: selectionEmptyReport.lastNewBooleanValue());
0549:
0550: }
0551:
0552: // Selection In Synch With the Selection Index After List Operations ******
0553:
0554: public void testSelectionReflectsIndexAfterClear() {
0555: ValueModel selectionHolder = new ValueHolder();
0556: SelectionInList<String> sil = new SelectionInList<String>(
0557: new ValueHolder(listModel, true), selectionHolder);
0558: sil.setSelectionIndex(1);
0559: PropertyChangeReport changeReport = new PropertyChangeReport();
0560: sil.addPropertyChangeListener(
0561: SelectionInList.PROPERTYNAME_SELECTION, changeReport);
0562:
0563: assertEquals("SelectionHolder holds the second list element.",
0564: listModel.get(1), selectionHolder.getValue());
0565:
0566: listModel.clear();
0567: assertEquals("The selection index is -1.", -1, sil
0568: .getSelectionIndex());
0569: assertEquals("The selection is null.", null, sil.getSelection());
0570: assertEquals("The selection holder value is null.", null, sil
0571: .getSelectionHolder().getValue());
0572: assertEquals("A selection change event has been fired.", 1,
0573: changeReport.eventCount());
0574:
0575: // If this event provides an old value, it should be the old value.
0576: if (changeReport.lastOldValue() != null) {
0577: assertEquals("The selection change's old value is 'two'.",
0578: "two", changeReport.lastOldValue());
0579: }
0580: assertEquals("The selection change new value is null.", null,
0581: changeReport.lastNewValue());
0582: }
0583:
0584: public void testSelectionReflectsIndexAfterIndexMoveBack() {
0585: ValueModel selectionHolder = new ValueHolder();
0586: SelectionInList<String> sil = new SelectionInList<String>(
0587: new ValueHolder(listModel, true), selectionHolder);
0588: sil.setSelectionIndex(1);
0589: PropertyChangeReport changeReport = new PropertyChangeReport();
0590: sil.addPropertyChangeListener(
0591: SelectionInList.PROPERTYNAME_SELECTION, changeReport);
0592:
0593: Object initialSelection = listModel.get(1);
0594: assertEquals("SelectionHolder holds the second list element.",
0595: initialSelection, selectionHolder.getValue());
0596:
0597: listModel.remove(0);
0598: Object expectedSelection = listModel.get(0);
0599: assertEquals("The selection index has been decreased by 1.", 0,
0600: sil.getSelectionIndex());
0601: assertEquals("The selection remains unchanged.",
0602: expectedSelection, sil.getSelection());
0603: assertEquals("The selection holder value remains unchanged.",
0604: expectedSelection, sil.getSelectionHolder().getValue());
0605: assertEquals("No selection change event has been fired.", 0,
0606: changeReport.eventCount());
0607: }
0608:
0609: public void testSelectionReflectsIndexAfterIndexMoveForward() {
0610: ValueModel selectionHolder = new ValueHolder();
0611: SelectionInList<String> sil = new SelectionInList<String>(
0612: new ValueHolder(listModel, true), selectionHolder);
0613: sil.setSelectionIndex(1);
0614: PropertyChangeReport changeReport = new PropertyChangeReport();
0615: sil.addPropertyChangeListener(
0616: SelectionInList.PROPERTYNAME_SELECTION, changeReport);
0617:
0618: Object initialSelection = listModel.get(1);
0619: assertEquals("SelectionHolder holds the second list element.",
0620: initialSelection, selectionHolder.getValue());
0621:
0622: listModel.add(0, "zero");
0623: Object expectedSelection = listModel.get(2);
0624: assertEquals("The selection index has been increased by 1.", 2,
0625: sil.getSelectionIndex());
0626: assertEquals("The selection remains unchanged.",
0627: expectedSelection, sil.getSelection());
0628: assertEquals("The selection holder value remains unchanged.",
0629: expectedSelection, sil.getSelectionHolder().getValue());
0630: assertEquals("No selection change event has been fired.", 0,
0631: changeReport.eventCount());
0632: }
0633:
0634: // Properties Must be Changed Before the PropertyChangeEvent is Fired *****
0635:
0636: public void testSelectionChangeEventFiredAfterSelectionChange() {
0637: final SelectionInList<String> sil = new SelectionInList<String>(
0638: listModel);
0639: sil.getSelectionHolder().setValue("one");
0640: sil.addValueChangeListener(new PropertyChangeListener() {
0641: public void propertyChange(PropertyChangeEvent evt) {
0642: assertEquals("Value equals valueChange's new value.",
0643: sil.getValue(), evt.getNewValue());
0644: }
0645: });
0646: sil.addPropertyChangeListener(
0647: SelectionInList.PROPERTYNAME_SELECTION,
0648: new PropertyChangeListener() {
0649: public void propertyChange(PropertyChangeEvent evt) {
0650: assertEquals(
0651: "Selection equals selectionChange's new value.",
0652: sil.getSelection(), evt.getNewValue());
0653: }
0654: });
0655: sil.getSelectionHolder().setValue("two");
0656: }
0657:
0658: public void testSelectionEmptyChangeEventFiredAfterSelectionEmptyChange() {
0659: final SelectionInList<String> sil = new SelectionInList<String>(
0660: listModel);
0661: sil.getSelectionHolder().setValue("kuckuck");
0662: sil.addPropertyChangeListener(
0663: SelectionInList.PROPERTYNAME_SELECTION_EMPTY,
0664: new PropertyChangeListener() {
0665: public void propertyChange(PropertyChangeEvent evt) {
0666: assertEquals(
0667: "Selection empty equals selectionEmtpyChange's new value.",
0668: Boolean.valueOf(sil.isSelectionEmpty()),
0669: evt.getNewValue());
0670: }
0671: });
0672: sil.getSelectionHolder().setValue("two");
0673: }
0674:
0675: public void testSelectionIndexChangeEventFiredAfterSelectionIndexChange() {
0676: final SelectionInList<String> sil = new SelectionInList<String>(
0677: listModel);
0678: sil.getSelectionIndexHolder().setValue(new Integer(1));
0679: sil.addPropertyChangeListener(
0680: SelectionInList.PROPERTYNAME_SELECTION_INDEX,
0681: new PropertyChangeListener() {
0682: public void propertyChange(PropertyChangeEvent evt) {
0683: assertEquals(
0684: "Selection index equals selectionIndexChange's new value.",
0685: new Integer(sil.getSelectionIndex()),
0686: evt.getNewValue());
0687: }
0688: });
0689: sil.getSelectionIndexHolder().setValue(new Integer(2));
0690: }
0691:
0692: // ListModel Operations Affect the Selection and Selection Index **********
0693:
0694: public void testContentsChangedOnSelection() {
0695: SelectionInList<String> sil = new SelectionInList<String>(
0696: listModel);
0697: final int initialSelection = 2;
0698: sil.setSelectionIndex(initialSelection);
0699: assertEquals("Initial selection index", initialSelection, sil
0700: .getSelectionIndex());
0701: listModel.setElementAt("another", initialSelection);
0702: assertEquals(
0703: "Index after re-setting the element at selection index",
0704: initialSelection, sil.getSelectionIndex());
0705: assertEquals("sil value must be the updated element",
0706: "another", sil.getSelection());
0707: assertEquals("selectionHolder value must equal sil value", sil
0708: .getSelection(), sil.getSelectionHolder().getValue());
0709: }
0710:
0711: public void testIgnoreContentsChangedOnMinusOne() {
0712: testIgnoreContentsChanged(2, "another");
0713: }
0714:
0715: public void testIgnoreContentsChangedOnMinusOneEmptySelection() {
0716: testIgnoreContentsChanged(-1, "two");
0717: }
0718:
0719: private void testIgnoreContentsChanged(int silSelectionIndex,
0720: Object comboSelection) {
0721: ComboBoxModel comboBoxModel = new UnforgivingComboBoxModel(
0722: AN_ARRAY);
0723: SelectionInList<String> sil = new SelectionInList<String>(
0724: comboBoxModel);
0725: sil.setSelectionIndex(silSelectionIndex);
0726: Object silSelection = sil.getSelection();
0727: comboBoxModel.setSelectedItem(comboSelection);
0728: assertEquals("Initial selection index", silSelectionIndex, sil
0729: .getSelectionIndex());
0730: assertEquals("sil value must be unchanged", silSelection, sil
0731: .getSelection());
0732: }
0733:
0734: public void testInsertBeforeSelectionIncreasesSelectionIndex() {
0735: SelectionInList<String> sil = new SelectionInList<String>(
0736: listModel);
0737: final int initialSelection = 2;
0738: sil.setSelectionIndex(initialSelection);
0739: assertEquals("Initial selection index", initialSelection, sil
0740: .getSelectionIndex());
0741: listModel.insertElementAt("another", 0);
0742: assertEquals(
0743: "Index after inserting an element before the selection",
0744: initialSelection + 1, sil.getSelectionIndex());
0745: }
0746:
0747: public void testInsertBeforeSelectionKeepsSelection() {
0748: SelectionInList<String> sil = new SelectionInList<String>(
0749: listModel);
0750: sil.setSelectionIndex(2);
0751: assertEquals("Initial selection index", 2, sil
0752: .getSelectionIndex());
0753: Object selection = sil.getSelection();
0754: listModel.insertElementAt("another", 0);
0755: assertEquals("Selection after inserting an element", selection,
0756: sil.getSelection());
0757: }
0758:
0759: public void testInsertAfterSelectionKeepsSelectionIndex() {
0760: SelectionInList<String> sil = new SelectionInList<String>(
0761: listModel);
0762: final int initialSelection = 1;
0763: sil.setSelectionIndex(initialSelection);
0764: assertEquals("Initial selection index", initialSelection, sil
0765: .getSelectionIndex());
0766: listModel.insertElementAt("another", initialSelection + 1);
0767: assertEquals(
0768: "Index after inserting an element after the selection",
0769: initialSelection, sil.getSelectionIndex());
0770: }
0771:
0772: public void testRemoveBeforeSelectionDecreasesSelectionIndex() {
0773: SelectionInList<String> sil = new SelectionInList<String>(
0774: listModel);
0775: final int initialSelection = 2;
0776: sil.setSelectionIndex(initialSelection);
0777: assertEquals("Initial selection index", initialSelection, sil
0778: .getSelectionIndex());
0779: listModel.remove(0);
0780: assertEquals("Selection index after removing an element",
0781: initialSelection - 1, sil.getSelectionIndex());
0782: }
0783:
0784: public void testRemoveBeforeSelectionKeepsSelection() {
0785: SelectionInList<String> sil = new SelectionInList<String>(
0786: listModel);
0787: sil.setSelectionIndex(2);
0788: assertEquals("Initial selection index", 2, sil
0789: .getSelectionIndex());
0790: Object selection = sil.getSelection();
0791: listModel.remove(0);
0792: assertEquals("Selection after removing an element", selection,
0793: sil.getSelection());
0794: }
0795:
0796: /**
0797: * Removes the selected first element from a non-empty list and
0798: * checks whether the selection index is reset to -1.
0799: */
0800: public void testRemoveSelectedFirstElementResetsSelectionIndex() {
0801: SelectionInList<String> sil = new SelectionInList<String>(
0802: listModel);
0803: final int initialSelectionIndex = 0;
0804: sil.setSelectionIndex(initialSelectionIndex);
0805: assertEquals("Selection index before the remove action",
0806: initialSelectionIndex, sil.getSelectionIndex());
0807:
0808: listModel.remove(initialSelectionIndex);
0809: assertEquals(
0810: "Selection index after the removal of the selected element",
0811: -1, sil.getSelectionIndex());
0812: }
0813:
0814: /**
0815: * Removes the selected last element from a non-empty list and
0816: * checks whether the selection index is reset to -1.
0817: */
0818: public void testRemoveSelectedLastElementResetsSelectionIndex() {
0819: SelectionInList<String> sil = new SelectionInList<String>(
0820: listModel);
0821: final int initialSelectionIndex = listModel.getSize() - 1;
0822: sil.setSelectionIndex(initialSelectionIndex);
0823: assertEquals("Selection index before the remove action",
0824: initialSelectionIndex, sil.getSelectionIndex());
0825:
0826: listModel.remove(initialSelectionIndex);
0827: assertEquals(
0828: "Selection index after the removal of the selected element",
0829: -1, sil.getSelectionIndex());
0830: }
0831:
0832: public void testRemoveAfterSelectionKeepsSelectionIndex() {
0833: SelectionInList<String> sil = new SelectionInList<String>(
0834: listModel);
0835: final int initialSelectionIndex = 0;
0836: sil.setSelectionIndex(initialSelectionIndex);
0837: assertEquals("Initial selection index", initialSelectionIndex,
0838: sil.getSelectionIndex());
0839: listModel.remove(1);
0840: assertEquals("Selection index after removing an element",
0841: initialSelectionIndex, sil.getSelectionIndex());
0842: }
0843:
0844: // Keeping the Selection on List Changes **********************************
0845:
0846: /**
0847: * Changes the listHolder's (list) value and checks how
0848: * the SelectionInList keeps or resets the selection.
0849: * The listHolder is a <code>ValueHolder</code> that
0850: * reports an old and a new value.
0851: */
0852: public void testKeepsSelectionOnListChange() {
0853: testKeepsSelectionOnListChange(new ValueHolder(null, true),
0854: false);
0855: }
0856:
0857: /**
0858: * Changes the listHolder's (list) value and checks how
0859: * the SelectionInList keeps or resets the selection.
0860: * The listHolder is a <code>ValueHolder</code> that
0861: * reports an old and a new value.
0862: */
0863: public void testKeepsTableSelectionOnListChange() {
0864: testKeepsSelectionOnListChange(new ValueHolder(null, true),
0865: true);
0866: }
0867:
0868: /**
0869: * Changes the listHolder's (list) value and checks how
0870: * the SelectionInList keeps or resets the selection.
0871: * The listHolder is a <code>ForgetfulValueHolder</code> that
0872: * uses null as old value when reporting value changes.
0873: */
0874: public void testKeepsSelectionOnListChangeNoOldList() {
0875: testKeepsSelectionOnListChange(new ValueHolderWithOldValueNull(
0876: null), false);
0877: }
0878:
0879: /**
0880: * Changes the listHolder's (list) value and checks how
0881: * the SelectionInList keeps or resets the selection.
0882: * The listHolder is a <code>ForgetfulValueHolder</code> that
0883: * uses null as old value when reporting value changes.
0884: */
0885: public void testKeepsTableSelectionOnListChangeNoOldList() {
0886: testKeepsSelectionOnListChange(new ValueHolderWithOldValueNull(
0887: null), true);
0888: }
0889:
0890: /**
0891: * Changes the listHolder's (list) value and checks how
0892: * the SelectionInList keeps or resets the selection.
0893: * If specified, the SelectionInList will be bound to a JTable
0894: * using an AbstractTableAdapter and a SingleSelectionAdapter.
0895: * Since the JTable may clear the selection after some updates,
0896: * this tests if the selection is restored.
0897: *
0898: * @param listHolder the ValueModel that holds the list
0899: * @param bindToTable if true, the SelectionInList will be bound
0900: * to a JTable
0901: */
0902: private void testKeepsSelectionOnListChange(ValueModel listHolder,
0903: boolean bindToTable) {
0904: List<String> list1 = new ArrayList<String>();
0905: list1.add("One");
0906: list1.add("Two");
0907: list1.add("Three");
0908: List<String> list2 = new ArrayList<String>(list1);
0909: List<String> list3 = new ArrayList<String>();
0910: list3.add("Three");
0911: list3.add(new String("Two"));
0912: list3.add("One");
0913: List<String> list4 = new ArrayList<String>(list1);
0914: list4.add("Four");
0915: List<String> list5 = list1.subList(0, 2);
0916: List<String> list6 = new ArrayList<String>();
0917: list6.add("One");
0918: list6.add("Three");
0919: list6.add(new String("Two"));
0920:
0921: listHolder.setValue(list1);
0922: SelectionInList<String> sil = new SelectionInList<String>(
0923: listHolder);
0924: sil.setSelectionIndex(1);
0925: if (bindToTable) {
0926: TableModel tableModel = new AbstractTableAdapter<String>(
0927: sil, new String[] { "Name" }) {
0928:
0929: public Object getValueAt(int rowIndex, int columnIndex) {
0930: return getRow(rowIndex);
0931: }
0932: };
0933: JTable table = new JTable(tableModel);
0934: table.setSelectionModel(new SingleListSelectionAdapter(sil
0935: .getSelectionIndexHolder()));
0936: }
0937:
0938: Object oldSelection = sil.getSelection();
0939: assertEquals("List1: Selection is 'Two'.", "Two", oldSelection);
0940:
0941: listHolder.setValue(list2);
0942: assertEquals("List2: Selection index is still 1.", 1, sil
0943: .getSelectionIndex());
0944: assertEquals("List2: Selection is still 'Two'.", "Two", sil
0945: .getSelection());
0946:
0947: listHolder.setValue(list3);
0948: assertEquals("List3: Selection index is still 1.", 1, sil
0949: .getSelectionIndex());
0950: assertEquals("List3: Selection is still 'Two'.", "Two", sil
0951: .getSelection());
0952:
0953: listHolder.setValue(list4);
0954: assertEquals("List4: Selection index is still 1.", 1, sil
0955: .getSelectionIndex());
0956: assertEquals("List4: Selection is still 'Two'.", "Two", sil
0957: .getSelection());
0958:
0959: listHolder.setValue(list5);
0960: assertEquals("List5: Selection index is still 1.", 1, sil
0961: .getSelectionIndex());
0962: assertEquals("List5: Selection is still 'Two'.", "Two", sil
0963: .getSelection());
0964:
0965: listHolder.setValue(list6);
0966: assertEquals("List6: Selection index is now 2.", 2, sil
0967: .getSelectionIndex());
0968: assertEquals("List6: Selection is still 'Two'.", "Two", sil
0969: .getSelection());
0970:
0971: listHolder.setValue(new ArrayList<String>());
0972: assertEquals("Selection index is -1.", -1, sil
0973: .getSelectionIndex());
0974: assertEquals("Selection is null.", null, sil.getSelection());
0975:
0976: listHolder.setValue(list1);
0977: assertEquals("Selection index is still -1.", -1, sil
0978: .getSelectionIndex());
0979: assertEquals("Selection is still null.", null, sil
0980: .getSelection());
0981: }
0982:
0983: // List Change Events *****************************************************
0984:
0985: /**
0986: * Tests the SelectionInList ListDataEvents fired during list changes.
0987: * The transitions are {} -> {} -> {a, b} -> {b, c} -> {a, b, c} -> {}.
0988: */
0989: public void testListChangeEvents() {
0990: List<String> list1 = Collections.emptyList();
0991: List<String> list2 = Collections.emptyList();
0992: List<String> list3 = Arrays.asList("a", "b");
0993: List<String> list4 = Arrays.asList("b", "c");
0994: List<String> list5 = Arrays.asList("a", "b", "c");
0995: List<String> list6 = Collections.emptyList();
0996:
0997: SelectionInList<String> sil = new SelectionInList<String>(list1);
0998: ListDataReport report = new ListDataReport();
0999: sil.addListDataListener(report);
1000:
1001: sil.setList(list2);
1002: assertEquals("The transition {} -> {} fires no ListDataEvent.",
1003: 0, report.eventCount());
1004:
1005: report.clearEventList();
1006: sil.setList(list3);
1007: assertEquals("The transition {} -> {a, b} fires 1 add event.",
1008: 1, report.eventCount());
1009: assertEvent(
1010: "The transition {} -> {a, b} fires an add event with interval[0, 1].",
1011: ListDataEvent.INTERVAL_ADDED, 0, 1, report.lastEvent());
1012:
1013: report.clearEventList();
1014: sil.setList(list4);
1015: assertEquals(
1016: "The transition {a, b} -> {b, c} fires 1 add event.",
1017: 1, report.eventCount());
1018: assertEvent(
1019: "The transition {a, b} -> {b, c} fires an add event with interval[0, 1].",
1020: ListDataEvent.CONTENTS_CHANGED, 0, 1, report
1021: .lastEvent());
1022:
1023: report.clearEventList();
1024: sil.setList(list5);
1025: assertEquals(
1026: "The transition {a, b} -> {b, c, d} fires two events.",
1027: 2, report.eventCount());
1028: assertEvent(
1029: "The transition {b, c} -> {a, b, c} fires an add event with interval[2, 2].",
1030: ListDataEvent.INTERVAL_ADDED, 2, 2, report
1031: .previousEvent());
1032: assertEvent(
1033: "The transition {b, c} -> {a, b, c} fires a contents changed with interval[0, 1].",
1034: ListDataEvent.CONTENTS_CHANGED, 0, 1, report
1035: .lastEvent());
1036:
1037: report.clearEventList();
1038: sil.setList(list6);
1039: assertEquals("The transition {b, c, d} -> {} fires one event.",
1040: 1, report.eventCount());
1041: assertEvent(
1042: "The transition {b, c, d} -> {} fires a remove event with interval[0, 1].",
1043: ListDataEvent.INTERVAL_REMOVED, 0, 2, report
1044: .lastEvent());
1045: }
1046:
1047: private void assertEvent(String description, int eventType,
1048: int index0, int index1, ListDataEvent event) {
1049: assertEquals("Type: " + description, eventType, event.getType());
1050: assertEquals("Index0: " + description, index0, event
1051: .getIndex0());
1052: assertEquals("Index1: " + description, index1, event
1053: .getIndex1());
1054: }
1055:
1056: // Resetting the selection if the new list is empty or null
1057:
1058: public void testResetsSelectionIndexOnNullOrEmptyList() {
1059: SelectionInList<String> sil = new SelectionInList<String>(
1060: listModel);
1061: sil.setSelectionIndex(1);
1062:
1063: sil.setList(Collections.<String> emptyList());
1064: assertEquals("Selection index is -1.", -1, sil
1065: .getSelectionIndex());
1066: assertEquals("Selection is still null.", null, sil
1067: .getSelection());
1068:
1069: sil.setListModel(listModel);
1070: sil.setSelectionIndex(1);
1071: sil.setList(null);
1072: assertEquals("Selection index is -1.", -1, sil
1073: .getSelectionIndex());
1074: assertEquals("Selection is still null.", null, sil
1075: .getSelection());
1076: }
1077:
1078: // Firing ListDataEvents **************************************************
1079:
1080: /**
1081: * Checks that list data events from an underlying are reported
1082: * by the SelectionInList.
1083: */
1084: public void testFiresListModelListDataEvents() {
1085: PropertyChangeReport changeReport = new PropertyChangeReport();
1086: ListDataReport listDataReport1 = new ListDataReport();
1087: ListDataReport listDataReport2 = new ListDataReport();
1088:
1089: ArrayListModel<String> arrayListModel = new ArrayListModel<String>();
1090: SelectionInList<String> sil = new SelectionInList<String>(
1091: (ListModel) arrayListModel);
1092:
1093: arrayListModel.addListDataListener(listDataReport1);
1094: sil.addListDataListener(listDataReport2);
1095: sil.addValueChangeListener(changeReport);
1096:
1097: arrayListModel.add("One");
1098: assertEquals("No list change.", changeReport.eventCount(), 0);
1099: assertEquals("An element has been added.", listDataReport2
1100: .eventCount(), 1);
1101: assertEquals("An element has been added.", listDataReport2
1102: .eventCountAdd(), 1);
1103:
1104: arrayListModel.addAll(Arrays.asList(new String[] { "two",
1105: "three", "four" }));
1106: assertEquals("No list change.", changeReport.eventCount(), 0);
1107: assertEquals("An element block has been added.",
1108: listDataReport2.eventCount(), 2);
1109: assertEquals("An element block has been added.",
1110: listDataReport2.eventCountAdd(), 2);
1111:
1112: arrayListModel.remove(0);
1113: assertEquals("An element has been removed.", listDataReport2
1114: .eventCount(), 3);
1115: assertEquals("No element has been added.", listDataReport2
1116: .eventCountAdd(), 2);
1117: assertEquals("An element has been removed.", listDataReport2
1118: .eventCountRemove(), 1);
1119:
1120: arrayListModel.set(1, "newTwo");
1121: assertEquals("An element has been replaced.", listDataReport2
1122: .eventCount(), 4);
1123: assertEquals("No element has been added.", listDataReport2
1124: .eventCountAdd(), 2);
1125: assertEquals("No element has been removed.", listDataReport2
1126: .eventCountRemove(), 1);
1127: assertEquals("An element has been changed.", listDataReport2
1128: .eventCountChange(), 1);
1129:
1130: // Compare the event counts of the list models listener
1131: // with the SelectionInList listener.
1132: assertEquals("Add event counts are equal.", listDataReport1
1133: .eventCountAdd(), listDataReport2.eventCountAdd());
1134: assertEquals("Remove event counts are equal.", listDataReport1
1135: .eventCountRemove(), listDataReport2.eventCountRemove());
1136: assertEquals("Change event counts are equal.", listDataReport1
1137: .eventCountChange(), listDataReport2.eventCountChange());
1138: }
1139:
1140: // Registering, Deregistering and Registering of the ListDataListener *****
1141:
1142: /**
1143: * Checks and verifies that the SelectionInList registers
1144: * its ListDataListener with the underlying ListModel once only.
1145: * In other words: the SelectionInList doesn't register
1146: * its ListDataListener multiple times.<p>
1147: *
1148: * Uses a list holder that checks the identity and
1149: * reports an old and new value.
1150: */
1151: public void testSingleListDataListener() {
1152: testSingleListDataListener(new ValueHolder(null, true));
1153: }
1154:
1155: /**
1156: * Checks and verifies that the SelectionInList registers
1157: * its ListDataListener with the underlying ListModel once only.
1158: * In other words: the SelectionInList doesn't register
1159: * its ListDataListener multiple times.<p>
1160: *
1161: * Uses a list holder uses null as old value when reporting value changes.
1162: */
1163: public void testSingleListDataListenerNoOldList() {
1164: testSingleListDataListener(new ValueHolderWithOldValueNull(null));
1165: }
1166:
1167: /**
1168: * Checks and verifies that the SelectionInList registers
1169: * its ListDataListener with the underlying ListModel once only.
1170: * In other words: the SelectionInList doesn't register
1171: * its ListDataListener multiple times.
1172: */
1173: private void testSingleListDataListener(ValueModel listHolder) {
1174: new SelectionInList<String>(listHolder);
1175: ArrayListModel<String> listModel1 = new ArrayListModel<String>();
1176: LinkedListModel<String> listModel2 = new LinkedListModel<String>();
1177: listHolder.setValue(listModel1);
1178: assertEquals(
1179: "SelectionInList registered its ListDataListener.", 1,
1180: listModel1.getListDataListeners().length);
1181: listHolder.setValue(listModel1);
1182: assertEquals(
1183: "SelectionInList reregistered its ListDataListener.",
1184: 1, listModel1.getListDataListeners().length);
1185: listHolder.setValue(listModel2);
1186: assertEquals(
1187: "SelectionInList deregistered its ListDataListener.",
1188: 0, listModel1.getListDataListeners().length);
1189: assertEquals(
1190: "SelectionInList registered its ListDataListener.", 1,
1191: listModel2.getListDataListeners().length);
1192: }
1193:
1194: /**
1195: * Checks and verifies for a bunch of ListModel instances,
1196: * whether the ListDataListener has been reregistered properly.
1197: */
1198: public void testReregisterListDataListener() {
1199: ObservableList<Object> empty1 = new ArrayListModel<Object>();
1200: ObservableList<Object> empty2 = new ArrayListModel<Object>();
1201: testReregistersListDataListener(empty1, empty2);
1202:
1203: ObservableList<Object> empty3 = new LinkedListModel<Object>();
1204: ObservableList<Object> empty4 = new LinkedListModel<Object>();
1205: testReregistersListDataListener(empty3, empty4);
1206:
1207: ObservableList<Object> array1 = new ArrayListModel<Object>();
1208: ObservableList<Object> array2 = new ArrayListModel<Object>();
1209: array1.add(Boolean.TRUE);
1210: array2.add(Boolean.TRUE);
1211: testReregistersListDataListener(array1, array2);
1212:
1213: ObservableList<Object> linked1 = new LinkedListModel<Object>();
1214: ObservableList<Object> linked2 = new LinkedListModel<Object>();
1215: linked1.add(Boolean.TRUE);
1216: linked2.add(Boolean.TRUE);
1217: testReregistersListDataListener(linked1, linked2);
1218: }
1219:
1220: /**
1221: * Checks and verifies whether the ListDataListener has been
1222: * reregistered properly. This will fail if the change support
1223: * fails to fire a change event when the instance changes.<p>
1224: *
1225: * Creates a SelectionInList on list1, then changes it to list2,
1226: * modifies boths lists, and finally checks whether the SelectionInList
1227: * has fired the correct events.
1228: */
1229: private void testReregistersListDataListener(
1230: ObservableList<Object> list1, ObservableList<Object> list2) {
1231: ListDataReport listDataReport1 = new ListDataReport();
1232: ListDataReport listDataReport2 = new ListDataReport();
1233: ListDataReport listDataReportSel = new ListDataReport();
1234:
1235: SelectionInList<Object> sil = new SelectionInList<Object>(
1236: (ListModel) list1);
1237:
1238: // Change the list model.
1239: // Changes on list1 shall not affect the SelectionInList.
1240: // Changes in list2 shall be the same as for the SelectionInList.
1241: sil.setListModel(list2);
1242:
1243: list1.addListDataListener(listDataReport1);
1244: list2.addListDataListener(listDataReport2);
1245: sil.addListDataListener(listDataReportSel);
1246:
1247: // Modify both list models.
1248: list1.add("one1");
1249: list1.add("two1");
1250: list1.add("three1");
1251: list1.add("four1");
1252: list1.remove(1);
1253: list1.remove(0);
1254: list1.set(0, "newOne1");
1255: list1.set(1, "newTwo1");
1256:
1257: assertEquals("Events counted for list model 1", 8,
1258: listDataReport1.eventCount());
1259: assertEquals("No events counted for list model 2", 0,
1260: listDataReport2.eventCount());
1261: assertEquals("No events counted for the SelectionInList", 0,
1262: listDataReportSel.eventCount());
1263:
1264: list2.add("one2");
1265: list2.add("two2");
1266: list2.add("three2");
1267: list2.remove(1);
1268: list2.set(0, "newOne2");
1269:
1270: assertEquals("Events counted for list model 2", 5,
1271: listDataReport2.eventCount());
1272: assertEquals("Events counted for the SelectionInList", 5,
1273: listDataReportSel.eventCount());
1274:
1275: // Compare the event lists.
1276: assertEquals("Events for list2 and SelectionInList differ.",
1277: listDataReport2, listDataReportSel);
1278: }
1279:
1280: // Handling Vetoes *********************************************************
1281:
1282: public void testHandlesVetoedIndexChange() {
1283: ConstrainedIndexBean cib = new ConstrainedIndexBean(0);
1284: ValueModel selectionHolder = new ValueHolder();
1285: ValueModel indexHolder = new PropertyAdapter<ConstrainedIndexBean>(
1286: cib, "index", true);
1287: SelectionInList<ConstrainedIndexBean> sil = new SelectionInList<ConstrainedIndexBean>(
1288: listModel, selectionHolder, indexHolder);
1289: JComboBox combo = BasicComponentFactory.createComboBox(sil);
1290: assertEquals("Initial bean index is SelectionInList index.",
1291: cib.getIndex(), sil.getSelectionIndex());
1292: sil.setSelectionIndex(1);
1293: assertEquals("Changed bean index is SelectionInList index.",
1294: cib.getIndex(), sil.getSelectionIndex());
1295: assertEquals("Changed bean index is combo index.", cib
1296: .getIndex(), combo.getSelectedIndex());
1297: cib.addVetoableChangeListener(new VetoableChangeRejector());
1298: sil.setSelectionIndex(2);
1299: assertEquals("Old bean index is SelectionInList index.", cib
1300: .getIndex(), sil.getSelectionIndex());
1301: assertEquals("Old bean index is combo index.", cib.getIndex(),
1302: combo.getSelectedIndex());
1303: }
1304:
1305: // Helper Code ************************************************************
1306:
1307: private DefaultListModel createListModel(Object[] array) {
1308: DefaultListModel model = new DefaultListModel();
1309: for (Object element : array) {
1310: model.addElement(element);
1311: }
1312: return model;
1313: }
1314:
1315: /**
1316: * A DefaultComboBoxModel that fires when accessing illegal
1317: * index (instead of silently returning null).
1318: * DefaultCombo is mad anyway - should return the selected item on -1...
1319: */
1320: private static final class UnforgivingComboBoxModel extends
1321: DefaultComboBoxModel {
1322:
1323: UnforgivingComboBoxModel(Object[] elements) {
1324: super (elements);
1325: }
1326:
1327: @Override
1328: public Object getElementAt(int index) {
1329: if ((index < 0) || (index >= getSize()))
1330: throw new ArrayIndexOutOfBoundsException(index);
1331: return super .getElementAt(index);
1332: }
1333: }
1334:
1335: public static final class ConstrainedIndexBean extends Model {
1336:
1337: private int index;
1338:
1339: ConstrainedIndexBean(int index) {
1340: this .index = index;
1341: }
1342:
1343: public int getIndex() {
1344: return index;
1345: }
1346:
1347: public void setIndex(int newValue) throws PropertyVetoException {
1348: int oldValue = getIndex();
1349: fireVetoableChange("index", oldValue, newValue);
1350: index = newValue;
1351: firePropertyChange("index", oldValue, newValue);
1352: }
1353:
1354: }
1355:
1356: }
|