Package com.eteks.sweethome3d.applet

Source Code of com.eteks.sweethome3d.applet.AppletApplication$AppletBasicService

/*
* AppletApplication.java 11 Oct 2008
*
* Sweet Home 3D, Copyright (c) 2008 Emmanuel PUYBARET / eTeks <info@eteks.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.eteks.sweethome3d.applet;

import java.applet.AppletContext;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.jnlp.BasicService;
import javax.jnlp.ServiceManager;
import javax.jnlp.ServiceManagerStub;
import javax.jnlp.UnavailableServiceException;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

import com.eteks.sweethome3d.j3d.Component3DManager;
import com.eteks.sweethome3d.j3d.ModelManager;
import com.eteks.sweethome3d.j3d.TextureManager;
import com.eteks.sweethome3d.model.CollectionEvent;
import com.eteks.sweethome3d.model.CollectionListener;
import com.eteks.sweethome3d.model.Home;
import com.eteks.sweethome3d.model.HomeApplication;
import com.eteks.sweethome3d.model.HomeRecorder;
import com.eteks.sweethome3d.model.UserPreferences;
import com.eteks.sweethome3d.plugin.PluginAction;
import com.eteks.sweethome3d.plugin.PluginManager;
import com.eteks.sweethome3d.swing.ControllerAction;
import com.eteks.sweethome3d.swing.IconManager;
import com.eteks.sweethome3d.swing.ResourceAction;
import com.eteks.sweethome3d.swing.SwingTools;
import com.eteks.sweethome3d.swing.SwingViewFactory;
import com.eteks.sweethome3d.tools.OperatingSystem;
import com.eteks.sweethome3d.viewcontroller.ContentManager;
import com.eteks.sweethome3d.viewcontroller.HomeController;
import com.eteks.sweethome3d.viewcontroller.HomeView;
import com.eteks.sweethome3d.viewcontroller.PlanController;
import com.eteks.sweethome3d.viewcontroller.ViewFactory;

/**
* An application wrapper working in applet.
* @author Emmanuel Puybaret
*/
public class AppletApplication extends HomeApplication {
  private static final String FURNITURE_CATALOG_URLS_PARAMETER       = "furnitureCatalogURLs";
  private static final String FURNITURE_RESOURCES_URL_BASE_PARAMETER = "furnitureResourcesURLBase";
  private static final String TEXTURES_CATALOG_URLS_PARAMETER        = "texturesCatalogURLs";
  private static final String TEXTURES_RESOURCES_URL_BASE_PARAMETER  = "texturesResourcesURLBase";
  private static final String PLUGIN_URLS_PARAMETER                  = "pluginURLs";
  private static final String WRITE_HOME_URL_PARAMETER               = "writeHomeURL";
  private static final String READ_HOME_URL_PARAMETER                = "readHomeURL";
  private static final String LIST_HOMES_URL_PARAMETER               = "listHomesURL";
  private static final String READ_PREFERENCES_URL_PARAMETER         = "readPreferencesURL";
  private static final String WRITE_PREFERENCES_URL_PARAMETER        = "writePreferencesURL";
  private static final String DEFAULT_HOME_PARAMETER                 = "defaultHome";
  private static final String ENABLE_EXPORT_TO_SH3D                  = "enableExportToSH3D";
  private static final String ENABLE_EXPORT_TO_SVG                   = "enableExportToSVG";
  private static final String ENABLE_EXPORT_TO_OBJ                   = "enableExportToOBJ";
  private static final String ENABLE_PRINT_TO_PDF                    = "enablePrintToPDF";
  private static final String ENABLE_CREATE_PHOTO                    = "enableCreatePhoto";
  private static final String ENABLE_CREATE_VIDEO                    = "enableCreateVideo";
  private static final String SHOW_MEMORY_STATUS_PARAMETER           = "showMemoryStatus";
  private static final String USER_LANGUAGE                          = "userLanguage";
 
  private JApplet         applet;
  private final String    name;
  private HomeRecorder    homeRecorder;
  private UserPreferences userPreferences;
  private ContentManager  contentManager;
  private ViewFactory     viewFactory;
  private PluginManager   pluginManager;
  private Timer           memoryStatusTimer;

