/* * 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.soapui.support.components; import com.eviware.soapui.SoapUI; import com.eviware.soapui.model.ModelItem; import com.eviware.soapui.model.tree.SoapUITreeNode; import com.eviware.soapui.model.tree.nodes.support.EmptyModelItem; import com.eviware.soapui.support.ListDataListenerAdapter; import com.eviware.soapui.support.UISupport; import com.eviware.soapui.support.swing.ModelItemListMouseListener; import com.eviware.soapui.support.types.StringList; import com.eviware.soapui.ui.support.DefaultDesktopPanel; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.event.ListDataEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreePath; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; public class ModelItemListDesktopPanel extends DefaultDesktopPanel { private final ModelItem[] modelItems; private JList list; private ItemsListModel listModel; private InternalTreeModelListener treeModelListener; private Map<ModelItem, StringList> detailInfo = new HashMap<ModelItem, StringList>(); private JList detailList; private DetailsListModel detailListModel; public ModelItemListDesktopPanel(String title, String description, ModelItem[] modelItems) { super(title, description, new JPanel(new BorderLayout())); this.modelItems = modelItems; buildUI(); treeModelListener = new InternalTreeModelListener(); SoapUI.getNavigator().getMainTree().getModel().addTreeModelListener(treeModelListener); } public void addDetails(ModelItem modelItem, String details) { if (!detailInfo.containsKey(modelItem)) { detailInfo.put(modelItem, new StringList()); } detailInfo.get(modelItem).add(details); } private void buildUI() { JPanel p = (JPanel) getComponent(); p.add(UISupport.buildDescription(getTitle(), getDescription(), null), BorderLayout.NORTH); p.add(buildModelItemList(), BorderLayout.CENTER); } @Override public boolean onClose(boolean canCancel) { SoapUI.getNavigator().getMainTree().getModel().removeTreeModelListener(treeModelListener); return super.onClose(canCancel); } private Component buildModelItemList() { listModel = new ItemsListModel(modelItems); list = new JList(listModel); list.setCellRenderer(new ItemListCellRenderer()); ModelItemListMouseListener modelItemListMouseListener = new ModelItemListMouseListener(); JPopupMenu popupMenu = new JPopupMenu(); popupMenu.add(new RemoveAction()); popupMenu.add(new HighlightAction()); modelItemListMouseListener.setPopupMenu(popupMenu); list.addMouseListener(modelItemListMouseListener); listModel.addListDataListener(new ListDataListenerAdapter() { @Override public void intervalRemoved(ListDataEvent e) { if (listModel.isEmpty()) { SwingUtilities.invokeLater(new Runnable() { public void run() { SoapUI.getDesktop().closeDesktopPanel(ModelItemListDesktopPanel.this); } }); } } }); list.addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { detailListModel.refresh(); } }); JInspectorPanelImpl inspectorPanel = new JInspectorPanelImpl(new JScrollPane(list)); inspectorPanel.addInspector(new JComponentInspector<JComponent>(buildDetails(), "Details", "Shows detailed information for the selected item", true)); return inspectorPanel; } private JComponent buildDetails() { detailListModel = new DetailsListModel(); detailList = new JList(detailListModel); return new JScrollPane(detailList); } private class DetailsListModel extends AbstractListModel { public Object getElementAt(int index) { ModelItem modelItem = (ModelItem) list.getSelectedValue(); if (modelItem == null || !detailInfo.containsKey(modelItem)) { return null; } else { return detailInfo.get(modelItem).get(index); } } public void refresh() { fireContentsChanged(this, 0, getSize() - 1); } public int getSize() { ModelItem modelItem = (ModelItem) list.getSelectedValue(); if (modelItem == null || !detailInfo.containsKey(modelItem)) { return 0; } else { return detailInfo.get(modelItem).size(); } } } private class ItemsListModel extends DefaultListModel { public ItemsListModel(ModelItem[] modelItems) { for (ModelItem item : modelItems) { addElement(item); } } public void nodesChanged() { fireContentsChanged(this, 0, getSize() - 1); } } private class RemoveAction extends AbstractAction { public RemoveAction() { super("Remove"); putValue(SHORT_DESCRIPTION, "Removes this item from the list"); } public void actionPerformed(ActionEvent e) { int ix = list.getSelectedIndex(); if (ix != -1 && UISupport.confirm("Remove selected item from list?", "Remove Item")) { listModel.remove(ix); } } } private class HighlightAction extends AbstractAction { public HighlightAction() { super("Select in Tree"); putValue(SHORT_DESCRIPTION, "Selects this node in the Navigator Tree"); } public void actionPerformed(ActionEvent e) { int ix = list.getSelectedIndex(); if (ix != -1) { UISupport.select((ModelItem) listModel.getElementAt(ix)); } } } private final class InternalTreeModelListener implements TreeModelListener { public void treeNodesChanged(TreeModelEvent e) { listModel.nodesChanged(); } public void treeNodesInserted(TreeModelEvent e) { } public void treeNodesRemoved(TreeModelEvent e) { SwingUtilities.invokeLater(new Runnable() { public void run() { for (int c = 0; c < listModel.getSize(); c++) { if (SoapUI.getNavigator().getTreePath((ModelItem) listModel.elementAt(c)) == null) { listModel.remove(c); c--; } } } }); } public void treeStructureChanged(TreeModelEvent e) { } } private class ItemListCellRenderer extends DefaultListCellRenderer { public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (value instanceof ModelItem) { ModelItem item = (ModelItem) value; TreePath treePath = SoapUI.getNavigator().getTreePath(item); if (treePath == null) { if (!(item instanceof EmptyModelItem)) { // listModel.setElementAt( new EmptyModelItem( "<removed>", // item.getIcon()), index ); } label.setText("<removed>"); label.setToolTipText(null); } else { String str = item.getName() + " ["; for (int c = 1; c < treePath.getPathCount(); c++) { SoapUITreeNode comp = (SoapUITreeNode) treePath.getPathComponent(c); if (comp.getModelItem() instanceof EmptyModelItem) { continue; } if (c > 1) { str += " - "; } str += comp.toString(); } str += "]"; label.setText(str); label.setToolTipText(item.getDescription()); } label.setIcon(item.getIcon()); label.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); } return label; } } }