1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.support.components;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.model.ModelItem;
17 import com.eviware.soapui.model.tree.SoapUITreeNode;
18 import com.eviware.soapui.model.tree.nodes.support.EmptyModelItem;
19 import com.eviware.soapui.support.ListDataListenerAdapter;
20 import com.eviware.soapui.support.UISupport;
21 import com.eviware.soapui.support.swing.ModelItemListMouseListener;
22 import com.eviware.soapui.support.types.StringList;
23 import com.eviware.soapui.ui.support.DefaultDesktopPanel;
24
25 import javax.swing.*;
26 import javax.swing.event.*;
27 import javax.swing.tree.TreePath;
28 import java.awt.*;
29 import java.awt.event.ActionEvent;
30 import java.util.HashMap;
31 import java.util.Map;
32
33 public class ModelItemListDesktopPanel extends DefaultDesktopPanel
34 {
35 private final ModelItem[] modelItems;
36 private JList list;
37 private ItemsListModel listModel;
38 private InternalTreeModelListener treeModelListener;
39 private Map<ModelItem,StringList> detailInfo = new HashMap<ModelItem, StringList>();
40 private JList detailList;
41 private DetailsListModel detailListModel;
42
43 public ModelItemListDesktopPanel( String title, String description, ModelItem [] modelItems )
44 {
45 super( title, description, new JPanel( new BorderLayout() ) );
46 this.modelItems = modelItems;
47
48 buildUI();
49
50 treeModelListener = new InternalTreeModelListener();
51 SoapUI.getNavigator().getMainTree().getModel().addTreeModelListener( treeModelListener );
52 }
53
54 public void addDetails( ModelItem modelItem, String details )
55 {
56 if( !detailInfo.containsKey( modelItem ))
57 detailInfo.put( modelItem, new StringList() );
58
59 detailInfo.get( modelItem ).add( details );
60 }
61
62 private void buildUI()
63 {
64 JPanel p = ( JPanel ) getComponent();
65
66 p.add( UISupport.buildDescription( getTitle(), getDescription(), null ), BorderLayout.NORTH );
67 p.add( buildModelItemList(), BorderLayout.CENTER );
68 }
69
70 @Override
71 public boolean onClose( boolean canCancel )
72 {
73 SoapUI.getNavigator().getMainTree().getModel().removeTreeModelListener( treeModelListener );
74 return super.onClose( canCancel );
75 }
76
77 private Component buildModelItemList()
78 {
79 listModel = new ItemsListModel( modelItems );
80
81 list = new JList( listModel);
82 list.setCellRenderer( new ItemListCellRenderer() );
83 ModelItemListMouseListener modelItemListMouseListener = new ModelItemListMouseListener();
84 JPopupMenu popupMenu = new JPopupMenu();
85 popupMenu.add( new RemoveAction() );
86 popupMenu.add( new HighlightAction() );
87
88 modelItemListMouseListener.setPopupMenu( popupMenu );
89 list.addMouseListener( modelItemListMouseListener );
90 listModel.addListDataListener( new ListDataListenerAdapter() {
91
92 @Override
93 public void intervalRemoved( ListDataEvent e )
94 {
95 if( listModel.isEmpty() )
96 {
97 SwingUtilities.invokeLater( new Runnable() {
98
99 public void run()
100 {
101 SoapUI.getDesktop().closeDesktopPanel( ModelItemListDesktopPanel.this );
102 }} );
103 }
104 }} );
105
106 list.addListSelectionListener( new ListSelectionListener() {
107
108 public void valueChanged( ListSelectionEvent e )
109 {
110 detailListModel.refresh();
111 }} );
112
113 JInspectorPanelImpl inspectorPanel = new JInspectorPanelImpl( new JScrollPane( list ) );
114 inspectorPanel.addInspector( new JComponentInspector<JComponent>( buildDetails(), "Details",
115 "Shows detailed information for the selected item", true ) );
116
117 return inspectorPanel;
118 }
119
120 private JComponent buildDetails()
121 {
122 detailListModel = new DetailsListModel();
123 detailList = new JList( detailListModel );
124 return new JScrollPane( detailList );
125 }
126
127 private class DetailsListModel extends AbstractListModel
128 {
129 public Object getElementAt( int index )
130 {
131 ModelItem modelItem = ( ModelItem ) list.getSelectedValue();
132 if( modelItem == null || !detailInfo.containsKey( modelItem ))
133 return null;
134 else
135 return detailInfo.get( modelItem ).get( index );
136 }
137
138 public void refresh()
139 {
140 fireIntervalAdded( this, 0, getSize()-1 );
141 }
142
143 public int getSize()
144 {
145 ModelItem modelItem = ( ModelItem ) list.getSelectedValue();
146 if( modelItem == null || !detailInfo.containsKey( modelItem ))
147 return 0;
148 else
149 return detailInfo.get( modelItem ).size();
150 }
151 }
152
153 private class ItemsListModel extends DefaultListModel
154 {
155 public ItemsListModel( ModelItem[] modelItems )
156 {
157 for( ModelItem item : modelItems )
158 addElement( item );
159 }
160
161 public void nodesChanged()
162 {
163 fireContentsChanged( this, 0, getSize()-1 );
164 }
165 }
166
167 private class RemoveAction extends AbstractAction
168 {
169 public RemoveAction()
170 {
171 super( "Remove" );
172 putValue( SHORT_DESCRIPTION, "Removes this item from the list" );
173 }
174
175 public void actionPerformed( ActionEvent e )
176 {
177 int ix = list.getSelectedIndex();
178 if( ix != -1 && UISupport.confirm( "Remove selected item from list?", "Remove Item" ))
179 listModel.remove( ix );
180 }
181 }
182
183 private class HighlightAction extends AbstractAction
184 {
185 public HighlightAction()
186 {
187 super( "Select in Tree" );
188 putValue( SHORT_DESCRIPTION, "Selects this node in the Navigator Tree" );
189 }
190
191 public void actionPerformed( ActionEvent e )
192 {
193 int ix = list.getSelectedIndex();
194 if( ix != -1 )
195 UISupport.select( ( ModelItem ) listModel.getElementAt( ix ));
196 }
197 }
198
199 private final class InternalTreeModelListener implements TreeModelListener
200 {
201 public void treeNodesChanged( TreeModelEvent e )
202 {
203 listModel.nodesChanged();
204 }
205
206 public void treeNodesInserted( TreeModelEvent e )
207 {
208 }
209
210 public void treeNodesRemoved( TreeModelEvent e )
211 {
212 SwingUtilities.invokeLater( new Runnable() {
213
214 public void run()
215 {
216 for( int c = 0; c < listModel.getSize(); c++ )
217 {
218 if( SoapUI.getNavigator().getTreePath( ( ModelItem ) listModel.elementAt( c )) == null )
219 {
220 listModel.remove( c );
221 c--;
222 }
223 }
224 }} );
225 }
226
227 public void treeStructureChanged( TreeModelEvent e )
228 {
229 }
230 }
231
232 private class ItemListCellRenderer extends DefaultListCellRenderer
233 {
234 public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus )
235 {
236 JLabel label = ( JLabel ) super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
237
238 if( value instanceof ModelItem )
239 {
240 ModelItem item = ( ModelItem ) value;
241 TreePath treePath = SoapUI.getNavigator().getTreePath( item );
242
243 if( treePath == null )
244 {
245 if( !(item instanceof EmptyModelItem))
246 {
247
248 }
249
250 label.setText( "<removed>" );
251 label.setToolTipText( null );
252 }
253 else
254 {
255 String str = item.getName() + " [";
256
257 for( int c = 1; c < treePath.getPathCount(); c++ )
258 {
259 SoapUITreeNode comp = ( SoapUITreeNode ) treePath.getPathComponent( c );
260 if( comp.getModelItem() instanceof EmptyModelItem )
261 continue;
262
263 if( c > 1 )
264 str += " - ";
265
266 str += comp.toString();
267 }
268
269 str += "]";
270
271 label.setText( str);
272 label.setToolTipText( item.getDescription() );
273 }
274
275 label.setIcon( item.getIcon() );
276 label.setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ));
277 }
278
279 return label;
280 }
281 }
282 }