KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > application > swt > SWTThickClientGui


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: SWTThickClientGui.java,v 1.15 2007/01/07 06:14:22 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.application.swt;
23
24 import java.io.InputStream JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.custom.StackLayout;
31 import org.eclipse.swt.graphics.Color;
32 import org.eclipse.swt.graphics.Font;
33 import org.eclipse.swt.graphics.FontData;
34 import org.eclipse.swt.graphics.GC;
35 import org.eclipse.swt.graphics.Image;
36 import org.eclipse.swt.graphics.Point;
37 import org.eclipse.swt.graphics.Rectangle;
38 import org.eclipse.swt.layout.GridData;
39 import org.eclipse.swt.layout.GridLayout;
40 import org.eclipse.swt.widgets.Composite;
41 import org.eclipse.swt.widgets.CoolBar;
42 import org.eclipse.swt.widgets.CoolItem;
43 import org.eclipse.swt.widgets.Display;
44 import org.eclipse.swt.widgets.Event;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.Listener;
47 import org.eclipse.swt.widgets.MessageBox;
48 import org.eclipse.swt.widgets.Monitor;
49 import org.eclipse.swt.widgets.Shell;
50 import org.eclipse.swt.widgets.ToolBar;
51 import org.eclipse.swt.widgets.ToolItem;
52 import org.opensubsystems.core.application.SeparatorModule;
53 import org.opensubsystems.core.application.ThickClient;
54 import org.opensubsystems.core.application.ThickClientGui;
55 import org.opensubsystems.core.application.ThickClientModule;
56 import org.opensubsystems.core.error.OSSException;
57 import org.opensubsystems.core.util.GlobalConstants;
58
59 /**
60  * Implementation of ThickClientGui using SWT library.
61  *
62  * @version $Id: SWTThickClientGui.java,v 1.15 2007/01/07 06:14:22 bastafidli Exp $
63  * @author Miro Halas
64  * @code.reviewer Miro Halas
65  * @code.reviewed 1.11 2006/04/05 04:58:04 bastafidli
66  */

