/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.x.form.support; 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; 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 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; /** * 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.NORTH); 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); } }