/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.libraries.designtime.swing; import javax.swing.*; import javax.swing.event.ListDataEvent; import java.awt.event.ActionEvent; /** * A combobox that does not check whether a selected item is part of the model when the box is not editable. * * @author Thomas Morgner. */ public class SmartComboBox<T> extends JComboBox { private boolean selectingItem; /** * Creates a <code>JComboBox</code> that takes it's items from an existing <code>ComboBoxModel</code>. Since the * <code>ComboBoxModel</code> is provided, a combo box created using this constructor does not create a default combo * box model and may impact how the insert, remove and add methods behave. * * @param aModel the <code>ComboBoxModel</code> that provides the displayed list of items * @see javax.swing.DefaultComboBoxModel */ public SmartComboBox( final ComboBoxModel aModel ) { super( aModel ); } /** * Creates a <code>JComboBox</code> that contains the elements in the specified array. By default the first item in * the array (and therefore the data model) becomes selected. * * @param items an array of objects to insert into the combo box * @see javax.swing.DefaultComboBoxModel */ public SmartComboBox( final T[] items ) { super( items ); } /** * Creates a <code>JComboBox</code> with a default data model. The default data model is an empty list of objects. Use * <code>addItem</code> to add items. By default the first item in the data model becomes selected. * * @see javax.swing.DefaultComboBoxModel */ public SmartComboBox() { } /** * Sets the selected item in the combo box display area to the object in the argument. If <code>anObject</code> is in * the list, the display area shows <code>anObject</code> selected. * <p/> * If <code>anObject</code> is <i>not</i> in the list and the combo box is uneditable, it will not change the current * selection. For editable combo boxes, the selection will change to <code>anObject</code>. * <p/> * If this constitutes a change in the selected item, <code>ItemListener</code>s added to the combo box will be * notified with one or two <code>ItemEvent</code>s. If there is a current selected item, an <code>ItemEvent</code> * will be fired and the state change will be <code>ItemEvent.DESELECTED</code>. If <code>anObject</code> is in the * list and is not currently selected then an <code>ItemEvent</code> will be fired and the state change will be * <code>ItemEvent.SELECTED</code>. * <p/> * <code>ActionListener</code>s added to the combo box will be notified with an <code>ActionEvent</code> when this * method is called. * * @param anObject the list object to select; use <code>null</code> to clear the selection */ public void setSelectedItem( final Object anObject ) { final Object oldSelection = selectedItemReminder; if ( oldSelection == null || !oldSelection.equals( anObject ) ) { // Must toggle the state of this flag since this method // call may result in ListDataEvents being fired. selectingItem = true; dataModel.setSelectedItem( anObject ); selectingItem = false; if ( selectedItemReminder != dataModel.getSelectedItem() ) { // in case a users implementation of ComboBoxModel // doesn't fire a ListDataEvent when the selection // changes. selectedItemChanged(); } } fireActionEvent(); } /** * This method is public as an implementation side effect. do not call or override. */ public void actionPerformed( final ActionEvent e ) { if ( isEditable() ) { final Object newItem = getEditor().getItem(); setPopupVisible( false ); getModel().setSelectedItem( newItem ); } else { setPopupVisible( false ); } final String oldCommand = getActionCommand(); setActionCommand( "comboBoxEdited" ); fireActionEvent(); setActionCommand( oldCommand ); } /** * This method is public as an implementation side effect. do not call or override. */ public void contentsChanged( final ListDataEvent e ) { final Object oldSelection = selectedItemReminder; final Object newSelection = dataModel.getSelectedItem(); if ( oldSelection == null || !oldSelection.equals( newSelection ) ) { selectedItemChanged(); if ( !selectingItem ) { fireActionEvent(); } } } }