67 public class SWTThickClientGui implements ThickClientGui
68 {
69    // Constants ////////////////////////////////////////////////////////////////
70

71    /**
72     * Name of GUI technology used to build the thick client.
73     */

74    public static final String JavaDoc SWT_GUI_TECHNOLOGY = "SWT";
75
76    // Constants ////////////////////////////////////////////////////////////////
77

78    /**
79     * Default width of the icon to access modules.
80     */

81    public static final int DEFAULT_MODULE_ICON_WIDTH = 90;
82
83    /**
84     * Default height of the icon to access modules.
85     */

86    public static final int DEFAULT_MODULE_ICON_HEIGHT = 5;
87
88    /**
89     * Default size of the text under icon to access modules.
90     */

91    public static final int DEFAULT_MODULE_ICON_TEXT = 14;
92    
93    /**
94     * Flags required to display message with yes/no question.
95     */

96    public static final int SWT_MESSAGE_YES_NO_QUESTION = SWT.APPLICATION_MODAL
97                                                          | SWT.YES | SWT.NO
98                                                          | SWT.ICON_QUESTION;
99    
100    /**
101     * Flags required to display error message.
102     */

103    public static final int SWT_MESSAGE_ERROR = SWT.APPLICATION_MODAL | SWT.OK
104                                                | SWT.ICON_ERROR;
105       
106    /**
107     * Flags required to display information message.
108     */

109    public static final int SWT_MESSAGE_INFO = SWT.APPLICATION_MODAL | SWT.OK
110                                                | SWT.ICON_INFORMATION;
111       
112    // Attributes ///////////////////////////////////////////////////////////////
113

114    /**
115     * Client for which to display the gui.
116     */

117    protected ThickClient m_client;
118    
119    /**
120     * Style used to construct the main window.
121     */

122    protected int m_iMainWindowStyle;
123    
124    /**
125     * Icon to use for the application.or null if no icon was defined.
126     */

127    protected Image m_iconImage;
128    
129    /**
130     * Blue image to use in module toolbar.
131     */

132    protected Image m_blueImage;
133    
134    /**
135     * Red image to use in module toolbar.
136     */

137    protected Image m_redImage;
138    
139    /**
140     * Green image to use in module toolbar.
141     */

142    protected Image m_greenImage;
143    
144    /**
145     * Yellow image to use in module toolbar.
146     */

147    protected Image m_yellowImage;
148    
149    /**
150     * Gray image to use in module toolbar.
151     */

152    protected Image m_grayImage;
153    
154    /**
155     * Display object used to render on the screen.
156     */

157    protected Display m_display;
158    
159    /**
160     * Main window shell.
161     */

162    protected Shell m_shell;
163    
164    /**
165     * Font used by buttons at module bar.
166     */

167    protected Font m_moduleBarFont;
168    
169    /**
170     * Control representing client area of the application.
171     */

172    protected Composite m_clientArea;
173    
174    /**
175     * Main toolbar of the application
176     */

177    protected CoolBar m_mainToolBar;
178    
179    /**
180     * Toolbar containing buttons representing modules allowing user to switch
181     * from module to module.
182     */

183    protected ToolBar m_moduleBar;
184    
185    /**
186     * Toolbar item containing module toolbar.
187     */

188    protected CoolItem m_moduleBarItem;
189    
190    /**
191     * Splash image to display when the application is starting.
192     */

193    protected Image m_splashImage = null;
194    
195    /**
196     * Logo of the customer to display when the application is starting.
197     */

198    protected Image m_logoImage = null;
199    
200    /**
201     * Toolbar buttons created for individual modules. Key is the module name
202     * value is the tool item.
203     */

204    protected Map JavaDoc m_mapModuleToolItems;
205    
206    // Constructors /////////////////////////////////////////////////////////////
207

208    /**
209     * Construct instance of the thick client gui.
210     */

211    public SWTThickClientGui(
212    )
213    {
214       m_mapModuleToolItems = new HashMap JavaDoc();
215 // TODO: ThickClient: If the position is ANYWHERE we need to display the normal
216
// window with titlebar and all the controls there
217
// The default style is optimized for fullscreen application
218
// Don't allow to resize the window SWT.TITLE | SWT.CLOSE | SWT.RESIZE
219
// Do not display title bar to prevent moving the window around
220
// and also in Fedora with BlueCurve I have no control over the color
221
// of the title bar so that I cannot set them to the same color.
222
// This way there is no title bar and when two windows are opened
223
// at the same time they both look active at the same time
224
m_iMainWindowStyle = SWT.BORDER;
225    }
226    
227    /**
228     * Get display device used by the aplication.
229     *
230     * @return Display
231     */

232    public Display getDisplay(
233    )
234    {
235       return m_display;
236    }
237
238    /**
239     * Get main shell of the aplication.
240     *
241     * @return Shell
242     */

243    public Shell getShell(
244    )
245    {
246       return m_shell;
247    }
248
249    /**
250     * Get client area of the application
251     *
252     * @return Composite
253     */

254    public Composite getClientArea(
255    )
256    {
257       return m_clientArea;
258    }
259    
260    /**
261     * Get icon to use for this application.
262     *
263     * @return Image
264     */

265    public Image getIconImage()
266    {
267       return m_iconImage;
268    }
269
270    /**
271     * Get images representing solid colors
272     *
273     * @return Image[] - array of solid color images in order, blue, red, green
274     * yellow, gray
275     */

276    public Image[] getSolidColorImages(
277    )
278    {
279       return new Image[] {m_blueImage, m_redImage, m_greenImage, m_yellowImage,
280                           m_grayImage,
281                          };
282    }
283    
284    /**
285     * {@inheritDoc}
286     */

287    public void init(
288       ThickClient client
289    )
290    {
291       m_client = client;
292    }
293    
294    /**
295     * {@inheritDoc}
296     */

297    public void createDisplayResources(
298       boolean bHideCursor
299    )
300    {
301       GC gc = null;
302       
303       // This must be disposed 1
304
m_display = new Display();
305
306       // Do it at this point since this affects every window created so it
307
// needs to be done as early as possible
308
if (bHideCursor)
309       {
310          ResourceManager.getInstance().setHiddenDefaultCursor(m_display);
311       }
312       
313       // Create the images big enough so the button can be easily pushed by finger
314
// This must be disposed 2
315
m_blueImage = new Image(m_display, DEFAULT_MODULE_ICON_WIDTH,
316                               DEFAULT_MODULE_ICON_HEIGHT);
317       Color color = m_display.getSystemColor(SWT.COLOR_BLUE);
318       try
319       {
320          gc = new GC(m_blueImage);
321          gc.setBackground(color);
322          gc.fillRectangle(m_blueImage.getBounds());
323       }
324       finally
325       {
326          if (gc != null)
327          {
328             gc.dispose();
329             gc = null;
330          }
331       }
332    
333       m_redImage = new Image(m_display, DEFAULT_MODULE_ICON_WIDTH,
334                              DEFAULT_MODULE_ICON_HEIGHT);
335       // This must be disposed 3
336
color = m_display.getSystemColor(SWT.COLOR_RED);
337       try
338       {
339          gc = new GC(m_redImage);
340          gc.setBackground(color);
341          gc.fillRectangle(m_redImage.getBounds());
342       }
343       finally
344       {
345          if (gc != null)
346          {
347             gc.dispose();
348             gc = null;
349          }
350       }
351    
352       m_greenImage = new Image(m_display, DEFAULT_MODULE_ICON_WIDTH,
353                                DEFAULT_MODULE_ICON_HEIGHT);
354       // This must be disposed 4
355
color = m_display.getSystemColor(SWT.COLOR_GREEN);
356       try
357       {
358          gc = new GC(m_greenImage);
359          gc.setBackground(color);
360          gc.fillRectangle(m_greenImage.getBounds());
361       }
362       finally
363       {
364          if (gc != null)
365          {
366             gc.dispose();
367             gc = null;
368          }
369       }
370
371       m_yellowImage = new Image(m_display, DEFAULT_MODULE_ICON_WIDTH,
372                                 DEFAULT_MODULE_ICON_HEIGHT);
373       // This must be disposed 5
374
color = m_display.getSystemColor(SWT.COLOR_YELLOW);
375       try
376       {
377          gc = new GC(m_yellowImage);
378          gc.setBackground(color);
379          gc.fillRectangle(m_yellowImage.getBounds());
380       }
381       finally
382       {
383          if (gc != null)
384          {
385             gc.dispose();
386             gc = null;
387          }
388       }
389
390       m_grayImage = new Image(m_display, DEFAULT_MODULE_ICON_WIDTH,
391                               DEFAULT_MODULE_ICON_HEIGHT);
392       // This must be disposed 6
393
color = m_display.getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
394       try
395       {
396          gc = new GC(m_grayImage);
397          gc.setBackground(color);
398          gc.fillRectangle(m_grayImage.getBounds());
399       }
400       finally
401       {
402          if (gc != null)
403          {
404             gc.dispose();
405             gc = null;
406          }
407       }
408       
409       InputStream JavaDoc icon;
410       
411       // TODO: ThickClient: Fix the build to correctly package and install
412
// the icon.gif. Ask me for these files.
413

414       // This must be disposed 7
415
icon = getClass().getResourceAsStream("/icon.gif");
416       if (icon != null)
417       {
418          m_iconImage = new Image(m_display, icon);
419       }
420    }
421    
422    /**
423     * {@inheritDoc}
424     */

425    public void destroyDisplayResources(
426    )
427    {
428       // The application is done so release all global resources
429
ResourceManager.getInstance().releaseResources();
430       
431       if ((m_iconImage != null) && (!m_iconImage.isDisposed()))
432       {
433          m_iconImage.dispose(); // 7
434
m_iconImage = null;
435       }
436       if ((m_grayImage != null) && (!m_grayImage.isDisposed()))
437       {
438          m_grayImage.dispose(); // 6
439
}
440       if ((m_yellowImage != null) && (!m_yellowImage.isDisposed()))
441       {
442          m_yellowImage.dispose(); // 5
443
}
444       if ((m_greenImage != null) && (!m_greenImage.isDisposed()))
445       {
446          m_greenImage.dispose(); // 4
447
}
448       if ((m_redImage != null) && (!m_redImage.isDisposed()))
449       {
450          m_redImage.dispose(); // 3
451
}
452       if ((m_blueImage != null) && (!m_blueImage.isDisposed()))
453       {
454          m_blueImage.dispose(); // 2
455
}
456       if ((m_display != null) && (!m_display.isDisposed()))
457       {
458          m_display.dispose(); // 1
459
}
460    }
461    
462    /**
463     * {@inheritDoc}
464     */

465    public void createMainWindow(
466    )
467    {
468       // Create the main window based on the specified styles
469
m_shell = new Shell(m_display, m_iMainWindowStyle);
470       // Set the default cursor for this shell which will hide it on the
471
// touchscreen if such option is specified
472
ResourceManager.getInstance().setDefaultCursor(m_shell);
473       if (m_iconImage != null)
474       {
475          // Set an icon for the window and application if one was defined
476
m_shell.setImage(m_iconImage);
477       }
478       // Set the title bar and toolbar text
479
m_shell.setText(GlobalConstants.getCurrentProduct().getProductName()
480          + " " + GlobalConstants.getCurrentProduct().getProductVersion()
481          + " by " + GlobalConstants.getCurrentProduct().getProductCreator());
482 // TODO: ThickClient: If the position is ANYWHERE we do not want to maximize it
483
// The window cannot be maximized because the it cannot be correctly
484
// positioned on double head (two monitor) display. Don't make it
485
// maximized and just size it so that it fills the whole screen
486
// m_shell.setMaximized(true);
487
GridLayout shellLayout = new GridLayout();
488       m_shell.setLayout(shellLayout);
489       m_shell.addListener(SWT.Close, new Listener()
490       {
491          public void handleEvent(Event event)
492          {
493             if (m_client.canStopGUI())
494             {
495                if (m_client.stopGUI())
496                {
497                   event.doit = true;
498                }
499                else
500                {
501                   event.doit = false;
502                }
503             }
504             else
505             {
506                event.doit = false;
507             }
508          }
509       });
510
511       // Create the main toolbar
512
m_mainToolBar = new CoolBar(m_shell, SWT.NONE);
513       m_mainToolBar.setLocked(false);
514       // Create client area which will fill the rest of the screen
515
m_clientArea = new Composite(m_shell, SWT.NONE);
516       // Use stack layout since only one module will be visible at a time
517
// and when user switches from module to module we will switch pages
518
// which are stacked one behind another
519
m_clientArea.setLayout(new StackLayout());
520          
521       // This will be toolbar to access individual modules
522
m_moduleBar = new ToolBar(m_mainToolBar, SWT.HORIZONTAL);
523       // This will be toolbar specific to each module
524
// This will make the main toolbar movable
525
m_moduleBarItem = new CoolItem(m_mainToolBar, SWT.NONE);
526       m_moduleBarItem.setControl(m_moduleBar);
527
528       // Increase the font height so the button can be easily pushed by finger
529
// if used on touchscreen
530
Font initialFont = m_moduleBar.getFont();
531       FontData[] fontData = initialFont.getFontData();
532       for (int i = 0; i < fontData.length; i++)
533       {
534          fontData[i].setHeight(DEFAULT_MODULE_ICON_TEXT);
535       }
536       // This must be disposed
537
// TODO: Improve: It would be better if this is allocated by ResourceManager
538
m_moduleBarFont = new Font(m_display, fontData);
539       m_moduleBar.setFont(m_moduleBarFont);
540    }
541
542    /**
543     * {@inheritDoc}
544     */

545    public void destroyMainWindow(
546    )
547    {
548       // TODO: Improve: Do we need to dispose/release m_shell, m_mainArea
549
// m_mainToolBar, m_moduleBar, m_moduleBarItem?
550

551       if ((m_moduleBarFont != null) && (!m_moduleBarFont.isDisposed()))
552       {
553          m_moduleBarFont.dispose();
554       }
555       m_moduleBarFont = null;
556       if (!m_shell.isDisposed())
557       {
558          m_shell.dispose();
559       }
560       m_shell = null;
561    }
562       
563    /**
564     * {@inheritDoc}
565     */

566    public void createModules(
567       Map JavaDoc mapModules
568    ) throws OSSException
569    {
570       Iterator JavaDoc modules;
571       
572       for (modules = mapModules.values().iterator(); modules.hasNext();)
573       {
574          addModule((ThickClientModule)modules.next());
575       }
576
577       // Once all the modules were created adjust the module bar so that it
578
// fits all the modules
579

580       // This will resize the main toolbar
581
Point size = m_moduleBar.computeSize(SWT.DEFAULT, SWT.DEFAULT);
582       m_moduleBarItem.setSize(m_moduleBarItem.computeSize(size.x, size.y));
583       m_mainToolBar.setSize(m_mainToolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT));
584       m_mainToolBar.setLocked(true);
585       
586       // This will decide how will the main toolbar be placed in the main window
587
GridData data = new GridData();
588       data.horizontalAlignment = GridData.FILL;
589       data.verticalAlignment = GridData.BEGINNING;
590       data.grabExcessHorizontalSpace = true;
591       m_mainToolBar.setLayoutData(data);
592    }
593    
594    /**
595     * {@inheritDoc}
596     */

