alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core;

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import java.util.MissingResourceException;
import javax.swing.*;
import javax.swing.border.*;

import org.openide.*;
import org.openide.loaders.*;
import org.openide.actions.*;
import org.openide.filesystems.*;
import org.openide.filesystems.FileSystem;
import org.openide.windows.*;
import org.openide.explorer.*;
import org.openide.util.NbBundle;
import org.openide.util.SharedClassObject;
import org.openide.util.Utilities;
import org.openide.util.io.*;
import org.openide.nodes.*;

import org.netbeans.core.actions.*;
import org.netbeans.core.perftool.StartLog;
import java.util.Hashtable;
import java.lang.reflect.Field;
import java.net.URL;
import javax.swing.plaf.InputMapUIResource;
import javax.swing.plaf.metal.MetalLookAndFeel;
import org.openide.awt.StatusDisplayer;

/**
 * Main class for NetBeans when run in GUI mode.
 */
public final class Main extends NonGui {

  /** starting time, set at the beginning of start() */
  private static long startTime;
    
  /** is there a splash screen or not */
  private static Splash.SplashOutput splash;

  /** Defines a max value for splash progress bar.
   */
  public static void setSplashMaxSteps(int maxSteps)
  {
      if (Boolean.getBoolean("netbeans.splash.nobar") || noSplash || splash == null)
          return;
      splash.setMaxSteps(maxSteps);
  }
  
  /** Adds temporary steps to create a max value for splash progress bar later.
   */
  public static void addToSplashMaxSteps(int steps)
  {
      if (Boolean.getBoolean("netbeans.splash.nobar") || noSplash || splash == null)
          return;
      splash.addToMaxSteps(steps);
  }
  
  /** Adds temporary steps and creates a max value for splash progress bar.
   */
  public static void addAndSetSplashMaxSteps(int steps)
  {
      if (Boolean.getBoolean("netbeans.splash.nobar") || noSplash || splash == null)
          return;
      splash.addAndSetMaxSteps(steps);
  }
  
  /** Increments a current value of splash progress bar by one step.
   */
  public static void incrementSplashProgressBar()
  {
      incrementSplashProgressBar(1);
  }
  
  /** Increments a current value of splash progress bar by given steps.
   */
  public static void incrementSplashProgressBar(int steps)
  {
      if (Boolean.getBoolean("netbeans.splash.nobar") || noSplash || splash == null)
          return;
      splash.increment(steps);
  }
  
  /** Starts TopThreadGroup which properly overrides uncaughtException
   * Further - new thread in the group execs main
   */
  public static void main (String[] argv) throws Exception {
    TopThreadGroup tg = new TopThreadGroup ("IDE Main", argv); // NOI18N - programatic name
    StartLog.logStart ("Forwarding to topThreadGroup"); // NOI18N
    tg.start ();
    StartLog.logProgress ("Main.main finished"); // NOI18N
  }

  /**
   * Sets up the custom font size and theme url for the plaf library to
   * process.
   */
  private void initUICustomizations() {
      URL themeURL = null;
      boolean wantTheme = Boolean.getBoolean ("netbeans.useTheme") ||
          uiClass != null && uiClass.getName().indexOf("MetalLookAndFeel") >= 0;

      try {
          if (wantTheme) {
              //Put a couple things into UIDefaults for the plaf library to process if it wants
               FileObject fo =
                    Repository.getDefault().getDefaultFileSystem().findResource("themes.xml"); //NOI18N
               if (fo == null) {            // File under system/ failed --> try to load from a .jar
                    // file in /lib packed as /org/netbeans/core/resources/themes.xml
                    themeURL = getClass().getResource("resources/themes.xml"); // NOI18N
               } else {
                    try {
                        themeURL = fo.getURL();
                    } catch (FileStateInvalidException fsie) {
                        //do nothing
                    }
               }
          }
          //Bugfix #33546: If fontsize was not set from cammand line try to set it from bundle key
          if (uiFontSize == 0) {
              String key = "";
              try {
                  key = NbBundle.getMessage (Main.class, "CTL_globalFontSize"); //NOI18N
              } catch (MissingResourceException mre) {
                  //Key not found, nothing to do
              }
              if (key.length() > 0) {
                  try {
                      uiFontSize = Integer.parseInt(key);
                  } catch (NumberFormatException exc) {
                      //Incorrect value, nothing to do
                  }
              }
          }
      } finally {
          org.netbeans.swing.plaf.Startup.run(uiClass, uiFontSize, themeURL);
      }
      if (uiFontSize > 0 && "GTK".equals(UIManager.getLookAndFeel().getID())) { //NOI18N
          ErrorManager.getDefault().log(ErrorManager.WARNING, NbBundle.getMessage(Main.class,
          "GTK_FONTSIZE_UNSUPPORTED")); //NOI18N
      }
      StartLog.logProgress("Fonts updated"); // NOI18N
  }
  
