Index: core/startup/src/org/netbeans/core/startup/Splash.java =================================================================== RCS file: /shared/data/ccvs/repository/core/startup/src/org/netbeans/core/startup/Splash.java,v retrieving revision 1.15 diff -u -r1.15 Splash.java --- core/startup/src/org/netbeans/core/startup/Splash.java 13 Jul 2006 08:19:03 -0000 1.15 +++ core/startup/src/org/netbeans/core/startup/Splash.java 20 Jul 2006 15:47:36 -0000 @@ -29,9 +29,11 @@ import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.HeadlessException; import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.SplashScreen; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -97,8 +99,6 @@ return Utilities.loadImage(Utilities.isLargeFrameIcons() ? ICON_BIG : ICON_SMALL, true); } - private Frame frame; - private SplashComponent comp; private Splash() { @@ -113,23 +113,10 @@ return; if (running) { - if (frame == null) { - frame = new Frame(NbBundle.getMessage(Splash.class, "LBL_splash_window_title")); // e.g. for window tray display - frame.setIconImage(createIDEImage()); // again, only for possible window tray display - frame.setUndecorated(true); - // add splash component - frame.setLayout (new BorderLayout()); - frame.add(comp, BorderLayout.CENTER); - - int width = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_WIDTH")); - int height = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_HEIGHT")); - frame.setPreferredSize(new Dimension(width, height)); - - SwingUtilities.invokeLater (new SplashRunner(frame, true)); - } + comp.start(); } else { - SwingUtilities.invokeLater (new SplashRunner(frame, false)); + comp.stop(); } } @@ -197,6 +184,14 @@ return loadSplash(); } } + + private static class NativeSplash { + + + void close() { + + } + } /** * This class implements double-buffered splash screen component. @@ -215,6 +210,7 @@ private Rectangle rect = new Rectangle(); private Rectangle bar = new Rectangle(); private Rectangle bar_inc = new Rectangle(); + final private Rectangle nativeClip; private int progress = 0; private int maxSteps = 0; @@ -226,6 +222,12 @@ private String text; private FontMetrics fm; + private Frame frame; + + private Object nativeSplash; + + private boolean about; // flag about/splash + /** * Creates a new splash screen component. * param about true is this component will be used in about dialog @@ -277,16 +279,48 @@ } catch (NumberFormatException nfe) { //ignore - use default size } + this.about = about; - image = new ImageIcon(about? loadAbout(): loadSplash()).getImage(); // load! - Font font = new Font("Dialog", Font.PLAIN, size); setFont(font); // NOI18N fm = getFontMetrics(font); + nativeClip = bar.union(view); } - /** + public void start() { + nativeSplash = getNative(); + // we are already showing splash + if (nativeSplash != null) + return; + + if (frame == null) { + image = new ImageIcon(about? loadAbout(): loadSplash()).getImage(); // load! + + frame = new Frame(NbBundle.getMessage(Splash.class, "LBL_splash_window_title")); // e.g. for window tray display + frame.setIconImage(createIDEImage()); // again, only for possible window tray display + frame.setUndecorated(true); + // add splash component + frame.setLayout (new BorderLayout()); + frame.add(this, BorderLayout.CENTER); + + int width = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_WIDTH")); + int height = Integer.parseInt(NbBundle.getMessage(Splash.class, "SPLASH_HEIGHT")); + frame.setPreferredSize(new Dimension(width, height)); + + SwingUtilities.invokeLater (new SplashRunner(frame, true)); + } + } + + private void stop() { + if (nativeSplash != null) { + closeNative(nativeSplash); + return; + } + SwingUtilities.invokeLater (new SplashRunner(frame, false)); + } + + /** * Defines the single line of text this component will display. */ public void setText(final String text) { @@ -312,7 +346,14 @@ view, new Rectangle(), rect, 0); dirty = dirty.union(rect); // update screen (assume repaint manager optimizes unions;) - repaint(dirty); + Object ss = getNative(); + if (ss != null) { + updateNative(ss, dirty); + nativeRepaintText = true; + } + else { + repaint(dirty); + } dirty = new Rectangle(rect); } }); @@ -376,11 +417,18 @@ progress = maxSteps; else if (maxSteps > 0) { int bl = bar.width * progress / maxSteps - barStart; - if (bl > 1 || barStart % 2 == 0) { + if (bl > 2) { barLength = bl; bar_inc = new Rectangle(bar.x + barStart, bar.y, barLength + 1, bar.height); //System.out.println(this); - repaint(bar_inc); + Object ss = getNative(); + if (ss != null) { + updateNative(ss, bar); + nativeRepaintBar = true; + } + else { + repaint(bar_inc); + } //System.out.println("(painting " + bar_inc + ")"); } } @@ -393,7 +441,7 @@ */ private void addToMaxSteps(int steps) { int max = maxSteps + steps; - int prog = progress / maxSteps * max; + int prog = progress * max / maxSteps ; maxSteps = max; progress = prog; // do repaint on next increment @@ -410,8 +458,17 @@ * Renders this component to the given graphics. */ public void paint(Graphics graphics) { + paint(graphics, false); + } + + /** + * Renders this component to the given graphics. + */ + private void paint(Graphics graphics, boolean toNative) { graphics.setColor(color_text); - graphics.drawImage(image, 0, 0, null); + if (!toNative) { + graphics.drawImage(image, 0, 0, null); + } if (text != null) { if (fm == null) { @@ -419,6 +476,8 @@ // fully understand why return; } + Rectangle clip = graphics.getClipBounds(); + if ((clip == null || clip.intersects(view)) && (!toNative || nativeRepaintText)) { SwingUtilities.layoutCompoundLabel(fm, text, null, BOTTOM, LEFT, BOTTOM, LEFT, @@ -428,10 +487,14 @@ g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); graphics.drawString(text, rect.x, rect.y + fm.getAscent()); + } +// else { +// System.out.println("skipping text painting"); +// } } // Draw progress bar if applicable - if (!noBar && maxSteps > 0/* && barLength > 0*/) + if (!noBar && maxSteps > 0/* && barLength > 0*/ && (!toNative || nativeRepaintBar)) { graphics.setColor(color_bar); graphics.fillRect(bar.x, bar.y, barStart + barLength, bar.height); @@ -439,11 +502,14 @@ graphics.drawLine(bar.x, bar.y, bar.x, bar.y + bar.height); graphics.drawLine(bar.x + barStart + barLength, bar.y, bar.x + barStart + barLength, bar.y + bar.height); graphics.setColor(color_edge); - graphics.drawLine(bar.x, bar.y + bar.height / 2, bar.x, bar.y + bar.height / 2); - graphics.drawLine(bar.x + barStart + barLength, bar.y + bar.height / 2, bar.x + barStart + barLength, bar.y + bar.height / 2); + graphics.drawLine(bar.x, bar.y + bar.height / 2, bar.x, bar.y + bar.height - bar.height / 2); + graphics.drawLine(bar.x + barStart + barLength, bar.y + bar.height / 2, bar.x + barStart + barLength, bar.y + bar.height - bar.height / 2); barStart += barLength; barLength = 0; } + nativeRepaintScheduled = false; + nativeRepaintBar = false; + nativeRepaintText = false; } public Dimension getPreferredSize() { @@ -454,11 +520,77 @@ return true; } + private Object getNative () { + if (ss == null) { + try { + ss = SplashScreen.getSplashScreen(); + if (ss != null) { + nativeGraphics = ss.createGraphics(); + nativeGraphics.setClip(nativeClip); + } + } catch (UnsupportedOperationException ex) { // OK, not supported + } + } + + return ss; + } + + private void closeNative(Object ss) { + System.out.println("counter "+counter); + if (ss != null) { + try { + ((SplashScreen)ss).close(); + } + catch (IllegalStateException ise) { + ss = null; + nativeGraphics = null; + } + } + } + + private boolean nativeRepaintScheduled = false; + private boolean nativeRepaintBar = false; + private boolean nativeRepaintText = false; + + private SplashScreen ss = null; + private Graphics2D nativeGraphics; + + private static int counter = 0; + + private void updateNative(Object ss, final Rectangle clip) { + if (nativeRepaintScheduled) + return; + final SplashScreen s = (SplashScreen)ss; + nativeRepaintScheduled = true; + SwingUtilities.invokeLater(new Runnable() { + public void run() { + try { + long t0 = System.currentTimeMillis(); +// g.setClip(clip); + Graphics2D g = nativeGraphics; + if (g == null) + return; + paint(g, true); + long t1 = System.currentTimeMillis(); +// g.setClip(nativeClip); + s.update(); + long t2 = System.currentTimeMillis(); + ++counter; +// System.out.println("splash update "+counter+": "+(t1-t0)+",\t"+(t2-t1)+", "+System.identityHashCode(nativeGraphics)); + } + catch (IllegalStateException ex) {} // ignore + } + + }); + } + + public String toString() { return "SplashComponent - " + "progress: " + progress + "/" + maxSteps + " text: " + text; } + } private static class SplashDialog extends JDialog implements ActionListener { @@ -523,5 +655,9 @@ } } } + + public org.netbeans.core.startup.Splash.SplashComponent getComp() { + return comp; + } }