597    public void destroyModules(
598       Map JavaDoc mapModules
599    )
600    {
601       m_mapModuleToolItems.clear();
602    }
603    
604    /**
605     * {@inheritDoc}
606     */

607    public void pasivateModule(
608       ThickClientModule module
609    )
610    {
611       ToolItem item;
612
613       item = (ToolItem)m_mapModuleToolItems.get(module.getName());
614       if (GlobalConstants.ERROR_CHECKING)
615       {
616          assert item != null
617                 : "Cannot find toolbar item for module " + module.getName();
618       }
619   
620       if (module instanceof SWTThickClientModule)
621       {
622          Composite clientArea;
623          
624          clientArea = ((SWTThickClientModule)module).getClientArea();
625          if (clientArea != null)
626          {
627            clientArea.setVisible(false);
628          }
629       }
630       
631       item.setSelection(false);
632       if (GlobalConstants.isWindows())
633       {
634          Image hotImage;
635          Image normalImage;
636          
637          // TODO: Bug: SWT 3.0M7: This is a bug in SWT 3.0M7 and below but they
638
// actually say that this is a correct behaviour and that Windows should
639
// not display the hot image when pushed. So when they fix it on windows
640
// we need to remove the check above
641
// Swap the images to signal inactive module
642
hotImage = item.getHotImage();
643          normalImage = item.getImage();
644          item.setHotImage(normalImage);
645          item.setImage(hotImage);
646       }
647    }
648
649    /**
650     * {@inheritDoc}
651     */

