KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > startup > Splash


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.core.startup;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.awt.Color JavaDoc;
24 import java.awt.Component JavaDoc;
25 import java.awt.Dimension JavaDoc;
26 import java.awt.EventQueue JavaDoc;
27 import java.awt.Font JavaDoc;
28 import java.awt.FontMetrics JavaDoc;
29 import java.awt.Frame JavaDoc;
30 import java.awt.Graphics JavaDoc;
31 import java.awt.Graphics2D JavaDoc;
32 import java.awt.Image JavaDoc;
33 import java.awt.Rectangle JavaDoc;
34 import java.awt.RenderingHints JavaDoc;
35 import java.awt.Window JavaDoc;
36 import java.awt.event.ActionEvent JavaDoc;
37 import java.awt.event.ActionListener JavaDoc;
38 import java.awt.event.KeyEvent JavaDoc;
39 import java.lang.ref.Reference JavaDoc;
40 import java.lang.ref.WeakReference JavaDoc;
41 import java.util.MissingResourceException JavaDoc;
42 import java.util.ResourceBundle JavaDoc;
43 import java.util.StringTokenizer JavaDoc;
44 import java.util.logging.Level JavaDoc;
45 import java.util.logging.Logger JavaDoc;
46 import javax.accessibility.Accessible JavaDoc;
47 import javax.swing.ImageIcon JavaDoc;
48 import javax.swing.JComponent JavaDoc;
49 import javax.swing.JDialog JavaDoc;
50 import javax.swing.JPanel JavaDoc;
51 import javax.swing.JTabbedPane JavaDoc;
52 import javax.swing.KeyStroke JavaDoc;
53 import static javax.swing.SwingConstants JavaDoc.*;
54 import javax.swing.SwingUtilities JavaDoc;
55 import javax.swing.WindowConstants JavaDoc;
56 import org.netbeans.Util;
57 import org.openide.util.Utilities;
58 import org.openide.util.NbBundle;
59
60 /** A class that encapsulates all the splash screen things.
61 *
62 * @author Ian Formanek, David Peroutka, Radim Kubacki
63 */

