001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.ui.desktop.standalone;
014:
015: import java.awt.BorderLayout;
016: import java.awt.Graphics;
017: import java.awt.Image;
018: import java.awt.Toolkit;
019: import java.awt.event.ActionEvent;
020: import java.beans.PropertyChangeEvent;
021: import java.beans.PropertyChangeListener;
022: import java.beans.PropertyVetoException;
023: import java.io.File;
024: import java.util.ArrayList;
025: import java.util.HashMap;
026: import java.util.Iterator;
027: import java.util.List;
028: import java.util.Map;
029:
030: import javax.swing.AbstractAction;
031: import javax.swing.Action;
032: import javax.swing.BorderFactory;
033: import javax.swing.JComponent;
034: import javax.swing.JDesktopPane;
035: import javax.swing.JInternalFrame;
036: import javax.swing.JPanel;
037: import javax.swing.JScrollPane;
038: import javax.swing.event.InternalFrameAdapter;
039: import javax.swing.event.InternalFrameEvent;
040:
041: import com.eviware.soapui.SoapUI;
042: import com.eviware.soapui.model.ModelItem;
043: import com.eviware.soapui.model.PanelBuilder;
044: import com.eviware.soapui.model.util.PanelBuilderRegistry;
045: import com.eviware.soapui.model.workspace.Workspace;
046: import com.eviware.soapui.support.UISupport;
047: import com.eviware.soapui.support.action.swing.ActionList;
048: import com.eviware.soapui.support.action.swing.DefaultActionList;
049: import com.eviware.soapui.ui.desktop.AbstractSoapUIDesktop;
050: import com.eviware.soapui.ui.desktop.DesktopPanel;
051: import com.eviware.soapui.ui.desktop.SoapUIDesktop;
052:
053: /**
054: * The default standalone soapUI desktop using a JDesktopPane
055: *
056: * @author Ole.Matzura
057: */
058:
059: public class StandaloneDesktop extends AbstractSoapUIDesktop {
060: private JDesktopPane desktopPane;
061: private Map<ModelItem, JInternalFrame> modelItemToInternalFrameMap = new HashMap<ModelItem, JInternalFrame>();
062: private Map<JInternalFrame, DesktopPanel> internalFrameToDesktopPanelMap = new HashMap<JInternalFrame, DesktopPanel>();
063: private DesktopPanelPropertyChangeListener desktopPanelPropertyChangeListener = new DesktopPanelPropertyChangeListener();
064: private InternalDesktopFrameListener internalFrameListener = new InternalDesktopFrameListener();
065: private ActionList actions;
066:
067: private DesktopPanel currentPanel;
068:
069: private CloseCurrentAction closeCurrentAction = new CloseCurrentAction();
070: private CloseOtherAction closeOtherAction = new CloseOtherAction();
071: private CloseAllAction closeAllAction = new CloseAllAction();
072:
073: private static int openFrameCount = 0;
074: private static final int xOffset = 30, yOffset = 30;
075: private JPanel desktopPanel = new JPanel(new BorderLayout());
076:
077: private boolean transferring;
078:
079: public StandaloneDesktop(Workspace workspace) {
080: super (workspace);
081:
082: buildUI();
083:
084: actions = new DefaultActionList("Desktop");
085: actions.addAction(closeCurrentAction);
086: actions.addAction(closeOtherAction);
087: actions.addAction(closeAllAction);
088:
089: enableWindowActions();
090: }
091:
092: private void enableWindowActions() {
093: closeCurrentAction.setEnabled(currentPanel != null
094: && internalFrameToDesktopPanelMap.size() > 0);
095: closeOtherAction.setEnabled(currentPanel != null
096: && internalFrameToDesktopPanelMap.size() > 1);
097: closeAllAction
098: .setEnabled(internalFrameToDesktopPanelMap.size() > 0);
099: }
100:
101: private void buildUI() {
102: desktopPane = new SoapUIDesktopPane();
103: JScrollPane scrollPane = new JScrollPane(desktopPane);
104: desktopPanel.add(scrollPane, BorderLayout.CENTER);
105: }
106:
107: public JComponent getDesktopComponent() {
108: return desktopPanel;
109: }
110:
111: public boolean closeDesktopPanel(DesktopPanel desktopPanel) {
112: try {
113: if (desktopPanel.getModelItem() != null) {
114: return closeDesktopPanel(desktopPanel.getModelItem());
115: } else {
116: JInternalFrame frame = getFrameForDesktopPanel(desktopPanel);
117: if (frame != null) {
118: frame.doDefaultCloseAction();
119: return frame.isClosed();
120: }
121: // else
122: // throw new RuntimeException( "Cannot close unkown DesktopPanel: " + desktopPanel.getTitle() );
123:
124: return false;
125: }
126: } finally {
127: enableWindowActions();
128: }
129: }
130:
131: private JInternalFrame getFrameForDesktopPanel(
132: DesktopPanel desktopPanel) {
133: for (JInternalFrame frame : internalFrameToDesktopPanelMap
134: .keySet()) {
135: if (internalFrameToDesktopPanelMap.get(frame) == desktopPanel) {
136: return frame;
137: }
138: }
139:
140: return null;
141: }
142:
143: public boolean hasDesktopPanel(ModelItem modelItem) {
144: return modelItemToInternalFrameMap.containsKey(modelItem);
145: }
146:
147: public DesktopPanel showDesktopPanel(ModelItem modelItem) {
148: PanelBuilder<ModelItem> panelBuilder = PanelBuilderRegistry
149: .getPanelBuilder(modelItem);
150: if (modelItemToInternalFrameMap.containsKey(modelItem)) {
151: JInternalFrame frame = modelItemToInternalFrameMap
152: .get(modelItem);
153: try {
154: desktopPane.getDesktopManager().deiconifyFrame(frame);
155: frame.setSelected(true);
156: frame.moveToFront();
157: currentPanel = internalFrameToDesktopPanelMap
158: .get(frame);
159: } catch (PropertyVetoException e) {
160: SoapUI.logError(e);
161: }
162: } else if (panelBuilder != null
163: && panelBuilder.hasDesktopPanel()) {
164: DesktopPanel desktopPanel = panelBuilder
165: .buildDesktopPanel(modelItem);
166: if (desktopPanel == null)
167: return null;
168:
169: JInternalFrame frame = createContentFrame(desktopPanel);
170:
171: desktopPane.add(frame);
172: try {
173: frame.setSelected(true);
174: } catch (PropertyVetoException e) {
175: SoapUI.logError(e);
176: }
177:
178: modelItemToInternalFrameMap.put(modelItem, frame);
179: internalFrameToDesktopPanelMap.put(frame, desktopPanel);
180:
181: fireDesktopPanelCreated(desktopPanel);
182:
183: currentPanel = desktopPanel;
184: desktopPanel.getComponent().requestFocusInWindow();
185: } else
186: Toolkit.getDefaultToolkit().beep();
187:
188: enableWindowActions();
189:
190: return currentPanel;
191: }
192:
193: private JInternalFrame createContentFrame(DesktopPanel desktopPanel) {
194: desktopPanel
195: .addPropertyChangeListener(desktopPanelPropertyChangeListener);
196:
197: JComponent panel = desktopPanel.getComponent();
198: panel.setOpaque(true);
199:
200: String title = desktopPanel.getTitle();
201:
202: JInternalFrame frame = new JInternalFrame(title, true, true,
203: true, true);
204: frame.addInternalFrameListener(internalFrameListener);
205: frame.setContentPane(panel);
206: frame.setSize(panel.getPreferredSize());
207: frame.setVisible(true);
208: frame.setFrameIcon(desktopPanel.getIcon());
209: frame.setToolTipText(desktopPanel.getDescription());
210: frame
211: .setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
212: frame.setLocation(xOffset * (openFrameCount % 10), yOffset
213: * (openFrameCount % 10));
214: frame.setBorder(BorderFactory.createCompoundBorder(
215: BorderFactory.createRaisedBevelBorder(), BorderFactory
216: .createEmptyBorder(2, 2, 2, 2)));
217: openFrameCount++;
218: return frame;
219: }
220:
221: public boolean closeDesktopPanel(ModelItem modelItem) {
222: try {
223: if (modelItemToInternalFrameMap.containsKey(modelItem)) {
224: JInternalFrame frame = modelItemToInternalFrameMap
225: .get(modelItem);
226: frame.doDefaultCloseAction();
227: return frame.isClosed();
228: }
229:
230: return false;
231: } finally {
232: enableWindowActions();
233: }
234: }
235:
236: private class InternalDesktopFrameListener extends
237: InternalFrameAdapter {
238: public void internalFrameClosing(InternalFrameEvent e) {
239: DesktopPanel desktopPanel = internalFrameToDesktopPanelMap
240: .get(e.getInternalFrame());
241: if (!transferring && !desktopPanel.onClose(true)) {
242: return;
243: }
244:
245: desktopPanel
246: .removePropertyChangeListener(desktopPanelPropertyChangeListener);
247:
248: modelItemToInternalFrameMap.remove(desktopPanel
249: .getModelItem());
250: internalFrameToDesktopPanelMap.remove(e.getInternalFrame());
251:
252: e.getInternalFrame().dispose();
253:
254: if (!transferring)
255: fireDesktopPanelClosed(desktopPanel);
256:
257: if (currentPanel == desktopPanel)
258: currentPanel = null;
259: }
260:
261: public void internalFrameActivated(InternalFrameEvent e) {
262: currentPanel = internalFrameToDesktopPanelMap.get(e
263: .getInternalFrame());
264: if (currentPanel != null) {
265: fireDesktopPanelSelected(currentPanel);
266: }
267:
268: enableWindowActions();
269: }
270:
271: public void internalFrameDeactivated(InternalFrameEvent e) {
272: currentPanel = null;
273: enableWindowActions();
274: }
275: }
276:
277: public class CloseCurrentAction extends AbstractAction {
278: public CloseCurrentAction() {
279: super ("Close Current");
280: putValue(Action.SHORT_DESCRIPTION,
281: "Closes the current window");
282: putValue(Action.ACCELERATOR_KEY, UISupport
283: .getKeyStroke("menu F4"));
284:
285: }
286:
287: public void actionPerformed(ActionEvent e) {
288: JInternalFrame frame = desktopPane.getSelectedFrame();
289: if (frame != null)
290: closeDesktopPanel(internalFrameToDesktopPanelMap
291: .get(frame));
292: }
293: }
294:
295: public class CloseOtherAction extends AbstractAction {
296: public CloseOtherAction() {
297: super ("Close Others");
298: putValue(Action.SHORT_DESCRIPTION,
299: "Closes all windows except the current one");
300: putValue(Action.ACCELERATOR_KEY, UISupport
301: .getKeyStroke("menu alt O"));
302: }
303:
304: public void actionPerformed(ActionEvent e) {
305: JInternalFrame frame = desktopPane.getSelectedFrame();
306: if (frame == null)
307: return;
308:
309: Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap
310: .keySet().iterator();
311: while (i.hasNext()) {
312: JInternalFrame f = i.next();
313: if (f != frame) {
314: closeDesktopPanel(internalFrameToDesktopPanelMap
315: .get(f));
316: i = internalFrameToDesktopPanelMap.keySet()
317: .iterator();
318: }
319: }
320: }
321: }
322:
323: public class CloseAllAction extends AbstractAction {
324: public CloseAllAction() {
325: super ("Close All");
326: putValue(Action.SHORT_DESCRIPTION, "Closes all windows");
327: putValue(Action.ACCELERATOR_KEY, UISupport
328: .getKeyStroke("menu alt L"));
329: }
330:
331: public void actionPerformed(ActionEvent e) {
332: closeAll();
333: }
334: }
335:
336: public ActionList getActions() {
337: return actions;
338: }
339:
340: private class DesktopPanelPropertyChangeListener implements
341: PropertyChangeListener {
342: public void propertyChange(PropertyChangeEvent evt) {
343: DesktopPanel desktopPanel = (DesktopPanel) evt.getSource();
344: JInternalFrame frame = getFrameForDesktopPanel(desktopPanel);
345: if (frame != null) {
346: if (evt.getPropertyName().equals(
347: DesktopPanel.TITLE_PROPERTY)) {
348: frame.setTitle(desktopPanel.getTitle());
349: } else if (evt.getPropertyName().equals(
350: DesktopPanel.ICON_PROPERTY)) {
351: frame.setFrameIcon(desktopPanel.getIcon());
352: }
353: }
354: }
355: }
356:
357: public DesktopPanel[] getDesktopPanels() {
358: return internalFrameToDesktopPanelMap.values()
359: .toArray(
360: new DesktopPanel[internalFrameToDesktopPanelMap
361: .size()]);
362: }
363:
364: public DesktopPanel getDesktopPanel(ModelItem modelItem) {
365: return internalFrameToDesktopPanelMap.get(modelItem);
366: }
367:
368: public DesktopPanel showDesktopPanel(DesktopPanel desktopPanel) {
369: JInternalFrame frame = getFrameForDesktopPanel(desktopPanel);
370: if (frame != null) {
371: try {
372: desktopPane.getDesktopManager().deiconifyFrame(frame);
373: frame.setSelected(true);
374: frame.moveToFront();
375: } catch (Exception e) {
376: SoapUI.logError(e);
377: }
378: } else {
379: frame = createContentFrame(desktopPanel);
380: desktopPane.add(frame);
381:
382: if (desktopPanel.getModelItem() != null)
383: modelItemToInternalFrameMap.put(desktopPanel
384: .getModelItem(), frame);
385:
386: internalFrameToDesktopPanelMap.put(frame, desktopPanel);
387: fireDesktopPanelCreated(desktopPanel);
388: frame.moveToFront();
389: desktopPanel.getComponent().requestFocusInWindow();
390: }
391:
392: currentPanel = desktopPanel;
393: enableWindowActions();
394:
395: return desktopPanel;
396: }
397:
398: class SoapUIDesktopPane extends JDesktopPane {
399: Image img;
400: private int imageWidth;
401: private int imageHeight;
402:
403: public SoapUIDesktopPane() {
404: try {
405: File file = new File("soapui-background.gif");
406: if (!file.exists())
407: file = new File("soapui-background.jpg");
408: if (!file.exists())
409: file = new File("soapui-background.png");
410:
411: if (file.exists()) {
412: img = javax.imageio.ImageIO.read(file);
413: imageWidth = img.getWidth(this );
414: imageHeight = img.getHeight(this );
415: }
416: } catch (Exception e) {
417: }
418: }
419:
420: public void paintComponent(Graphics g) {
421: super .paintComponent(g);
422:
423: if (img == null)
424: return;
425:
426: int x = (this .getWidth() - imageWidth) / 2;
427: int y = (this .getHeight() - imageHeight) / 2;
428:
429: g.drawImage(img, x, y, imageWidth, imageHeight, this );
430: }
431: }
432:
433: public void transferTo(SoapUIDesktop newDesktop) {
434: transferring = true;
435:
436: List<DesktopPanel> values = new ArrayList<DesktopPanel>(
437: internalFrameToDesktopPanelMap.values());
438: for (DesktopPanel desktopPanel : values) {
439: closeDesktopPanel(desktopPanel);
440: newDesktop.showDesktopPanel(desktopPanel);
441: }
442:
443: transferring = false;
444: }
445:
446: public boolean closeAll() {
447: while (internalFrameToDesktopPanelMap.size() > 0) {
448: Iterator<JInternalFrame> i = internalFrameToDesktopPanelMap
449: .keySet().iterator();
450: try {
451: i.next().setClosed(true);
452: } catch (PropertyVetoException e1) {
453: SoapUI.logError(e1);
454: }
455: }
456:
457: internalFrameToDesktopPanelMap.clear();
458: modelItemToInternalFrameMap.clear();
459:
460: JInternalFrame[] allFrames = desktopPane.getAllFrames();
461: for (JInternalFrame frame : allFrames) {
462: frame.doDefaultCloseAction();
463: }
464:
465: enableWindowActions();
466: return true;
467: }
468: }
|