  /** Initialization code.
  */
  public void run () {
      org.netbeans.core.xml.SAXFactoryImpl.install();
      org.netbeans.core.xml.DOMFactoryImpl.install();
      StartLog.logStart ("TopManager initialization (org.netbeans.core.Main.run())"); //NOI18N
      initUICustomizations();

    // do the non gui initialization
    super.run ();

    StartLog.logProgress ("NonGui part done"); // NOI18N

    StartLog.logEnd ("TopManager initialization (org.netbeans.core.Main.run())"); //NOI18N
  }


  /** Method to initialize the main window.
  */
  protected void initializeMainWindow () {
    StartLog.logStart ("Main window initialization"); //NOI18N

    // #28536: make sure a JRE bug does not prevent the event queue from having
    // the right context class loader
    // and #35470: do it early, before any module-loaded AWT code might run
    // and #36820: even that isn't always early enough, so we need to push
    // a new EQ to enforce the context loader
    // XXX this is a hack!
    try {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                Thread.currentThread().setContextClassLoader(getModuleSystem().getManager().getClassLoader());
                Toolkit.getDefaultToolkit().getSystemEventQueue().push(new EventQueue());
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    // -----------------------------------------------------------------------------------------------------
    // 11. Initialization of main window
      StatusDisplayer.getDefault().setStatusText (NbBundle.getMessage (Main.class, "MSG_MainWindowInit"));

    // force to initialize timer
    // sometimes happened that the timer thread was initialized under
    // a TaskThreadGroup
    // such task never ends or, if killed, timer is over
    Timer timerInit = new Timer(0, new java.awt.event.ActionListener() {
          public void actionPerformed(java.awt.event.ActionEvent ev) { }
    });
    timerInit.setRepeats(false);
    timerInit.start();
    incrementSplashProgressBar(10);
    StartLog.logProgress ("Timer initialized"); // NOI18N

    // -----------------------------------------------------------------------------------------------------
    // 13. Initialize Shortcuts
    if (
        System.getProperty ("netbeans.kill") == null && // NOI18N
        System.getProperty ("netbeans.close") == null // NOI18N
    ) {
        // JST:
        // do not install the shortcut editor when the ide is started
        // for the first time
        //XXX We no longer do a sanity start when building - does this code accomplish anything? - Tim
        ShortcutsFolder.initShortcuts();
    }
    incrementSplashProgressBar();
    StartLog.logProgress ("Shortcuts initialized"); // NOI18N


// -----------------------------------------------------------------------------------------------------
// 14. Open main window

    if (System.getProperty("netbeans.warmup.skip") == null // NOI18N
        && System.getProperty("netbeans.close") == null) // NOI18N
    {
        // #37529 WindowsAPI can be accessed from AWT thread only.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                final Frame mainWindow = WindowManager.getDefault().getMainWindow();
                mainWindow.addComponentListener(new ComponentAdapter() {
                    public void componentShown(ComponentEvent evt) {
                        mainWindow.removeComponentListener(this);
                        WarmUpSupport.warmUp();
                    }
                });
            }
        });
    }

      StatusDisplayer.getDefault().setStatusText (NbBundle.getMessage (Main.class, "MSG_WindowShowInit"));
    if (StartLog.willLog()) {
        waitForMainWindowPaint();
    }
    // Starts GUI components to be created and shown on screen.
    // I.e. main window + current workspace components.

    // Access winsys from AWT thread only. In this case main thread wouldn't harm, just to be kosher.
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            StartLog.logProgress ("Window system initialization"); // NOI18N
            NbTopManager.WindowSystem windowSystem = (NbTopManager.WindowSystem)
                    org.openide.util.Lookup.getDefault().lookup(NbTopManager.WindowSystem.class);
            if(windowSystem != null) {
                windowSystem.load();
                StartLog.logProgress ("Window system loaded"); // NOI18N
                windowSystem.show();
            } else {
                ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, 
                    new NullPointerException("\n\n\nWindowSystem is not supplied!!!\\n\n")); // NOI18N
            }

            StatusDisplayer.getDefault().setStatusText(""); // NOI18N

            StartLog.logProgress ("Window system shown"); // NOI18N
            if (!StartLog.willLog()) {
                maybeDie();
                // note that if we ARE logging and measuring startup,
                // the IDE is killed through wairForMainWindowPaint() called above
            }
        }
    });
    StartLog.logEnd ("Main window initialization"); //NOI18N
  }
  
  /**
  * @exception SecurityException if it is called multiple times
  */
  static void start (String[] args) throws SecurityException {
    startTime = System.currentTimeMillis();
    
    StartLog.logEnd ("Forwarding to topThreadGroup"); // NOI18N
    StartLog.logStart ("Preparation"); // NOI18N
  
    if (System.getProperties ().get ("org.openide.TopManager") == null) { // NOI18N
      // update the top manager to our main if it has not been provided yet
      System.getProperties().put (
        // Note that it is no longer actually a TopManager; historical relic:
        "org.openide.TopManager", // NOI18N
        "org.netbeans.core.Main" // NOI18N
      );
    }

    CLIOptions.initialize();
    StartLog.logProgress ("Command line parsed"); // NOI18N

// -----------------------------------------------------------------------------------------------------
// 4. Display Splash Screen & manager
    StartLog.logStart ("Creation of TopManager"); // NOI18N 

    NbTopManager.get();
    StartLog.logEnd ("Creation of TopManager"); // NOI18N

    // finish starting
    if (splash != null) {
      Splash.hideSplash(splash);
      splash = null;
    }
    StartLog.logProgress ("Splash hidden"); // NOI18N
    StartLog.logEnd ("Preparation"); // NOI18N
  }
  
  private static void endOfStartupMeasuring () {
  
      if (org.netbeans.core.perftool.Util.isRunning()) {
          measureStart(startTime);
      }
      StartLog.logProgress("Startup memory and time measured"); // NOI18N

      StartLog.logMeasuredStartupTime();
      
      maybeDie();
  }

    private static void maybeDie() {
        
      // finish starting
      if (System.getProperty("netbeans.kill") != null) {
          doExit(5);
      }

      // close IDE
      if (System.getProperty("netbeans.close") != null) {
          if (Boolean.getBoolean("netbeans.warm.close")) {
              // Do other stuff related to startup, to measure the effect.
              // Useful for performance testing.
              ShortcutsFolder.initShortcuts();
              new WarmUpSupport().run(); // synchronous
          }
          org.openide.LifecycleManager.getDefault().exit();
      }

  }
  
  private static void waitForMainWindowPaint() {

      // Waits for notification about processed paint event for main window
      // require modified java.awt.EventQueue to run succesfully
      Runnable r = new Runnable() {
          public void run() {
              try {
                  String m = new String("monitor"); // NOI18N
                  synchronized (m) {
                      Field f = java.awt.EventQueue.class.getField("displayingMainWindowMonitor"); // NOI18N
                      f.set(null,m);
                      m.wait();
                  }
                  endOfStartupMeasuring();
              } catch (NoSuchFieldException e) {
                  StartLog.logProgress(e.toString());
              } catch (IllegalAccessException e) {
                  StartLog.logProgress(e.toString());
              } catch (InterruptedException e) {
                  StartLog.logProgress(e.toString());
              }
          }
      };
      new Thread(r).start();
  }
  
    /** Prints out some info about time/heap if the measurement is enabled. */
    private static void measureStart(long time) {
        org.netbeans.core.perftool.Util.waitForSystemThreads();
        org.netbeans.core.perftool.PerformanceMeter pm = org.netbeans.core.perftool.PerformanceMeterFactory.getPerformanceMeter();
        pm.notifyTime("Total startup time:", System.currentTimeMillis() - time); // NOI18N
        Runtime rt = Runtime.getRuntime();
	try {
	    Thread.sleep( 5000 );
	} catch( InterruptedException e ) {}
        for( int i=0; i<5; i++ ) rt.gc();
	try {
	    Thread.sleep( 5000 );
	} catch( InterruptedException e ) {}
        for( int i=0; i<5; i++ ) rt.gc();
        long mem = rt.totalMemory();
	long free = rt.freeMemory();
        pm.notifyMemory("Total heap:", mem); // NOI18N
        pm.notifyMemory("Used heap:", mem - free); // NOI18N
    }

    /** Return splash screen.
   */
  protected Splash.SplashOutput getSplash() {
      return splash;
  }
  
    /** This is a notification about hiding wizards 
     * during startup (Import, Setup). It makes splash screen visible again.
     */
    protected void showSplash () {
        if (!noSplash) {
            if (splash != null) {
                if (Splash.isVisible(splash))
                    return;
                splash = null;
            }
            splash = Splash.showSplash ();
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.