public BackgroundImageWizardController(
     Home home,
     UserPreferences preferences,
     ViewFactory viewFactory,
     ContentManager contentManager,
     UndoableEditSupport undoSupport) {
   super(preferences, viewFactory);
   this.home = home;
   this.preferences = preferences;
   this.viewFactory = viewFactory;
   this.contentManager = contentManager;
   this.undoSupport = undoSupport;
   this.propertyChangeSupport = new PropertyChangeSupport(this);
   setTitle(preferences.getLocalizedString(BackgroundImageWizardController.class, "wizard.title"));
   setResizable(true);
   // Initialize states
   this.imageChoiceStepState = new ImageChoiceStepState();
   this.imageScaleStepState = new ImageScaleStepState();
   this.imageOriginStepState = new ImageOriginStepState();
   setStepState(this.imageChoiceStepState);
 }
  public ViewerHelper(final JApplet applet) {
    // Create default user preferences with no catalog
    final UserPreferences preferences =
        new UserPreferences() {
          @Override
          public void addLanguageLibrary(String languageLibraryName) throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public boolean languageLibraryExists(String languageLibraryName)
              throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public void addFurnitureLibrary(String furnitureLibraryName) throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public boolean furnitureLibraryExists(String furnitureLibraryName)
              throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public boolean texturesLibraryExists(String name) throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public void addTexturesLibrary(String name) throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public void write() throws RecorderException {
            throw new UnsupportedOperationException();
          }

          @Override
          public boolean isNavigationPanelVisible() {
            return "true".equalsIgnoreCase(applet.getParameter(NAVIGATION_PANEL));
          }
        };

    // Create a view factory able to instantiate only a 3D view and a threaded task view
    final ViewFactory viewFactory =
        new ViewFactory() {
          public View createBackgroundImageWizardStepsView(
              BackgroundImage backgroundImage,
              UserPreferences preferences,
              BackgroundImageWizardController backgroundImageWizardController) {
            throw new UnsupportedOperationException();
          }

          public View createFurnitureCatalogView(
              FurnitureCatalog catalog,
              UserPreferences preferences,
              FurnitureCatalogController furnitureCatalogController) {
            throw new UnsupportedOperationException();
          }

          public View createFurnitureView(
              Home home, UserPreferences preferences, FurnitureController furnitureController) {
            throw new UnsupportedOperationException();
          }

          public HelpView createHelpView(
              UserPreferences preferences, HelpController helpController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createHome3DAttributesView(
              UserPreferences preferences, Home3DAttributesController home3DAttributesController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createHomeFurnitureView(
              UserPreferences preferences, HomeFurnitureController homeFurnitureController) {
            throw new UnsupportedOperationException();
          }

          public HomeView createHomeView(
              Home home, UserPreferences preferences, HomeController homeController) {
            throw new UnsupportedOperationException();
          }

          public ImportedFurnitureWizardStepsView createImportedFurnitureWizardStepsView(
              CatalogPieceOfFurniture piece,
              String modelName,
              boolean importHomePiece,
              UserPreferences preferences,
              ImportedFurnitureWizardController importedFurnitureWizardController) {
            throw new UnsupportedOperationException();
          }

          public View createImportedTextureWizardStepsView(
              CatalogTexture texture,
              String textureName,
              UserPreferences preferences,
              ImportedTextureWizardController importedTextureWizardController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createLabelView(
              boolean modification, UserPreferences preferences, LabelController labelController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createPageSetupView(
              UserPreferences preferences, PageSetupController pageSetupController) {
            throw new UnsupportedOperationException();
          }

          public PlanView createPlanView(
              Home home, UserPreferences preferences, PlanController planController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createPrintPreviewView(
              Home home,
              UserPreferences preferences,
              HomeController homeController,
              PrintPreviewController printPreviewController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createRoomView(
              UserPreferences preferences, RoomController roomController) {
            throw new UnsupportedOperationException();
          }

          public TextureChoiceView createTextureChoiceView(
              UserPreferences preferences, TextureChoiceController textureChoiceController) {
            throw new UnsupportedOperationException();
          }

          public ThreadedTaskView createThreadedTaskView(
              String taskMessage, UserPreferences preferences, ThreadedTaskController controller) {
            return new ThreadedTaskPanel(taskMessage, preferences, controller) {
              private boolean taskRunning;

              public void setTaskRunning(boolean taskRunning, View executingView) {
                if (taskRunning && !this.taskRunning) {
                  // Display task panel directly at applet center if it's empty
                  this.taskRunning = taskRunning;
                  JPanel contentPane = new JPanel(new GridBagLayout());
                  contentPane.add(this, new GridBagConstraints());
                  applet.setContentPane(contentPane);
                  applet.getRootPane().revalidate();
                }
              }
            };
          }

          public DialogView createUserPreferencesView(
              UserPreferences preferences, UserPreferencesController userPreferencesController) {
            throw new UnsupportedOperationException();
          }

          public View createView3D(
              final Home home, UserPreferences preferences, final HomeController3D controller) {
            HomeComponent3D homeComponent3D = new HomeComponent3D(home, preferences, controller);
            // Add tab key to input map to change camera
            InputMap inputMap = homeComponent3D.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
            inputMap.put(KeyStroke.getKeyStroke("SPACE"), "changeCamera");
            ActionMap actionMap = homeComponent3D.getActionMap();
            actionMap.put(
                "changeCamera",
                new AbstractAction() {
                  public void actionPerformed(ActionEvent ev) {
                    if (home.getCamera() == home.getTopCamera()) {
                      controller.viewFromObserver();
                    } else {
                      controller.viewFromTop();
                    }
                  }
                });
            return homeComponent3D;
          }

          public DialogView createWallView(
              UserPreferences preferences, WallController wallController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createWizardView(
              UserPreferences preferences, WizardController wizardController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createPhotoView(
              Home home, UserPreferences preferences, PhotoController photoController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createVideoView(
              Home home, UserPreferences preferences, VideoController videoController) {
            throw new UnsupportedOperationException();
          }

          public DialogView createCompassView(
              UserPreferences preferences, CompassController compassController) {
            throw new UnsupportedOperationException();
          }
        };

    // 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")));

    initLookAndFeel();

    addComponent3DRenderingErrorObserver(applet.getRootPane(), preferences);

    // Retrieve displayed home
    String homeUrlParameter = applet.getParameter(HOME_URL_PARAMETER);
    if (homeUrlParameter == null) {
      homeUrlParameter = "default.sh3d";
    }
    // Retrieve ignoreCache parameter value
    String ignoreCacheParameter = applet.getParameter(IGNORE_CACHE_PARAMETER);
    final boolean ignoreCache =
        ignoreCacheParameter != null && "true".equalsIgnoreCase(ignoreCacheParameter);
    try {
      final URL homeUrl = new URL(applet.getDocumentBase(), homeUrlParameter);
      // Read home in a threaded task
      Callable<Void> openTask =
          new Callable<Void>() {
            public Void call() throws RecorderException {
              // Read home with application recorder
              Home openedHome = readHome(homeUrl, ignoreCache);
              displayHome(applet.getRootPane(), openedHome, preferences, viewFactory);
              return null;
            }
          };
      ThreadedTaskController.ExceptionHandler exceptionHandler =
          new ThreadedTaskController.ExceptionHandler() {
            public void handleException(Exception ex) {
              if (!(ex instanceof InterruptedRecorderException)) {
                if (ex instanceof RecorderException) {
                  showError(
                      applet.getRootPane(),
                      preferences.getLocalizedString(ViewerHelper.class, "openError", homeUrl));
                } else {
                  ex.printStackTrace();
                }
              }
            }
          };
      new ThreadedTaskController(
              openTask,
              preferences.getLocalizedString(ViewerHelper.class, "openMessage"),
              exceptionHandler,
              null,
              viewFactory)
          .executeTask(null);
    } catch (MalformedURLException ex) {
      showError(
          applet.getRootPane(),
          preferences.getLocalizedString(ViewerHelper.class, "openError", homeUrlParameter));
      return;
    }
  }