652    public void activateModule(
653       ThickClientModule module
654    )
655    {
656       ToolItem item;
657       
658       item = (ToolItem)m_mapModuleToolItems.get(module.getName());
659       if (item != null)
660       {
661          if (module instanceof SWTThickClientModule)
662          {
663             Composite clientArea;
664             
665             clientArea = ((SWTThickClientModule)module).getClientArea();
666             if (clientArea != null)
667             {
668                clientArea.setVisible(true);
669                ((StackLayout)m_clientArea.getLayout()).topControl = clientArea;
670                m_clientArea.layout();
671             }
672          }
673       
674          // Item can be null if the main window was already hidden
675
item.setSelection(true);
676          if (GlobalConstants.isWindows())
677          {
678             Image hotImage;
679             Image normalImage;
680             
681             // TODO: Bug: SWT 3.0M7: This is a bug in SWT 3.0M7 and below but they
682
// actually say that this is a correct behaviour and that Windows
683
// should not display the hot image when pushed. So when they fix it
684
// on windows we need to remove the check above
685
// Swap the images to signal active module
686
hotImage = item.getHotImage();
687             normalImage = item.getImage();
688             item.setHotImage(normalImage);
689             item.setImage(hotImage);
690          }
691       }
692    }
693    
694    /**
695     * {@inheritDoc}
696     */