  public AppletApplication(final JApplet applet) {
    this.applet = applet;
    if (applet.getName() == null) {
      this.name = super.getName();
    } else {
      this.name = applet.getName();
    }
   
    final String readHomeURL = getAppletParameter(applet, READ_HOME_URL_PARAMETER, "readHome.php?home=%s");
    final String defaultHome = getAppletParameter(applet, DEFAULT_HOME_PARAMETER, "");   
    final boolean showMemoryStatus = getAppletBooleanParameter(applet, SHOW_MEMORY_STATUS_PARAMETER);

    URL codeBase = applet.getCodeBase();

    // Force offscreen in 3D view under Plugin 2 and Mac OS X
    System.setProperty("com.eteks.sweethome3d.j3d.useOffScreen3DView",
        String.valueOf(OperatingSystem.isMacOSX()           
            && applet.getAppletContext() != null
            && applet.getAppletContext().getClass().getName().startsWith("sun.plugin2.applet.Plugin2Manager")));
   
    // If Sweet Home 3D applet is launched from outside of Java Web Start or basic service is unavailable
    boolean serviceManagerAvailable = ServiceManager.getServiceNames() != null;
    if (serviceManagerAvailable) {
      try {
        ServiceManager.lookup("javax.jnlp.BasicService");
      } catch (UnavailableServiceException ex) {
        serviceManagerAvailable = false;
      }
    }

    if (!serviceManagerAvailable) {
      // Create JNLP services required by Sweet Home 3D
      ServiceManager.setServiceManagerStub(
          new StandaloneServiceManager(applet.getAppletContext(), codeBase));
      // Caution: setting a new service manager stub won't replace the existing one,
    }         
    initLookAndFeel();
  
    // Add a listener that changes the content pane of the current active applet
    // when a home is added to application
    addHomesListener(new CollectionListener<Home>() {
        private boolean firstHome = true;
       
        public void collectionChanged(CollectionEvent<Home> ev) {
          Home home = ev.getItem();
          switch (ev.getType()) {
            case ADD :
              try {
                final HomeController controller = createHomeController(home);
                // Change applet content
                applet.setContentPane((JComponent)controller.getView());
                applet.getRootPane().revalidate();

                // Open specified home at launch time if it exits
                if (this.firstHome) {
                  this.firstHome = false;
                  if (defaultHome.length() > 0 && readHomeURL.length() != 0) {
                    controller.open(defaultHome);
                  }
                }
              } catch (IllegalStateException ex) {
                // Check exception by class name to avoid a mandatory bind to Java 3D
                if ("javax.media.j3d.IllegalRenderingStateException".equals(ex.getClass().getName())) {
                  ex.printStackTrace();
                  show3DError();
                } else {
                  throw ex;
                }
              }
              break;
          }
        }
      });

    addComponent3DRenderingErrorObserver();
   
    EventQueue.invokeLater(new Runnable() {
        public void run() {
          // Create a home in Event Dispatch Thread
          addHome(createHome());
         
          if (showMemoryStatus) {
            final String memoryStatus = getUserPreferences().getLocalizedString(AppletApplication.class, "memoryStatus");
            // Launch a timer that displays memory used by the applet
            memoryStatusTimer = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                  Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
                  if (focusOwner != null && SwingUtilities.isDescendingFrom(focusOwner, applet)) {
                    Runtime runtime = Runtime.getRuntime();
                    applet.showStatus(String.format(memoryStatus,
                        Math.round(100f * (runtime.totalMemory() - runtime.freeMemory()) / runtime.maxMemory()),
                        runtime.maxMemory() / 1024 / 1024));
                  }
                }
              });
            memoryStatusTimer.start();
          }
        }
      });
  }
 
  /**
   * Deletes open homes and clears all the resources used by this application.
   * This method is called when an applet is destroyed. 
   */
  public void destroy() {
    if (this.memoryStatusTimer != null) {
      this.memoryStatusTimer.stop();
      this.memoryStatusTimer = null;
    }
    for (Home home : getHomes()) {
      // Delete directly home without closing it because when an applet is destroyed
      // we can't control how long a warning dialog about unsaved home will be displayed
      deleteHome(home);
    }
    // Collect deleted objects (seems to be required under Mac OS X when the applet is being reloaded)
    System.gc();
    // Stop managers threads
    IconManager.getInstance().clear();
    if (!"true".equalsIgnoreCase(System.getProperty("com.eteks.sweethome3d.no3D"))) {
      TextureManager.getInstance().clear();
      ModelManager.getInstance().clear();
    }
    // Delete temporary files
    OperatingSystem.deleteTemporaryFiles();
  }

  /**
   * Returns <code>true</code> if one of the homes of this application is modified.
   */
  public boolean isModified() {
    for (Home home : getHomes()) {
      if (home.isModified()) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns the array of URL objects matching the URL list.
   */
  private URL [] getURLs(URL codeBase, String urlList) {
    String [] urlStrings = urlList.split("\\s|,");
    List<URL> urls = new ArrayList<URL>(urlStrings.length);
    for (String urlString : urlStrings) {
      URL url = getURLWithCodeBase(codeBase, urlString);
      if (url != null) {
        urls.add(url);
      }
    }
    return urls.toArray(new URL [urls.size()]);
  }
 
  /**
   * Returns the URL object matching the given <code>url</code> eventually relative to <code>codeBase</code>.
   */
  private URL getURLWithCodeBase(URL codeBase, String url) {
    if (url != null
        && url.length() > 0) {
      try {
        return new URL(codeBase, url);
      } catch (MalformedURLException ex) {
        // Ignore malformed URLs
      }
    }
    return null;
  }
 
  /**
   * Returns the URL matching the given <code>url</code> eventually relative to <code>codeBase</code>.
   */
  private String getURLStringWithCodeBase(URL codeBase, String url) {
    if (url.length() > 0) {
      try {
        return new URL(codeBase, url).toString();
      } catch (MalformedURLException ex) {
        // Ignore malformed URLs
      }
    }
    return null;
  }
 
  /**
   * Returns the parameter value of the given <code>parameter</code> or
   * <code>defaultValue</code> if it doesn't exist.
   */
  private String getAppletParameter(JApplet applet, String parameter, String defaultValue) {
    String parameterValue = applet.getParameter(parameter);
    if (parameterValue == null) {
      return defaultValue;
    } else {
      return parameterValue;
    }
  }
 
  /**
   * Returns the parameter value of the given <code>parameter</code> or
   * <code>false</code> if it doesn't exist.
   */
  private boolean getAppletBooleanParameter(JApplet applet, String parameter) {
    return "true".equalsIgnoreCase(getAppletParameter(applet, parameter, "false"));
  }
 
  /**
   * Returns a new instance of a home controller after <code>home</code> was created.
   */
  protected HomeController createHomeController(Home home) {
    final String writeHomeURL = getAppletParameter(applet, WRITE_HOME_URL_PARAMETER, "writeHome.php");   
    final String readHomeURL = getAppletParameter(applet, READ_HOME_URL_PARAMETER, "readHome.php?home=%s");
    final String listHomesURL = getAppletParameter(applet, LIST_HOMES_URL_PARAMETER, "listHomes.php");
    final String defaultHome = getAppletParameter(applet, DEFAULT_HOME_PARAMETER, "");   
   
    // Create a home controller for new home
    boolean newHomeEnabled =
        writeHomeURL.length() != 0 && listHomesURL.length() != 0;
    boolean openEnabled =
        readHomeURL.length() != 0 && listHomesURL.length() != 0;
    boolean saveEnabled = writeHomeURL.length() != 0
        && (defaultHome.length() != 0 || listHomesURL.length() != 0);
    boolean saveAsEnabled =
        writeHomeURL.length() != 0 && listHomesURL.length() != 0;
   
    final HomeController controller = new HomeAppletController(
        home, AppletApplication.this, getViewFactory(), getContentManager(), getPluginManager(),
        newHomeEnabled, openEnabled, saveEnabled, saveAsEnabled);
   
    JRootPane homeView = (JRootPane)controller.getView();
    // Remove menu bar
    homeView.setJMenuBar(null);
   
    // As the applet has no menu, activate accelerators directly on home view
    for (HomeView.ActionType actionType : HomeView.ActionType.values()) {
      Action action = homeView.getActionMap().get(actionType);
      if (action != null) {
        ResourceAction.MenuItemAction menuAction = new ResourceAction.MenuItemAction(action);
        KeyStroke accelerator = (KeyStroke)menuAction.getValue(Action.ACCELERATOR_KEY);
        if (accelerator != null) {
          homeView.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(accelerator, actionType);
        }
      }
    }
   
    // Change default buttons in toolbar
    JToolBar toolBar = (JToolBar)homeView.getContentPane().getComponent(0);
    toolBar.setFloatable(false);   
    // Retrieve all buttons that are plug-in actions
    List<JComponent> pluginButtons = new ArrayList<JComponent>();
    for (int i = 0; i < toolBar.getComponentCount(); i++) {
      JComponent component = (JComponent)toolBar.getComponent(i);
      if (component instanceof AbstractButton
          && ((AbstractButton)component).getAction().
                getValue(PluginAction.Property.TOOL_BAR.name()) == Boolean.TRUE) {
        pluginButtons.add(component);
      }
    }
    toolBar.removeAll();
    // Add New, Open, Save, Save as buttons if they are enabled
    Action newHomeAction = getToolBarAction(homeView, HomeView.ActionType.NEW_HOME);
    if (newHomeAction != null && newHomeAction.isEnabled()) {
      toolBar.add(newHomeAction);
    }
    Action openAction = getToolBarAction(homeView, HomeView.ActionType.OPEN);
    if (openAction != null && openAction.isEnabled()) {
      toolBar.add(openAction);
    }
    Action saveAction = getToolBarAction(homeView, HomeView.ActionType.SAVE);
    if (saveAction != null && saveAction.isEnabled()) {
      toolBar.add(saveAction);
    }
    Action saveAsAction = getToolBarAction(homeView, HomeView.ActionType.SAVE_AS);
    if (saveAsAction != null && saveAsAction.isEnabled()) {
      toolBar.add(saveAsAction);
    }
   
    if (getAppletBooleanParameter(this.applet, ENABLE_EXPORT_TO_SH3D)) {
      try {
        // Add export to SH3D action
        Action exportToSH3DAction = new ControllerAction(getUserPreferences(),
            AppletApplication.class, "EXPORT_TO_SH3D", controller, "exportToSH3D");
        exportToSH3DAction.setEnabled(true);
        toolBar.add(new ResourceAction.ToolBarAction(exportToSH3DAction));
      } catch (NoSuchMethodException ex) {
        ex.printStackTrace();
      }
    }
   
    if (toolBar.getComponentCount() > 0) {
      toolBar.add(Box.createRigidArea(new Dimension(2, 2)));
    }
    addToolBarAction(homeView, HomeView.ActionType.PAGE_SETUP, toolBar);
    addToolBarAction(homeView, HomeView.ActionType.PRINT, toolBar);
    Action printToPdfAction = getToolBarAction(homeView, HomeView.ActionType.PRINT_TO_PDF);
    if (printToPdfAction != null
        && getAppletBooleanParameter(this.applet, ENABLE_PRINT_TO_PDF)
        && !OperatingSystem.isMacOSX()) {
      controller.getView().setEnabled(HomeView.ActionType.PRINT_TO_PDF, true);
      toolBar.add(printToPdfAction);
    }
    Action preferencesAction = getToolBarAction(homeView, HomeView.ActionType.PREFERENCES);
    if (preferencesAction != null) {
      toolBar.add(Box.createRigidArea(new Dimension(2, 2)));
      toolBar.add(preferencesAction);
    }
    toolBar.addSeparator();

    addToolBarAction(homeView, HomeView.ActionType.UNDO, toolBar);
    addToolBarAction(homeView, HomeView.ActionType.REDO, toolBar);
    toolBar.add(Box.createRigidArea(new Dimension(2, 2)));
    addToolBarAction(homeView, HomeView.ActionType.CUT, toolBar);
    addToolBarAction(homeView, HomeView.ActionType.COPY, toolBar);
    addToolBarAction(homeView, HomeView.ActionType.PASTE, toolBar);
    toolBar.add(Box.createRigidArea(new Dimension(2, 2)));
    addToolBarAction(homeView, HomeView.ActionType.DELETE, toolBar);
    toolBar.addSeparator();

    Action addHomeFurnitureAction = getToolBarAction(homeView, HomeView.ActionType.ADD_HOME_FURNITURE);
    if (addHomeFurnitureAction != null) {
      toolBar.add(addHomeFurnitureAction);
      toolBar.addSeparator();
    }
   
    final JToggleButton selectToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.SELECT));
    selectToggleButton.setSelected(true);
    toolBar.add(selectToggleButton);
    final JToggleButton panToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.PAN));
    toolBar.add(panToggleButton);
    final JToggleButton createWallsToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.CREATE_WALLS));
    toolBar.add(createWallsToggleButton);
    final JToggleButton createRoomsToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.CREATE_ROOMS));
    toolBar.add(createRoomsToggleButton);
    final JToggleButton createDimensionLinesToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.CREATE_DIMENSION_LINES));
    toolBar.add(createDimensionLinesToggleButton);
    final JToggleButton createLabelsToggleButton =
        new JToggleButton(getToolBarAction(homeView, HomeView.ActionType.CREATE_LABELS));
    toolBar.add(createLabelsToggleButton);
    // Add Select, Create Walls and Create dimensions buttons to radio group
    ButtonGroup group = new ButtonGroup();
    group.add(selectToggleButton);
    group.add(panToggleButton);
    group.add(createWallsToggleButton);
    group.add(createRoomsToggleButton);
    group.add(createDimensionLinesToggleButton);
    group.add(createLabelsToggleButton);
    controller.getPlanController().addPropertyChangeListener(PlanController.Property.MODE,
        new PropertyChangeListener() {
          public void propertyChange(PropertyChangeEvent ev) {
            PlanController.Mode mode = controller.getPlanController().getMode();
            selectToggleButton.setSelected(mode == PlanController.Mode.SELECTION);
            panToggleButton.setSelected(mode == PlanController.Mode.PANNING);
            createWallsToggleButton.setSelected(mode == PlanController.Mode.WALL_CREATION);
            createRoomsToggleButton.setSelected(mode == PlanController.Mode.ROOM_CREATION);
            createDimensionLinesToggleButton.setSelected(mode == PlanController.Mode.DIMENSION_LINE_CREATION);
            createLabelsToggleButton.setSelected(mode == PlanController.Mode.LABEL_CREATION);
          }
        });
    toolBar.add(Box.createRigidArea(new Dimension(2, 2)));
   
    addToolBarAction(homeView, HomeView.ActionType.ZOOM_OUT, toolBar);
    addToolBarAction(homeView, HomeView.ActionType.ZOOM_IN, toolBar);

    Action createPhotoAction = getToolBarAction(homeView, HomeView.ActionType.CREATE_PHOTO);
    if (createPhotoAction != null) {
      boolean enableCreatePhoto = getAppletBooleanParameter(this.applet, ENABLE_CREATE_PHOTO);
      controller.getView().setEnabled(HomeView.ActionType.CREATE_PHOTO, enableCreatePhoto);
      if (enableCreatePhoto) {
        toolBar.addSeparator();
        toolBar.add(createPhotoAction);
      }
    }

    // Add plug-in buttons
    if (pluginButtons.size() > 0) {
      toolBar.addSeparator();
      for (JComponent pluginButton : pluginButtons) {
        toolBar.add(pluginButton);
      }
    }
   
    Action aboutAction = getToolBarAction(homeView, HomeView.ActionType.ABOUT);
    if (aboutAction != null) {
      toolBar.addSeparator();
      toolBar.add(aboutAction);
    }
   
    controller.getView().setEnabled(HomeView.ActionType.EXPORT_TO_SVG,
        getAppletBooleanParameter(this.applet, ENABLE_EXPORT_TO_SVG));
    controller.getView().setEnabled(HomeView.ActionType.EXPORT_TO_OBJ,
        getAppletBooleanParameter(this.applet, ENABLE_EXPORT_TO_OBJ));
    controller.getView().setEnabled(HomeView.ActionType.CREATE_VIDEO,
        getAppletBooleanParameter(this.applet, ENABLE_CREATE_VIDEO));
   
    // Add a border
    homeView.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
   
    return controller;
  }
 
  /**
   * Adds the action matching the given <code>actionType</code> to the tool bar if it exists.
   */
  private void addToolBarAction(JComponent homeView, HomeView.ActionType actionType, JToolBar toolBar) {
    Action action = getToolBarAction(homeView, actionType);
    if (action != null) {
      toolBar.add(action);
    }
  }

  /**
   * Returns an action decorated for tool bar buttons.
   */
  private Action getToolBarAction(JComponent homeView, HomeView.ActionType actionType) {
    Action action = homeView.getActionMap().get(actionType);   
    return action != null
        ? new ResourceAction.ToolBarAction(action)
        : null;
  }
 
  /**
   * Returns a recorder able to write and read homes on server.
   */
  @Override
  public HomeRecorder getHomeRecorder() {
    if (this.homeRecorder == null) {
      URL codeBase = this.applet.getCodeBase();
      final String writeHomeURL = getAppletParameter(this.applet, WRITE_HOME_URL_PARAMETER, "writeHome.php");   
      final String readHomeURL = getAppletParameter(this.applet, READ_HOME_URL_PARAMETER, "readHome.php?home=%s");
      final String listHomesURL = getAppletParameter(this.applet, LIST_HOMES_URL_PARAMETER, "listHomes.php");
      this.homeRecorder = new HomeAppletRecorder(getURLStringWithCodeBase(codeBase, writeHomeURL),
          getURLStringWithCodeBase(codeBase, readHomeURL),
          getURLStringWithCodeBase(codeBase, listHomesURL));
    }
    return this.homeRecorder;
  }
 
  /**
   * Returns user preferences.
   */
  @Override
  public UserPreferences getUserPreferences() {
    // Initialize userPreferences lazily
    if (this.userPreferences == null) {
      URL codeBase = this.applet.getCodeBase();
      final String furnitureCatalogURLs = getAppletParameter(this.applet, FURNITURE_CATALOG_URLS_PARAMETER, "catalog.zip");
      final String furnitureResourcesUrlBase = getAppletParameter(this.applet, FURNITURE_RESOURCES_URL_BASE_PARAMETER, null);
      final String texturesCatalogURLs = getAppletParameter(this.applet, TEXTURES_CATALOG_URLS_PARAMETER, "catalog.zip");
      final String texturesResourcesUrlBase = getAppletParameter(this.applet, TEXTURES_RESOURCES_URL_BASE_PARAMETER, null);
      final String readPreferencesURL = getAppletParameter(this.applet, READ_PREFERENCES_URL_PARAMETER, "");   
      final String writePreferencesURL = getAppletParameter(this.applet, WRITE_PREFERENCES_URL_PARAMETER, "");   
      final String userLanguage = getAppletParameter(this.applet, USER_LANGUAGE, null);   
      this.userPreferences = new AppletUserPreferences(
          getURLs(codeBase, furnitureCatalogURLs),
          getURLWithCodeBase(codeBase, furnitureResourcesUrlBase),
          getURLs(codeBase, texturesCatalogURLs),
          getURLWithCodeBase(codeBase, texturesResourcesUrlBase),
          getURLWithCodeBase(codeBase, writePreferencesURL),
          getURLWithCodeBase(codeBase, readPreferencesURL),
          userLanguage);
    }
    return this.userPreferences;
  }

  /**
   * Returns a content manager able to handle files.
   */
  protected ContentManager getContentManager() {
    if (this.contentManager == null) {
      this.contentManager = new AppletContentManager(getHomeRecorder(), getUserPreferences());
    }
    return this.contentManager;
  }
 
  /**
   * Returns a Swing view factory.
   */
  protected ViewFactory getViewFactory() {
    if (this.viewFactory == null) {
     this.viewFactory = new SwingViewFactory();
    }
    return this.viewFactory;
  }

  /**
   * Returns the plugin manager of this application.
   */
  protected PluginManager getPluginManager() {
    if (this.pluginManager == null) {
      URL codeBase = this.applet.getCodeBase();
      String pluginURLs = getAppletParameter(this.applet, PLUGIN_URLS_PARAMETER, "");
      this.pluginManager = new PluginManager(getURLs(codeBase, pluginURLs));
    }
    return this.pluginManager;
  }

  /**
   * Returns applet name.
   */
  @Override
  public String getName() {
    return this.name;
  }
 
  /**
   * Returns information about the version of this applet application.
   */
  @Override
  public String getVersion() {
    String applicationVersion = getUserPreferences().getLocalizedString(
        AppletApplication.class, "applicationVersion");
    String versionInformation = System.getProperty("com.eteks.sweethome3d.deploymentInformation");
    if (versionInformation != null) {
      applicationVersion += " " + versionInformation;
    }
    return applicationVersion;
  }
 
  /**
   * Sets application look and feel.
   */
  private void initLookAndFeel() {
    try {
      // Apply current system look and feel
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      // Change default titled borders under Mac OS X 10.5
      if (OperatingSystem.isMacOSXLeopardOrSuperior()) {
        UIManager.put("TitledBorder.border",
            UIManager.getBorder("TitledBorder.aquaVariant"));
      }
      // Enable applets to update their content while window resizing
      Toolkit.getDefaultToolkit().setDynamicLayout(true);
      SwingTools.updateSwingResourceLanguage();
    } catch (Exception ex) {
      // Too bad keep current look and feel
    }
  }
 
  /**
   * Sets the rendering error listener bound to Java 3D
   * to avoid default System exit in case of error during 3D rendering.
   */
  private void addComponent3DRenderingErrorObserver() {
    if (!"true".equalsIgnoreCase(System.getProperty("com.eteks.sweethome3d.no3D"))) {
      // Instead of adding a RenderingErrorListener directly to VirtualUniverse,
      // we add it through Component3DManager, because offscreen rendering needs to check
      // rendering errors with its own RenderingErrorListener
      Component3DManager.getInstance().setRenderingErrorObserver(
          new Component3DManager.RenderingErrorObserver() {
            public void errorOccured(int errorCode, String errorMessage) {
              System.err.print("Error in Java 3D : " + errorCode + " " + errorMessage);
              EventQueue.invokeLater(new Runnable() {
                  public void run() {
                    show3DError();
                  }
                });
            }
          });
    }
  }

  /**
   * Displays a message to user about a 3D error.
   */
  private void show3DError() {
    String message = getUserPreferences().getLocalizedString(AppletApplication.class, "3DError.message");
    String title = getUserPreferences().getLocalizedString(AppletApplication.class, "3DError.title");
    JOptionPane.showMessageDialog(KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(),
        message, title, JOptionPane.ERROR_MESSAGE);
  }

  /**
   * JNLP <code>ServiceManagerStub</code> implementation for applets
   * run out of Java Web Start. This service manager supports <code>BasicService</code> only.
   */
  private static class StandaloneServiceManager implements ServiceManagerStub {
    private BasicService basicService;

    public StandaloneServiceManager(AppletContext appletContext,
                                    URL codeBase) {
      this.basicService = new AppletBasicService(appletContext, codeBase);
    }

    public Object lookup(final String name) throws UnavailableServiceException {
      if (name.equals("javax.jnlp.BasicService")) {
        return this.basicService;
      } else {
        throw new UnavailableServiceException(name);
      }
    }
   
    public String[] getServiceNames() {
      return new String[]  {"javax.jnlp.BasicService"};
    }
  }   

  /**
   * <code>BasicService</code> that displays a web page in the current browser.
   */
  private static class AppletBasicService implements BasicService {
    private final AppletContext appletContext;
    private final URL    codeBase;

    public AppletBasicService(AppletContext appletContext,
                              URL codeBase) {
      this.appletContext = appletContext;
      this.codeBase = codeBase;
    }

    public boolean showDocument(URL url) {
      this.appletContext.showDocument(url);
      return true;
    }

    public URL getCodeBase() {
      return this.codeBase;
    }

    public boolean isOffline() {
      return false;
    }

    public boolean isWebBrowserSupported() {
      return true;
    }
  }
}
TOP

Related Classes of com.eteks.sweethome3d.applet.AppletApplication$AppletBasicService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.