64 public final class Splash {
65
66     private static Splash splash;
67     
68     /** is there progress bar in splash or not */
69     private static boolean noBar = Boolean.getBoolean("netbeans.splash.nobar");
70     
71     static {
72     ResourceBundle JavaDoc bundle = NbBundle.getBundle(Splash.class);
73     noBar |= !Boolean.parseBoolean(bundle.getString("SplashShowProgressBar"));
74     }
75     
76     public static Splash getInstance() {
77     if (splash == null) {
78         splash = new Splash();
79     }
80     return splash;
81     }
82     
83     public static void showAboutDialog (java.awt.Frame JavaDoc parent, javax.swing.JComponent JavaDoc info) {
84         createAboutDialog (parent, info).setVisible(true);
85     }
86     
87     private static JDialog JavaDoc createAboutDialog (java.awt.Frame JavaDoc parent, javax.swing.JComponent JavaDoc info) {
88         SplashDialog splashDialog = new SplashDialog (parent, info);
89         return splashDialog;
90     }
91
92     // Copied from MainWindow:
93
private static final String JavaDoc ICON_SMALL = "org/netbeans/core/startup/frame.gif"; // NOI18N
94
private static final String JavaDoc ICON_BIG = "org/netbeans/core/startup/frame32.gif"; // NOI18N
95

96     private static Image JavaDoc createIDEImage() {
97     return Utilities.loadImage(Utilities.isLargeFrameIcons() ? ICON_BIG : ICON_SMALL, true);
98     }
99     
100     private Frame JavaDoc frame;
101     
102     private SplashComponent comp;
103     
104     private Splash() {
105     comp = new SplashComponent(false);
106     }
107     
108     /** Enables or disables splash component and its progress
109      * animation
110      */

111     public void setRunning(boolean running) {
112     if (CLIOptions.isNoSplash())
113         return;
114     
115     if (running) {
116         if (frame == null) {
117         frame = new Frame JavaDoc(NbBundle.getMessage(Splash.class, "LBL_splash_window_title")); // e.g. for window tray display
118
frame.setIconImage(createIDEImage()); // again, only for possible window tray display
119
frame.setUndecorated(true);
120         // add splash component
121
frame.setLayout (new BorderLayout JavaDoc());
122         frame.add(comp, BorderLayout.CENTER);
123         
124         int width = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_WIDTH"));
125         int height = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_HEIGHT"));
126         frame.setPreferredSize(new Dimension JavaDoc(width, height));
127         
128         SwingUtilities.invokeLater (new SplashRunner(frame, true));
129         }
130     }
131     else {
132         SwingUtilities.invokeLater (new SplashRunner(frame, false));
133     }
134     }
135     
136     public void dispose() {
137     setRunning(false);
138     splash = null;
139     }
140     
141     public void increment(int steps) {
142     if (noBar || CLIOptions.isNoSplash())
143         return;
144     
145 //System.out.println("Splash.increment ("+steps+"), "+comp);
146
if (comp != null) {
147         comp.increment(steps);
148     }
149     }
150     
151     public Component JavaDoc getComponent() {
152     return comp;
153     }
154     
155     /** Updates text in splash window
156      */

157     public void print (String JavaDoc s) {
158     if (CLIOptions.isNoSplash() || comp == null)
159         return;
160     
161     comp.setText(s);
162 //System.out.println("Splash.print ("+s+"), "+comp);
163
}
164
165     /** Adds specified numbers of steps to a progress
166      */

167     public void addToMaxSteps(int steps) {
168     if (noBar || CLIOptions.isNoSplash())
169         return;
170     
171 //System.out.println("Splash.addToMaxSteps ("+steps+"), "+comp);
172
if (comp != null) {
173         comp.addToMaxSteps(steps);
174     }
175     }
176     
177 //****************************************************************************
178
/**
179      * Standard way how to place the window to the center of the screen.
180      */

181     static final void center(Window JavaDoc c) {
182         c.pack();
183         c.setBounds(Utilities.findCenterBounds(c.getSize()));
184     }
185
186     /** Loads a splash image from its source */
187     private static Image JavaDoc loadSplash() {
188         return Utilities.loadImage("org/netbeans/core/startup/splash.gif", true);
189     }
190
191     /** Loads an about image from its source */
192     private static Image JavaDoc loadAbout() {
193         Image JavaDoc img = Utilities.loadImage("org/netbeans/core/startup/about.gif", true);
194         if (img != null) {
195             return img;
196         } else {
197             return loadSplash();
198         }
199     }
200
201     /**
202      * This class implements double-buffered splash screen component.
203      */

204     private static class SplashComponent extends JComponent JavaDoc implements Accessible JavaDoc {
205
206     Rectangle JavaDoc view;
207     Color JavaDoc color_text;
208     Color JavaDoc color_bar;
209     Color JavaDoc color_edge;
210     Color JavaDoc color_corner;
211     
212     /** font size for splash texts */
213     private int size = 12;
214     private Rectangle JavaDoc dirty = new Rectangle JavaDoc();
215     private Rectangle JavaDoc rect = new Rectangle JavaDoc();
216     private Rectangle JavaDoc bar = new Rectangle JavaDoc();
217     private Rectangle JavaDoc bar_inc = new Rectangle JavaDoc();
218     
219     private int progress = 0;
220     private int maxSteps = 0;
221     private int tmpSteps = 0;
222     private int barStart = 0;
223     private int barLength = 0;
224     
225         private Image JavaDoc image;
226     private String JavaDoc text;
227     private FontMetrics JavaDoc fm;
228
229     /**
230          * Creates a new splash screen component.
231      * param about true is this component will be used in about dialog
232          */

233         public SplashComponent(boolean about) {
234         
235         // 100 is allocated for module system that will adjust this when number
236
// of existing modules is known
237
maxSteps = 140;
238         
239         ResourceBundle JavaDoc bundle = NbBundle.getBundle(Splash.class);
240         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(
241             bundle.getString("SplashRunningTextBounds"), " ,"); // NOI18N
242
view = new Rectangle JavaDoc(Integer.parseInt(st.nextToken()),
243             Integer.parseInt(st.nextToken()),
244             Integer.parseInt(st.nextToken()),
245             Integer.parseInt(st.nextToken()));
246         st = new StringTokenizer JavaDoc(
247             bundle.getString("SplashProgressBarBounds"), " ,"); // NOI18N
248
try {
249         bar = new Rectangle JavaDoc(Integer.parseInt(st.nextToken()),
250             Integer.parseInt(st.nextToken()),
251             Integer.parseInt(st.nextToken()),
252             Integer.parseInt(st.nextToken()));
253         Integer JavaDoc rgb = Integer.decode(bundle.getString("SplashRunningTextColor")); // NOI18N
254
color_text = new Color JavaDoc(rgb.intValue());
255         rgb = Integer.decode(bundle.getString("SplashProgressBarColor")); // NOI18N
256
color_bar = new Color JavaDoc(rgb.intValue());
257         rgb = Integer.decode(bundle.getString("SplashProgressBarEdgeColor")); // NOI18N
258
color_edge = new Color JavaDoc(rgb.intValue());
259         rgb = Integer.decode(bundle.getString("SplashProgressBarCornerColor")); // NOI18N
260
color_corner = new Color JavaDoc(rgb.intValue());
261         } catch (NumberFormatException JavaDoc nfe) {
262         //IZ 37515 - NbBundle.DEBUG causes startup to fail - provide some useless values
263
Util.err.warning("Number format exception " + //NOI18N
264
"loading splash screen parameters."); //NOI18N
265
Logger.getLogger("global").log(Level.WARNING, null, nfe);
266         color_text = Color.BLACK;
267         color_bar = Color.ORANGE;
268         color_edge = Color.BLUE;
269         color_corner = Color.GREEN;
270         bar = new Rectangle JavaDoc(0, 0, 80, 10);
271         }
272         try {
273         String JavaDoc sizeStr = bundle.getString("SplashRunningTextFontSize");
274         size = Integer.parseInt(sizeStr);
275         } catch(MissingResourceException JavaDoc e){
276         //ignore - use default size
277
} catch (NumberFormatException JavaDoc nfe) {
278         //ignore - use default size
279
}
280         
281         image = new ImageIcon JavaDoc(about? loadAbout(): loadSplash()).getImage(); // load!
282

283         Font JavaDoc font = new Font JavaDoc("Dialog", Font.PLAIN, size);
284         
285         setFont(font); // NOI18N
286
fm = getFontMetrics(font);
287         }
288
289         /**
290          * Defines the single line of text this component will display.
291          */

292         public void setText(final String JavaDoc text) {
293         // trying to set again the same text?
294
if (text != null && text.equals(this.text)) return;
295         
296             // run in AWT, there were problems with accessing font metrics
297
// from now AWT thread
298
EventQueue.invokeLater(new Runnable JavaDoc() {
299                 public void run () {
300                     if (text == null) {
301                         repaint(dirty);
302                         return;
303                     }
304
305                     if (fm == null)
306                         return;
307
308                     adjustText(text);
309
310                     SwingUtilities.layoutCompoundLabel(fm, text, null,
311                                                        BOTTOM, LEFT, BOTTOM, LEFT,
312                                                        view, new Rectangle JavaDoc(), rect, 0);
313                     dirty = dirty.union(rect);
314                     // update screen (assume repaint manager optimizes unions;)
315
repaint(dirty);
316                     dirty = new Rectangle JavaDoc(rect);
317                 }
318             });
319         }
320         
321         /**
322          * Creates new text with the ellipsis at the end when text width is
323          * bigger than allowed space
324          */

325         private void adjustText(String JavaDoc text) {
326             String JavaDoc newText = null;
327             String JavaDoc newString;
328             
329             if (text == null)
330                 return ;
331
332             if (fm == null)
333                 return;
334             
335             int width = fm.stringWidth(text);
336             
337             if (width > view.width) {
338                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(text);
339                 while (st.hasMoreTokens()) {
340                     String JavaDoc element = st.nextToken();
341                     if (newText == null)
342                         newString = element;
343                     else
344                         newString = newText + " " + element; // NOI18N
345
if (fm.stringWidth(newString + "...") > view.width) { // NOI18N
346
this.text = newText + "..."; // NOI18N
347
break;
348                     } else
349                         newText = newString;
350                         
351                 }
352                 // #71064 - cut the text and put the ellipsis correctly when
353
// very loong text without spaces that exceeds available space is used
354
// it can happen in multibyte environment (such as japanese)
355
if (newText == null) {
356                     this.text = "";
357                     newString = "";
358                     newText = "";
359                     for (int i = 0; i < text.length(); i++) {
360                         newString += text.charAt(i);
361                         if (fm.stringWidth(newString + "...") > view.width) { // NOI18N
362
this.text = newText + "..."; // NOI18N
363
break;
364                         } else {
365                             newText = newString;
366                         }
367                     }
368                 }
369             } else
370                 this.text = text;
371         }
372     
373     public void increment(int steps) {
374         progress += steps;
375         if (progress > maxSteps)
376         progress = maxSteps;
377         else if (maxSteps > 0) {
378         int bl = bar.width * progress / maxSteps - barStart;
379         if (bl > 1 || barStart % 2 == 0) {
380             barLength = bl;
381             bar_inc = new Rectangle JavaDoc(bar.x + barStart, bar.y, barLength + 1, bar.height);
382 //System.out.println(this);
383
repaint(bar_inc);
384 //System.out.println("(painting " + bar_inc + ")");
385
}
386         }
387     }
388     
389
390     /** Adds space for given number of steps.
391      * It also alters progress to preserve ratio between completed and total
392      * number of steps.
393      */

394     private void addToMaxSteps(int steps) {
395         int max = maxSteps + steps;
396         int prog = progress / maxSteps * max;
397         maxSteps = max;
398         progress = prog;
399         // do repaint on next increment
400
}
401     
402         /**
403          * Override update to *not* erase the background before painting.
404          */

405         public void update(Graphics JavaDoc g) {
406             paint(g);
407         }
408
409         /**
410          * Renders this component to the given graphics.
411          */

412         public void paint(Graphics JavaDoc graphics) {
413             graphics.setColor(color_text);
414             graphics.drawImage(image, 0, 0, null);
415
416             if (text != null) {
417         if (fm == null) {
418             // XXX(-ttran) this happened on Japanese Windows NT, don't
419
// fully understand why
420
return;
421         }
422         
423         SwingUtilities.layoutCompoundLabel(fm, text, null,
424             BOTTOM, LEFT, BOTTOM, LEFT,
425             view, new Rectangle JavaDoc(), rect, 0);
426         // turn anti-aliasing on for the splash text
427
Graphics2D JavaDoc g2d = (Graphics2D JavaDoc)graphics;
428         g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
429             RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
430         graphics.drawString(text, rect.x, rect.y + fm.getAscent());
431             }
432
433             // Draw progress bar if applicable
434
if (!noBar && maxSteps > 0/* && barLength > 0*/)
435             {
436                 graphics.setColor(color_bar);
437                 graphics.fillRect(bar.x, bar.y, barStart + barLength, bar.height);
438                 graphics.setColor(color_corner);
439                 graphics.drawLine(bar.x, bar.y, bar.x, bar.y + bar.height);
440                 graphics.drawLine(bar.x + barStart + barLength, bar.y, bar.x + barStart + barLength, bar.y + bar.height);
441                 graphics.setColor(color_edge);
442                 graphics.drawLine(bar.x, bar.y + bar.height / 2, bar.x, bar.y + bar.height / 2);
443                 graphics.drawLine(bar.x + barStart + barLength, bar.y + bar.height / 2, bar.x + barStart + barLength, bar.y + bar.height / 2);
444                 barStart += barLength;
445                 barLength = 0;
446             }
447         }
448
449         public Dimension JavaDoc getPreferredSize() {
450             return new Dimension JavaDoc(image.getWidth (null), image.getHeight (null));
451         }
452
453         public boolean isOpaque () {
454             return true;
455         }
456         
457     public String JavaDoc toString() {
458         return "SplashComponent - " +
459             "progress: " + progress + "/" + maxSteps +
460             " text: " + text;
461     }
462     }
463
464     private static class SplashDialog extends JDialog JavaDoc implements ActionListener JavaDoc {
465         /** generated Serialized Version UID */
466         static final long serialVersionUID = 5185644855500178404L;
467
468         private final SplashComponent splashComponent = new SplashComponent(true);
469         
470         /** Creates a new SplashDialog */
471         public SplashDialog (java.awt.Frame JavaDoc parent, javax.swing.JComponent JavaDoc infoPanel) {
472             super (parent, true);
473     
474             JPanel JavaDoc splashPanel = new JPanel JavaDoc();
475             JTabbedPane JavaDoc tabbedPane = new JTabbedPane JavaDoc();
476             setTitle (NbBundle.getMessage(Splash.class, "CTL_About_Title"));
477             // add splash component
478
splashPanel.add (splashComponent);
479             tabbedPane.addTab(NbBundle.getMessage(Splash.class, "CTL_About_Title"), splashPanel);
480             tabbedPane.addTab(NbBundle.getMessage(Splash.class, "CTL_About_Detail"), infoPanel);
481             getContentPane().add(tabbedPane, BorderLayout.CENTER);
482
483             getRootPane().registerKeyboardAction(
484                 this,
485                 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
486                 JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
487             );
488             
489             tabbedPane.getAccessibleContext().setAccessibleName(NbBundle.getMessage(Splash.class, "ACSN_AboutTabs"));
490             tabbedPane.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(Splash.class, "ACSD_AboutTabs"));
491             getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(Splash.class, "ACSD_AboutDialog"));
492             
493             Splash.center(this);
494             
495             setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
496         }
497
498         public void actionPerformed(ActionEvent JavaDoc e) {
499             setVisible (false);
500             dispose();
501         }
502     }
503
504     private static class SplashRunner implements Runnable JavaDoc {
505
506         private Window JavaDoc splashWindow;
507         private boolean visible;
508
509         public SplashRunner(Window JavaDoc splashWindow, boolean visible) {
510             this.splashWindow = splashWindow;
511             this.visible = visible;
512         }
513
514         public void run() {
515             if (visible) {
516                 Splash.center(splashWindow);
517                 splashWindow.setVisible(true);
518                 splashWindow.toFront ();
519             }
520             else {
521                 splashWindow.setVisible (false);
522                 splashWindow.dispose ();
523             }
524         }
525     }
526
527 }
528
Popular Tags