697    public void createClientArea(
698    )
699    {
700       // This will decide how will the content are be placed in the main window
701
GridData mainLayoutData = new GridData();
702       mainLayoutData.horizontalAlignment = GridData.FILL;
703       mainLayoutData.verticalAlignment = GridData.FILL;
704       mainLayoutData.grabExcessHorizontalSpace = true;
705       mainLayoutData.grabExcessVerticalSpace = true;
706       m_clientArea.setLayoutData(mainLayoutData);
707
708       // Add label to the main area
709
Composite splashContainer = new Composite(m_clientArea, SWT.NONE);
710       GridLayout layout = new GridLayout();
711       layout.numColumns = 1;
712       splashContainer.setLayout(layout);
713
714       GridData splashData = new GridData();
715       splashData.horizontalAlignment = GridData.CENTER;
716       splashData.verticalAlignment = GridData.END;
717       splashData.grabExcessHorizontalSpace = true;
718       splashData.grabExcessVerticalSpace = true;
719       
720       Label splashImageLabel = new Label(splashContainer, SWT.CENTER | SWT.SHADOW_OUT);
721       splashImageLabel.setLayoutData(splashData);
722       
723       GridData licenseData = new GridData();
724       licenseData.horizontalAlignment = GridData.CENTER;
725       licenseData.verticalAlignment = GridData.END;
726       licenseData.grabExcessHorizontalSpace = true;
727       licenseData.grabExcessVerticalSpace = false;
728       
729       Label license = new Label(splashContainer, SWT.CENTER | SWT.SHADOW_NONE);
730       license.setText("licensed to");
731       license.setLayoutData(licenseData);
732
733       GridData logoData = new GridData();
734       logoData.horizontalAlignment = GridData.CENTER;
735       logoData.verticalAlignment = GridData.BEGINNING;
736       logoData.grabExcessHorizontalSpace = true;
737       logoData.grabExcessVerticalSpace = true;
738       
739       Label logoImageLabel = new Label(splashContainer, SWT.CENTER | SWT.SHADOW_OUT);
740       logoImageLabel.setLayoutData(logoData);
741
742       InputStream JavaDoc image;
743       InputStream JavaDoc logo;
744       
745       // TODO: ThickClient: Fix the build to correctly package and install
746
// the splash.jpg and customerlogo.gif. Ask me for these files.
747

748       image = getClass().getResourceAsStream("/splash.jpg");
749       if (image != null)
750       {
751          m_splashImage = new Image(m_display, image);
752          splashImageLabel.setImage(m_splashImage);
753       }
754       else
755       {
756          splashImageLabel.setText(
757             "Installation is corrupted. Important files are missing.");
758       }
759       logo = getClass().getResourceAsStream("/customerlogo.gif");
760       if (logo != null)
761       {
762          m_logoImage = new Image(m_display, logo);
763          logoImageLabel.setImage(m_logoImage);
764       }
765       else
766       {
767          logoImageLabel.setText(
768             "Installation is corrupted. Important files are missing.");
769       }
770       ((StackLayout)m_clientArea.getLayout()).topControl = splashContainer;
771    }
772    
773    /**
774     * {@inheritDoc}
775     */

