/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI 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 at gnu.org.
*/
package com.eviware.x.form.support;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.components.JXToolBar;
import com.eviware.x.form.XFormOptionsField;
import com.eviware.x.impl.swing.AbstractSwingXFormField;
/**
* Swing-Specific multi-select list
*
* @author ole.matzura
*/
public class XFormMultiSelectList extends AbstractSwingXFormField<JPanel> implements XFormOptionsField
{
private JList list;
private DefaultListModel listModel;
private List<Boolean> selected = new ArrayList<Boolean>();
PropertyChangeSupport pcs = new PropertyChangeSupport( this );
private int[] defaultIndex;
private Color defaultColor;
private SelectAllAction selectAllAction;
private UnselectAllAction unselectAllAction;
public XFormMultiSelectList( String[] values )
{
super( new JPanel( new BorderLayout() ) );
listModel = new DefaultListModel();
if( values != null )
{
for( String value : values )
{
selected.add( false );
listModel.addElement( value );
}
}
list = new JList( listModel );
list.setCellRenderer( new CheckListCellRenderer() );
list.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
list.addMouseListener( new MouseAdapter()
{
public void mousePressed( MouseEvent e )
{
int index = list.locationToIndex( e.getPoint() );
if( index != -1 && list.isEnabled() )
{
int[] oldValue = getSelectedIndexes();
selected.set( index, !selected.get( index ) );
pcs.firePropertyChange( "select", oldValue, getSelectedIndexes() );
list.repaint();
}
}
} );
getComponent().add( new JScrollPane( list ), BorderLayout.CENTER );
getComponent().add( buildToolbar(), BorderLayout.SOUTH );
getComponent().setSize( new Dimension( 400, 120 ) );
getComponent().setMaximumSize( new Dimension( 400, 120 ) );
getComponent().setPreferredSize( new Dimension( 400, 120 ) );
getComponent().setMinimumSize( new Dimension( 400, 120 ) );
}
private Component buildToolbar()
{
JXToolBar toolbar = UISupport.createSmallToolbar();
toolbar.addFixed( new JButton( selectAllAction = new SelectAllAction() ) );
toolbar.addRelatedGap();
toolbar.addFixed( new JButton( unselectAllAction = new UnselectAllAction() ) );
return toolbar;
}
public String getValue()
{
return String.valueOf( list.getSelectedValue() );
}
public void setValue( String value )
{
int index = listModel.indexOf( value );
selected.set( index, true );
list.setSelectedIndex( index );
}
public void addItem( Object value )
{
listModel.addElement( value );
selected.add( false );
}
public Object[] getOptions()
{
Object[] options = new Object[listModel.size()];
for( int c = 0; c < options.length; c++ )
options[c] = listModel.get( c );
return options;
}
public Object[] getSelectedOptions()
{
List<Object> result = new ArrayList<Object>();
for( int c = 0; c < selected.size(); c++ )
{
if( selected.get( c ) )
result.add( listModel.get( c ) );
}
return result.toArray();
}
public void setOptions( Object[] values )
{
listModel.clear();
selected.clear();
for( Object value : values )
{
selected.add( false );
listModel.addElement( value );
}
}
public class CheckListCellRenderer extends JCheckBox implements ListCellRenderer
{
public CheckListCellRenderer()
{
setBorder( BorderFactory.createEmptyBorder( 3, 3, 3, 3 ) );
}
public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus )
{
setText( value.toString() );
setSelected( selected.get( index ) );
if( isSelected )
{
setBackground( list.getSelectionBackground() );
setForeground( list.getSelectionForeground() );
}
else
{
if( isDefault( index ) )
setBackground( defaultColor );
else
setBackground( list.getBackground() );
setForeground( list.getForeground() );
}
return this;
}
}
public void setSelectedOptions( Object[] options )
{
List<Object> asList = Arrays.asList( options );
for( int c = 0; c < selected.size(); c++ )
{
selected.set( c, asList.contains( listModel.get( c ) ) );
}
list.repaint();
}
private class SelectAllAction extends AbstractAction
{
public SelectAllAction()
{
super( "Select all" );
putValue( SHORT_DESCRIPTION, "Selects all items in the list" );
}
public void actionPerformed( ActionEvent e )
{
int[] oldValue = getSelectedIndexes();
setSelectedOptions( getOptions() );
pcs.firePropertyChange( "select", oldValue, getSelectedIndexes() );
}
}
private class UnselectAllAction extends AbstractAction
{
public UnselectAllAction()
{
super( "Unselect all" );
putValue( SHORT_DESCRIPTION, "Unselects all items in the list" );
}
public void actionPerformed( ActionEvent e )
{
int[] oldValue = getSelectedIndexes();
setSelectedOptions( new String[0] );
pcs.firePropertyChange( "select", oldValue, getSelectedIndexes() );
}
}
public int[] getSelectedIndexes()
{
int cnt = 0;
for( int c = 0; c < selected.size(); c++ )
{
if( selected.get( c ) )
cnt++ ;
}
int[] result = new int[cnt];
cnt = 0;
for( int c = 0; c < selected.size(); c++ )
{
if( selected.get( c ) )
result[cnt++ ] = c;
}
return result;
}
public void setDefault( Color color, int... defIndex )
{
this.defaultIndex = defIndex;
this.defaultColor = color;
}
private boolean isDefault( int index )
{
if( defaultIndex == null )
return false;
for( int i : defaultIndex )
if( index == i )
return true;
return false;
}
public void addPropertyChangeListener( PropertyChangeListener listener )
{
pcs.addPropertyChangeListener( listener );
}
public void removePropertyChangeListener( PropertyChangeListener listener )
{
pcs.removePropertyChangeListener( listener );
}
@Override
public void setEnabled( boolean enabled )
{
super.setEnabled( enabled );
list.setEnabled( enabled );
selectAllAction.setEnabled( enabled );
unselectAllAction.setEnabled( enabled );
}
}