Java tutorial
/******************************************************************************* * Copyright (c) 2010 Stefan A. Tzeggai. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Stefan A. Tzeggai - initial API and implementation ******************************************************************************/ package org.geopublishing.atlasViewer.swing; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.Point2D; import java.util.Map; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.geopublishing.atlasViewer.AtlasConfig; import org.geotools.geometry.DirectPosition2D; import org.geotools.map.MapContext; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Point; import de.schmitzm.geotools.MapContextManagerInterface; import de.schmitzm.geotools.feature.FeatureUtil; import de.schmitzm.geotools.gui.XMapPane; import de.schmitzm.geotools.map.event.FeatureSelectedEvent; import de.schmitzm.geotools.map.event.GridCoverageValueSelectedEvent; import de.schmitzm.geotools.map.event.ObjectSelectionEvent; import de.schmitzm.swing.SwingUtil; /** * This Dialog wraps a {@link ClickInfoPanel} that shows information when the * mouse clicked inside the {@link Map} and has hit a visible features. * * @author <a href="mailto:skpublic@wikisquare.de">Stefan Alfons Tzeggai</a> * */ public class ClickInfoDialog extends JDialog { final ClickInfoPanel clickInfoPanel; /** * Is <code>null</code>, wenn wir im AS sind. */ private final AtlasConfig atlasConfig; Boolean userMovedTheWindow = false; protected int lastHeight; protected int lastWidth; protected boolean rightGlue = false; protected boolean bottomGlue = false; private static final Logger LOGGER = Logger.getLogger(ClickInfoDialog.class); /** * This Dialog wraps a {@link ClickInfoPanel} that shows information when * the mouse clicked inside the {@link Map} and has hit a visible features. * * @param parentGUI * A {@link Component} that links to the parent GUI * * @param modal * * @param atlasConfig * may be <code>null</code> if not in atlas context * * @param layerManager * A {@link MapContextManagerInterface} to communicate with the * geotools {@link MapContext} */ public ClickInfoDialog(final Component parentGUI, final boolean modal, final MapContextManagerInterface layerManager, AtlasConfig atlasConfig) { super(SwingUtil.getParentWindow(parentGUI)); this.atlasConfig = atlasConfig; if (layerManager == null) { throw new IllegalArgumentException("MapContextManagerInterface may not be null!"); } setModal(modal); clickInfoPanel = new ClickInfoPanel(layerManager, ClickInfoDialog.this, this.atlasConfig); // **************************************************************************** // Ensure, that the VideoPlayer is never left unattended. // **************************************************************************** addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { // clickInfoPanel.disposeVideoPlayer(); super.windowClosing(e); } }); addComponentListener(new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { userMovedTheWindow = true; // LOGGER.debug("Userinteraction TRUE!"); checkGlue(e); } @Override public void componentResized(ComponentEvent e) { final int newWidth = e.getComponent().getWidth(); final int newHeight = e.getComponent().getHeight(); /* * If rightGlue and the new width is less, move the window * right! */ if (rightGlue && newWidth < lastWidth) { int dif = (lastWidth - newWidth); setLocation(getLocation().x + dif, getLocation().y); } /* * If leftGlue all is automatically OK */ if (bottomGlue && newHeight < lastHeight) { int dif = (lastHeight - newHeight); setLocation(getLocation().x, getLocation().y + dif); } lastHeight = newHeight; lastWidth = newWidth; checkGlue(e); } private void checkGlue(final ComponentEvent e) { if ((e.getComponent().getWidth() + getLocation().x) == getToolkit().getScreenSize().width) { /** * The Window is now glued to the right. */ rightGlue = true; } else rightGlue = false; /** * Bottom GLUE is not yet supported because we can't properly * determine the bottom insets for windows + ubuntu */ // // int bottom = getToolkit().getScreenInsets( // ClickInfoDialog.this.getGraphicsConfiguration()).bottom; // // if ((e.getComponent().getHeight() + getLocation().y) == // (getToolkit() // .getScreenSize().height - bottom)) { // /** // * The Window is now glued to the bottom // */ // bottomGlue = true; // } else // bottomGlue = false; // // LOGGER.debug(bottom + "sd" // + getToolkit().getScreenSize().height + " sds " // + (e.getComponent().getHeight() + getLocation().y)); } }); final JPanel cp = new JPanel(new BorderLayout()); /** * Adding the Panel with a JScrollPane */ cp.add(new JScrollPane(clickInfoPanel), BorderLayout.CENTER); setContentPane(cp); setDefaultCloseOperation(HIDE_ON_CLOSE); } /** * Update with info-dialog with the new {@link ObjectSelectionEvent} */ public void setSelectionEvent(final ObjectSelectionEvent<?> objectSelectionEvent) { clickInfoPanel.setSelectionEvent(objectSelectionEvent); XMapPane source = objectSelectionEvent.getSource(); // Set the title of the dialog to the translated title the layer try { String title = objectSelectionEvent.getSourceLayer().getTitle(); if (atlasConfig != null) { setTitle(atlasConfig.getDataPool().get(title).getTitle().toString()); } else { title = StringUtils.right(title, 25); setTitle(title); } } catch (Exception e) { LOGGER.error(e.getMessage(), e); } XMapPane mapPane = objectSelectionEvent.getSource(); // If it is a feature, let it blink for a moment if (source instanceof XMapPane && objectSelectionEvent instanceof FeatureSelectedEvent) { mapPane.blink(((FeatureSelectedEvent) objectSelectionEvent).getSelectionResult()); } else { // Create a fake Feature and let it blink a moment final GridCoverageValueSelectedEvent gridSelection = (GridCoverageValueSelectedEvent) objectSelectionEvent; // TODO Help Martin, warum kann ich kein feake Feature mit correctem // CRS erstellen? Point2D selectionPoint = gridSelection.getSelectionPoint(); CoordinateReferenceSystem crs = mapPane.getMapContext().getCoordinateReferenceSystem(); SimpleFeatureType fakeFeatureType = FeatureUtil.createFeatureType(Point.class, crs); SimpleFeature fakeFeature = FeatureUtil.createFeatureInstance(fakeFeatureType, true, "fake raster selection", new DirectPosition2D(crs, selectionPoint.getX(), selectionPoint.getY())); System.out.println("crs = " + fakeFeature.getFeatureType().getCoordinateReferenceSystem()); mapPane.blink(fakeFeature); } } /** * Since the registerKeyboardAction() method is part of the JComponent class * definition, you must define the Escape keystroke and register the * keyboard action with a JComponent, not with a JDialog. The JRootPane for * the JDialog serves as an excellent choice to associate the registration, * as this will always be visible. If you override the protected * createRootPane() method of JDialog, you can return your custom JRootPane * with the keystroke enabled: */ @Override protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane rootPane = new JRootPane(); rootPane.registerKeyboardAction(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(false); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return rootPane; } }