776    public void destroyClientArea(
777    )
778    {
779       if ((m_splashImage != null) && (!m_splashImage.isDisposed()))
780       {
781          m_splashImage.dispose();
782          m_splashImage = null;
783       }
784       if ((m_logoImage != null) && (!m_logoImage.isDisposed()))
785       {
786          m_logoImage.dispose();
787          m_logoImage = null;
788       }
789    }
790    
791    /**
792     * {@inheritDoc}
793     */

794    public void displayMainWindow(
795       int iScreenPosition,
796       boolean bFixedSize
797    )
798    {
799       Rectangle client;
800       
801       client = determineClientArea(m_display, iScreenPosition, bFixedSize);
802
803       // Now display the main window and start the application
804
m_shell.pack();
805 // TODO: ThickClient: This will be valid only if the position is not ANYWHERE
806
// Now set the correct location and size so that it occupies the
807
// full screen
808
m_shell.setLocation(client.x, client.y);
809       m_shell.setSize(client.width, client.height);
810       m_shell.open();
811    }
812    
813    /**
814     * {@inheritDoc}
815     */

816    public void interactWithUser(
817    )
818    {
819       while (!m_shell.isDisposed())
820       {
821          if (!m_display.readAndDispatch())
822          {
823             m_display.sleep();
824          }
825       }
826    }
827    
828    /**
829     * {@inheritDoc}
830     */

831    public String JavaDoc getGuiTechnology(
832    )
833    {
834       return SWT_GUI_TECHNOLOGY;
835    }
836    
837    /**
838     * Determine the client area which should be occupied by the GUI. Based on
839     * the options specified when the user was started this may try to maximize
840     * the area occupied by the application or position it to a specific location
841     * of the screen.
842     *
843     * @param display - display which is used to display GUI
844     * @param iScreenPosition - screen position for which to determine the area,
845     * one of the GUI constants
846     * @param bFixedSize - should the gui be fixed size
847     * @return Rectangle - area which should be occupied by GUI
848     */

