it.tidalwave.geo.viewer.impl.GeoViewerTopComponent Maven / Gradle / Ivy
/***********************************************************************************************************************
*
* forceTen - open source geography
* Copyright (C) 2007-2012 by Tidalwave s.a.s. (http://www.tidalwave.it)
*
***********************************************************************************************************************
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
***********************************************************************************************************************
*
* WWW: http://forceten.tidalwave.it
* SCM: https://bitbucket.org/tidalwave/forceten-src
*
**********************************************************************************************************************/
package it.tidalwave.geo.viewer.impl;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Provider;
import java.util.List;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.awt.BorderLayout;
import javax.swing.ActionMap;
import javax.swing.text.DefaultEditorKit;
import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
import org.jdesktop.beansbinding.BeanProperty;
import org.jdesktop.beansbinding.BindingGroup;
import org.jdesktop.beansbinding.Bindings;
import org.jdesktop.observablecollections.ObservableList;
import org.jdesktop.observablecollections.ObservableListListener;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.ExplorerUtils;
import org.openide.windows.TopComponent;
import org.openide.windows.WindowManager;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
import it.tidalwave.util.logging.Logger;
import it.tidalwave.swing.PropertyManager;
import it.tidalwave.netbeans.windows.EnhancedTopComponent;
import it.tidalwave.netbeans.nodes.role.RootNodeProvider;
import it.tidalwave.netbeans.print.ComponentPrintCookie;
import it.tidalwave.util.NotFoundException;
import it.tidalwave.geo.viewer.GeoViewerPresentation;
import it.tidalwave.geo.viewer.GeoViewProviderManager;
import it.tidalwave.geo.viewer.role.GeoViewerUI;
import it.tidalwave.geo.viewer.spi.GeoViewProvider;
/***********************************************************************************************************************
*
* @author Fabrizio Giudici
* @version $Id$
*
**********************************************************************************************************************/
public final class GeoViewerTopComponent extends EnhancedTopComponent implements GeoViewerPresentation
{
private static final long serialVersionUID = 2340598234098234654L;
private static final String CLASS = GeoViewerTopComponent.class.getName();
private static final Logger logger = Logger.getLogger(CLASS);
private static final String PREFERRED_ID = GeoViewerPresentation.ID;
private static GeoViewerTopComponent instance;
private final ExplorerManager explorerManager = new ExplorerManager();
private final Lookup lookup;
@Inject
private Provider geoViewProviderManager;
@Inject
private GeoViewerUI geoViewerUI;
@Inject
private GeoRendererPanel geoRendererPanel;
private final ActionMap map = new ActionMap();
private final BindingGroup bindingGroup = new BindingGroup();
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private GeoViewerTopComponent()
{
setName(NbBundle.getMessage(GeoViewerTopComponent.class, "CTL_GeoViewerTopComponent"));
installUIResources();
// FIXME: this should be put in a reusable Role
try
{
map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(explorerManager));
map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(explorerManager));
// The standard paste action gets disabled with multiple nodes selected
map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(explorerManager));
// map.put(DefaultEditorKit.pasteAction, SystemAction.get(MultiPasteAction.class));
map.put("delete", ExplorerUtils.actionDelete(explorerManager, true)); // or false
}
catch (Throwable e) // when used outside NetBeans RCP
{
logger.info("No default actions");
}
lookup = new ProxyLookup(super.getLookup(),
ExplorerUtils.createLookup(explorerManager, map),
Lookups.fixed(new ComponentPrintCookie(this)));
// associateLookup(lookup);
// associateLookup(PrintSupport.createPrintingLookup());
}
/*******************************************************************************************************************
*
*
*
******************************************************************************************************************/
public void clearSceneFacade() // FIXME: drop this
{
logger.fine("clearSceneFacade()");
// getLookup().lookup(JXMapViewerSupport.class).getSceneFacade().clear();
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public Lookup getLookup()
{
return lookup;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public int getPersistenceType()
{
return TopComponent.PERSISTENCE_ALWAYS;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override @Nonnull
public String preferredID()
{
return PREFERRED_ID;
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void writeExternal (final @Nonnull ObjectOutput out)
throws IOException
{
super.writeExternal(out);
// FIXME: move to a specific role
final GeoViewProvider selectedGeoViewProvider = geoViewProviderManager.get().getSelectedGeoViewProvider();
out.writeUTF(selectedGeoViewProvider.getName());
}
/*******************************************************************************************************************
*
* {@inheritDoc}
*
******************************************************************************************************************/
@Override
public void readExternal (final @Nonnull ObjectInput in)
throws IOException, ClassNotFoundException
{
super.readExternal(in);
// FIXME: move to a specific role
try
{
final String mapProviderName = in.readUTF();
for (final GeoViewProvider geoViewProvider : geoViewProviderManager.get().getGeoViewProviders())
{
if (geoViewProvider.getName().equals(mapProviderName))
{
geoViewProviderManager.get().setSelectedGeoViewProvider(geoViewProvider);
break;
}
}
}
catch (IOException e)
{
logger.warning("Handling exception in readExternal(): %s", e);
}
}
/*******************************************************************************************************************
*
* Finishes the creation of the UI and binds some parts together.
*
******************************************************************************************************************/
@PostConstruct
@SuppressWarnings("PMD.UnusedPrivateMethod") @edu.umd.cs.findbugs.annotations.SuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD")
private void initialize()
{
setLayout(new BorderLayout());
add(geoViewerUI, BorderLayout.CENTER);
// FIXME But the root node should be returned from the GeoProvider since it should be different for 2D and 3D
final RootNodeProvider rootNodeProvider = getLookup().lookup(RootNodeProvider.class);
if (rootNodeProvider != null)
{
try
{
explorerManager.setRootContext(rootNodeProvider.getRootNode());
}
catch (NotFoundException e)
{
logger.severe("Can't set root context");
logger.throwing(CLASS, "initialize()", e);
}
}
// FIXME: you should listen for changes and eventually rebind
final GeoViewProviderManager gvpm = geoViewProviderManager.get();
bind(gvpm.getGeoViewProviders(), geoViewerUI.getGeoViewProviders());
bindingGroup.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, gvpm,
BeanProperty.create(GeoViewProviderManager.PROP_SELECTED_GEO_VIEW_PROVIDER),
geoViewerUI,
BeanProperty.create(GeoViewerUI.PROP_SELECTED_GEO_VIEW_PROVIDER)));
bindingGroup.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ, gvpm,
BeanProperty.create(GeoViewProviderManager.PROP_SELECTED_GEO_VIEW_PROVIDER),
geoRendererPanel,
BeanProperty.create(GeoRendererPanel.PROP_SELECTED_GEO_VIEW_PROVIDER)));
bindingGroup.bind();
}
/*******************************************************************************************************************
*
*
******************************************************************************************************************/
private void installUIResources()
{
PropertyManager.configure(this, "GeoViewerTopComponent"); // FIXME: what's this?
}
/*******************************************************************************************************************
*
* Gets default instance. Do not use directly: reserved for *.settings files only, i.e. deserialization routines;
* otherwise you could get a non-deserialized instance. To obtain the singleton instance, use {@link findInstance}.
*
******************************************************************************************************************/
@Nonnull
public static synchronized GeoViewerTopComponent getDefault()
{
if (instance == null)
{
instance = new GeoViewerTopComponent();
}
return instance;
}
/*******************************************************************************************************************
*
* Obtain the MapViewerTopComponent instance. Never call {@link #getDefault} directly!
*
******************************************************************************************************************/
@Nonnull
public static synchronized GeoViewerTopComponent findInstance()
{
TopComponent component = null;
try
{
component = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
}
catch (NoClassDefFoundError e)
{
logger.info("No WindowManager available");
}
if (component == null)
{
logger.warning("Cannot find Mapping component. It will not be located properly in the window system.");
return getDefault();
}
if (component instanceof GeoViewerTopComponent)
{
return (GeoViewerTopComponent)component;
}
logger.warning("There seem to be multiple components with the '%s' ID. That is a potential source of errors " +
"and unexpected behavior.", PREFERRED_ID);
return getDefault();
}
// FIXME: any smarter way to keep two ObservableLists in sync?
private static void bind (final @Nonnull ObservableList source,
final @Nonnull ObservableList target)
{
target.clear();
target.addAll(source);
source.addObservableListListener(new ObservableListListener()
{
@Override
public void listElementsAdded(ObservableList ol, int i, int i1)
{
target.clear();
target.addAll(source);
}
@Override
public void listElementsRemoved(ObservableList ol, int i, List list)
{
target.clear();
target.addAll(source);
}
@Override
public void listElementReplaced(ObservableList ol, int i, Object o)
{
target.clear();
target.addAll(source);
}
@Override
public void listElementPropertyChanged(ObservableList ol, int i)
{
target.clear();
target.addAll(source);
}
});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy