/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.uitools.swing; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.AbstractListModel; import javax.swing.ListModel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; /** * This wrapper extends a ListModel with fixed lists of items on either end. * * NB: Be careful using or wrapping this list model, since the "extended" * items may be unexpected by the client code or wrapper. */ public class ExtendedListModel extends AbstractListModel implements ListModel { // **************** Variables ********************************************* /** The wrapped list model */ protected ListModel listModel; /** The items "prepended" to the wrapped model */ protected List prefix; /** The items "appended" to the wrapped model */ protected List suffix; // **************** Constructors ****************************************** /** * Extend the specified list model with a prefix and suffix. */ public ExtendedListModel(List prefix, ListModel listModel, List suffix) { super(); this.initialize(listModel); this.prefix = new ArrayList(prefix); this.suffix = new ArrayList(suffix); } /** * Extend the specified list model with a singleton prefix and suffix. */ public ExtendedListModel(Object prefix, ListModel listModel, Object suffix) { this(Collections.singletonList(prefix), listModel, Collections.singletonList(suffix)); } /** * Extend the specified list model with a prefix. */ public ExtendedListModel(List prefix, ListModel listModel) { this(prefix, listModel, Collections.EMPTY_LIST); } /** * Extend the specified list model with a singleton prefix. */ public ExtendedListModel(Object prefix, ListModel listModel) { this(Collections.singletonList(prefix), listModel, Collections.EMPTY_LIST); } /** * Extend the specified list model with a suffix. */ public ExtendedListModel(ListModel listModel, List suffix) { this(Collections.EMPTY_LIST, listModel, suffix); } /** * Extend the specified list with a singleton suffix. */ public ExtendedListModel(ListModel listModel, Object suffix) { this(Collections.EMPTY_LIST, listModel, Collections.singletonList(suffix)); } /** * Extend the specified list model with a prefix containing a single null item. */ public ExtendedListModel(ListModel listModel) { this(Collections.singletonList(null), listModel, Collections.EMPTY_LIST); } // **************** Initialization **************************************** protected void initialize(ListModel model) { this.listModel = model; this.listModel.addListDataListener(this.buildListDataListener()); } protected ListDataListener buildListDataListener() { return new ListDataListener() { public void intervalAdded(ListDataEvent e) { ExtendedListModel.this.intervalAdded(e); } public void intervalRemoved(ListDataEvent e) { ExtendedListModel.this.intervalRemoved(e); } public void contentsChanged(ListDataEvent e) { ExtendedListModel.this.contentsChanged(e); } public String toString() { return "list data listener"; } }; } void intervalAdded(ListDataEvent e) { // Add prefix size to indices int prefixSize = this.prefix.size(); this.fireIntervalAdded(this, e.getIndex0() + prefixSize, e.getIndex1() + prefixSize); } void intervalRemoved(ListDataEvent e) { // Add prefix size to indices int prefixSize = this.prefix.size(); this.fireIntervalRemoved(this, e.getIndex0() + prefixSize, e.getIndex1() + prefixSize); } void contentsChanged(ListDataEvent e) { // Add prefix size to indices, unless the index is -1, // because for some reason, -1 is special int prefixSize = this.prefix.size(); int newIndex0 = (e.getIndex0() == -1) ? -1 : e.getIndex0() + prefixSize; int newIndex1 = (e.getIndex1() == -1) ? -1 : e.getIndex1() + prefixSize; this.fireContentsChanged(this, newIndex0, newIndex1); } // **************** ListModel implementation ****************************** public int getSize() { return this.prefix.size() + this.listModel.getSize() + this.suffix.size(); } public Object getElementAt(int index) { int prefixSize = this.prefix.size(); if (index < prefixSize) { return this.prefix.get(index); } else if (index >= prefixSize + this.listModel.getSize()) { return this.suffix.get(index - (prefixSize + this.listModel.getSize())); } else { return this.listModel.getElementAt(index - prefixSize); } } }