849    public Rectangle determineClientArea(
850       Display display,
851       int iScreenPosition,
852       boolean bFixedSize
853    )
854    {
855       Monitor screen = null;
856       Rectangle client;
857       
858       // Determine if we have multiple monitors and if we do then what monitor
859
// to use. This way the monitors can have different resolutions and the
860
// GUI can be displayed in different resolution
861
switch (iScreenPosition)
862       {
863          // TODO: ThickClient: Add support for GUI_ANYWHERE and assert for default
864
case (GUI_FULLSCREEN) :
865          {
866             screen = display.getPrimaryMonitor();
867             break;
868          }
869          case (GUI_LEFTSCREEN) :
870          {
871             Monitor[] screens;
872
873             screens = display.getMonitors();
874             if ((screens != null) && (screens.length == 2))
875             {
876                // Determine which screen is the left
877
if (screens[0].getClientArea().x < screens[1].getClientArea().x)
878                {
879                   screen = screens[0];
880                }
881                else
882                {
883                   screen = screens[1];
884                }
885             }
886             break;
887          }
888          case (GUI_RIGHTSCREEN) :
889          {
890             Monitor[] screens;
891
892             screens = display.getMonitors();
893             if ((screens != null) && (screens.length == 2))
894             {
895                // Determine which screen is the left
896
if (screens[0].getClientArea().x < screens[1].getClientArea().x)
897                {
898                   screen = screens[1];
899                }
900                else
901                {
902                   screen = screens[0];
903                }
904             }
905             break;
906          }
907          default:
908          {
909             assert false : "Unknown screen position " + iScreenPosition;
910          }
911       }
912       
913       // TODO: Configure: Make the fixed size 1024x768 configurable.
914
if (screen != null)
915       {
916          // We have found the monitors so try to use it's client are
917
client = screen.getClientArea();
918          if (bFixedSize)
919          {
920             // Keep the origin since it may be in different monitor
921
// and therefore nonzero
922
client.width = 1024;
923             client.height = 768;
924          }
925       }
926       else
927       {
928          // We didn't find correct monitor so simulate it if necessary by
929
// dividing the client area
930
client = display.getClientArea();
931          // TODO: ThickClient: Add support for GUI_ANYWHERE and assert for default
932
switch (iScreenPosition)
933          {
934             case (GUI_FULLSCREEN) :
935             {
936                if (bFixedSize)
937                {
938                   // Keep the origin since it may be in different monitor
939
// and therefore nonzero
940
client.width = 1024;
941                   client.height = 768;
942                }
943                break;
944             }
945             case (GUI_LEFTSCREEN) :
946             {
947                // Take left half of the screen
948
if (bFixedSize)
949                {
950                   client = new Rectangle(0, 0, 1024, 768);
951                }
952                else
953                {
954                   client.width = client.width / 2;
955                }
956                break;
957             }
958             case (GUI_RIGHTSCREEN) :
959             {
960                // Take the right half of the screen
961
if (bFixedSize)
962                {
963                   client.x = client.x + client.width - 1024;
964                   if (client.x < 0)
965                   {
966                      client.x = 0;
967                   }
968                   client.width = 1024;
969                   client.y = client.y + client.height - 768;
970                   if (client.y < 0)
971                   {
972                      client.y = 0;
973                   }
974                   client.height = 768;
975                }
976                else
977                {
978                   client.x = client.x + client.width / 2;
979                   client.width = client.width / 2;
980                }
981                break;
982             }
983             default:
984             {
985                assert false : "Unknown screen position " + iScreenPosition;
986             }
987          }
988       }
989       
990       return client;
991    }
992
993    /**
994     * {@inheritDoc}
995     */

996    public Object JavaDoc displayMessage(
997       String JavaDoc strTitle,
998       String JavaDoc strMessage,
999       Object JavaDoc additionalInfo
1000   )
1001   {
1002      int iStyle;
1003      int iAnswer;
1004      Object JavaDoc objAnswer;
1005      
1006      iStyle = getStyle(additionalInfo);
1007      iAnswer = displayMessage(m_shell, strTitle, strMessage, iStyle);
1008      objAnswer = getAnswer(iAnswer);
1009      
1010      return objAnswer;
1011   }
1012
1013   /**
1014    * Display message to user.
1015    *
1016    * @param shell - shell which should display the message
1017    * @param strTitle - title of the message, look at constants in this interface
1018    * @param strMessage - message to display
1019    * @param additionalInfo - additional information to pass in, this may be
1020    * implementation specific, look at constants in this
1021    * interface
1022    * @return Object - result of the message, this may be implementation
1023    * specific
1024    */

1025   public Object JavaDoc displayMessage(
1026      Shell shell,
1027      String JavaDoc strTitle,
1028      String JavaDoc strMessage,
1029      Object JavaDoc additionalInfo
1030   )
1031   {
1032      int iStyle;
1033      int iAnswer;
1034      Object JavaDoc objAnswer;
1035      
1036      iStyle = getStyle(additionalInfo);
1037      iAnswer = displayMessage(shell, strTitle, strMessage, iStyle);
1038      objAnswer = getAnswer(iAnswer);
1039      
1040      return objAnswer;
1041   }
1042
1043   // Helper methods ///////////////////////////////////////////////////////////
1044

1045   /**
1046    * Display message to user.
1047    *
1048    * @param shell - shell which should display the message
1049    * @param strTitle - title of the message
1050    * @param strMessage - message to display
1051    * @param iStyle - style of the message box to display
1052    * @return int - result of the message box
1053    */

1054   protected int displayMessage(
1055      Shell shell,
1056      String JavaDoc strTitle,
1057      String JavaDoc strMessage,
1058      int iStyle
1059   )
1060   {
1061      int iReturn;
1062      boolean bPrivateShell = false;
1063
1064      try
1065      {
1066         if (shell == null)
1067         {
1068            shell = new Shell(m_display);
1069            bPrivateShell = true;
1070         }
1071         
1072         MessageBox messageBox = new MessageBox(shell, iStyle);
1073         messageBox.setText(strTitle);
1074         messageBox.setMessage(strMessage);
1075         iReturn = messageBox.open();
1076      }
1077      finally
1078      {
1079         if ((shell != null) && (bPrivateShell))
1080         {
1081            shell.dispose();
1082         }
1083      }
1084      
1085      return iReturn;
1086   }
1087
1088   /**
1089    * Add module to the gui
1090    *
1091    * @param module - module to add
1092    */

1093   protected void addModule(
1094      ThickClientModule module
1095   )
1096   {
1097      ToolItem moduleItem;
1098      
1099      if (SeparatorModule.SEPARATOR.equals(module.getName()))
1100      {
1101         // This is special module which should be represented specially so that
1102
// we cannot really switch to it
1103
moduleItem = new ToolItem(m_moduleBar, SWT.SEPARATOR);
1104         
1105         // No need to remember separators in m_mapModuleToolItems
1106
}
1107      else
1108      {
1109         ModuleListener listener;
1110         Image[] images = null;
1111         
1112         moduleItem = new ToolItem(m_moduleBar, SWT.PUSH);
1113         moduleItem.setText(module.getName());
1114         
1115         if (module instanceof SWTThickClientModule)
1116         {
1117            images = ((SWTThickClientModule)module).getToolbarImages(this);
1118         }
1119         if (images != null)
1120         {
1121            moduleItem.setImage(images[0]);
1122            moduleItem.setDisabledImage(images[1]);
1123            moduleItem.setHotImage(images[2]);
1124         }
1125         else
1126         {
1127            moduleItem.setImage(m_blueImage);
1128            moduleItem.setDisabledImage(m_grayImage);
1129            moduleItem.setHotImage(m_greenImage);
1130         }
1131         
1132         listener = new ModuleListener(m_client, module.getName());
1133         moduleItem.addSelectionListener(listener);
1134         moduleItem.addDisposeListener(listener);
1135         
1136         m_mapModuleToolItems.put(module.getName(), moduleItem);
1137      }
1138   }
1139   
1140   /**
1141    * Convert the passed in style into valid SWT style.
1142    *
1143    * @param objStyle - one of the style constants in ThickClientGui
1144    * @return int - valid SWT style
1145    */

1146   protected int getStyle(
1147      Object JavaDoc objStyle
1148   )
1149   {
1150      int iStyle = 0;
1151      
1152      if (MESSAGE_STYLE_YES_NO_QUESTION.equals(objStyle))
1153      {
1154         iStyle = SWT_MESSAGE_YES_NO_QUESTION;
1155      }
1156      else if (MESSAGE_STYLE_ERROR.equals(objStyle))
1157      {
1158         iStyle = SWT_MESSAGE_ERROR;
1159      }
1160      else if (MESSAGE_STYLE_INFO.equals(objStyle))
1161      {
1162         iStyle = SWT_MESSAGE_INFO;
1163      }
1164      else
1165      {
1166         assert false : "Unknown message style to display " + objStyle;
1167      }
1168      
1169      return iStyle;
1170   }
1171   
1172   /**
1173    * Convert the passed in SWT answer into a predefined answer
1174    *
1175    * @param iAnswer - SWT answer
1176    * @return Object - one of asnwers defined in ThickClientGui or an Integer
1177    * value of the answer
1178    */

1179   protected Object JavaDoc getAnswer(
1180      int iAnswer
1181   )
1182   {
1183      Object JavaDoc objAnswer;
1184      
1185      if (SWT.YES == iAnswer)
1186      {
1187         objAnswer = MESSAGE_ANSWER_YES;
1188      }
1189      else
1190      {
1191         objAnswer = new Integer JavaDoc(iAnswer);
1192      }
1193
1194      return objAnswer;
1195   }
1196}
1197
Popular Tags