/* * ImageFrame.java * * Created on June 1, 2008, 4:28 PM */ package ch.ethz.ika.gui; import ch.ethz.ika.terrainviewer.ShearPanel; import ch.ethz.karto.map3d.Map3DGLCapabilities; import ch.ethz.karto.map3d.Map3DTexture; import ch.ethz.karto.map3d.gui.Map3DOptionsPanel; import ch.ethz.karto.map3d.Map3DViewer; import ch.ethz.karto.map3d.Map3DViewer.Camera; import ch.ethz.karto.map3d.Map3DTexture1DMapper; import ch.ethz.karto.swa.atlas.SystemInfoGPU; import com.bric.swing.ColorPicker; import com.bric.swing.MultiThumbSlider; import com.fizzysoft.sdu.RecentDocumentsManager; import ika.geo.GeoGrid; import ika.geo.GeoImage; import ika.geo.GeoObject; import ika.geo.grid.GaussianPyramid; import ika.geo.grid.GridGaussLowPassOperator; import ika.geo.grid.GridScaleOperator; import ika.geoimport.EsriASCIIGridReader; import ika.geoimport.GeoImporter; import ika.geoimport.ImageImporter; import ika.geoimport.SynchroneDataReceiver; import ika.gui.SwingWorkerWithProgressIndicator; import ika.gui.TransparentMacPanel; import ika.utils.CatmullRomSpline; import ika.utils.ErrorDialog; import ika.utils.FileUtils; import ika.utils.ImageUtils; import ika.utils.MathUtils; import ika.utils.PropertiesLoader; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import net.roydesign.mac.MRJAdapter; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.StringTokenizer; import java.util.prefs.Preferences; import javax.imageio.ImageIO; import javax.media.opengl.GLProfile; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import sun.reflect.generics.reflectiveObjects.NotImplementedException; /** * Main window. * @author Bernhard Jenny, Institute of Cartography, ETH Zurich. */ public class MainWindow extends javax.swing.JFrame implements PropertyChangeListener, ComponentListener { /** * smallest side length of the grid used for previewing */ private static final int MIN_GRID_CELLS = 64 * 64; private static final int MAX_GRID_SIDE = 6000; private static final int DEFAULT_GRID_SIDE = 1024; /** * maximum side length of a texture image */ private static final int MAX_TEXTURE_SIDE = 2048; private static final boolean VERBOSE = false; /** * OpenGL handler */ private Map3DViewer map3DViewer; /** * information string for the full resolution grid */ private String originalInfoText; /** * A pyramid of grid levels. */ private GaussianPyramid gridPyramid; /** * dimension of the window when minimized. */ private java.awt.Dimension packedSize = null; private boolean updatingGUI = false; private RecentDocumentsManager rdm; /** * multiplication sign surrounded by small spaces */ private static final String MULT_SIGN = "\u2006\u00D7\u2006"; private static final String APPNAME; static { java.util.Properties props = PropertiesLoader.loadProperties("ika.app.Application"); APPNAME = props.getProperty("ApplicationName"); } public MainWindow() throws IOException { initRecentDocumentsMenu(this); initComponents(); initMenus(); // setup 3D map this.map3DViewer = new Map3DViewer(Map3DViewer.GLComponentType.GL_AWT, GLProfile.getDefault()); this.map3DViewer.setDefaultCamera(75, 0, Map3DViewer.MAX_DISTANCE, 50, 0, 0); this.map3DViewer.resetToDefaultCamera(); // setup GUI controls of 3D map /*this.map3DOptionsPanel.setCameraVisible(Map3DViewer.Camera.orthogonal, true); this.map3DOptionsPanel.setCameraVisible(Map3DViewer.Camera.parallelOblique, true); this.map3DOptionsPanel.setCameraVisible(Map3DViewer.Camera.planOblique, true); this.map3DOptionsPanel.setCameraVisible(Map3DViewer.Camera.cylindrical, true); */ //this.map3DOptionsPanel.setAntialiasingPanelVisible(false); // add 3D map to GUI Component map3DComponent = map3DViewer.getComponent(); map3DComponent.setPreferredSize(new Dimension(400, 400)); this.container3D.add(map3DComponent, BorderLayout.CENTER); map3DComponent.addPropertyChangeListener(this); this.map3DOptionsPanel.setMap3DViewer(this.map3DViewer); this.map3DOptionsPanel.addPanel("Level of Detail", lodPanel); this.map3DOptionsPanel.setCameraVisible(Map3DViewer.Camera.cylindrical, true); // pack the window (= bring it to its smallest possible size) // and store this minimum size pack(); packedSize = getSize(); // register this as a ComponentListener to get resize events. // the resize-event-handler makes sure the window is not gettting too small. this.addComponentListener(this); } private void initRecentDocumentsMenu(final Component parent) { rdm = new RecentDocumentsManager() { private Preferences getPreferences() { return Preferences.userNodeForPackage(MainWindow.class); } @Override protected byte[] readRecentDocs() { return getPreferences().getByteArray("RecentDocuments"+APPNAME, null); } @Override protected void writeRecentDocs(byte[] data) { getPreferences().putByteArray("RecentDocuments"+APPNAME, data); } @Override protected void openFile(File file, ActionEvent event) { try { if (file != null) { openDEM(file.getCanonicalPath()); } } catch (IOException ex) { String msg = "Could not open the terrain model."; String title = APPNAME + " Error"; ErrorDialog.showErrorDialog(msg, title, ex, parent); } } }; } private GeoGrid getFullResolutionGrid() { if (gridPyramid == null) { return null; } return gridPyramid.getFullResolutionLevel(); } /** * Returns the grid that should be displayed in the 3D view * @return the displayGrid */ private GeoGrid getDisplayGrid() { if (gridPyramid == null) { return null; } return gridPyramid.getLevel(this.getDisplayLevel()); } /** * Returns the pyramid level that should be displayed as selected in the GUI. * @return */ private int getDisplayLevel() { int buttonCount = lodButtonPanel.getComponentCount(); for (int i = 0; i < buttonCount; i++) { JRadioButton b = (JRadioButton)lodButtonPanel.getComponent(i); if (b.isSelected()) { return gridPyramid.getLevelsCount() - i - 1; } } return 0; } /** * Returns the pyramid level that is initially displayed. * @return */ private int getDefaultDisplayLevel() { int lastLevel = gridPyramid.getLevelsCount() - 1; for (int i = lastLevel; i >= 0; i--) { GeoGrid grid = gridPyramid.getLevel(i); int cols = grid.getCols(); int rows = grid.getRows(); if (cols * rows >= DEFAULT_GRID_SIDE * DEFAULT_GRID_SIDE) { return i; } } return 0; } /** * Setup the panel for selecting the level of details. */ private void initLevelOfDetailGUI() { // find firstLevel, i.e. the ID of the largest pyramid level that can be // reasonable displayed int firstLevel, lastLevel = gridPyramid.getLevelsCount() - 1; for (firstLevel = 0; firstLevel <= lastLevel; firstLevel++) { GeoGrid grid = gridPyramid.getLevel(firstLevel); int cols = grid.getCols(); int rows = grid.getRows(); if (cols * rows <= MAX_GRID_SIDE * MAX_GRID_SIDE) { break; } } // find the default pyramid level to display int displayLevel = getDefaultDisplayLevel(); // add radio buttons to GUI lodButtonPanel.removeAll(); DecimalFormat df = new DecimalFormat("#,##0"); for (int i = lastLevel; i >= firstLevel; i--) { JRadioButton b = new JRadioButton(); // generate label for radio button GeoGrid grid = gridPyramid.getLevel(i); StringBuilder sb = new StringBuilder(); sb.append(df.format(grid.getCols())); sb.append(MULT_SIGN); sb.append(df.format(grid.getRows())); // generate tooltip for radio button String tooltip = "Preview with " + sb.toString() + " pixels."; if (lastLevel - firstLevel == 0) { tooltip += " Disabled because the model is small."; } b.setToolTipText(tooltip); // finish label if (i == 0) { sb.append(" (full resolution)"); } else if (i == lastLevel) { sb.append(" (fastest)"); } b.setText(sb.toString()); // add event listener b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (((JRadioButton)e.getSource()).isSelected()) { modelChanged(); } } }); lodButtonGroup.add(b); lodButtonPanel.add(b); // select the button of the currend display level (after adding it // to the button group) b.setSelected(displayLevel == i); // disable radio button if there is only one button b.setEnabled(lastLevel - firstLevel >= 1); } if (firstLevel != 0) { StringBuilder sb = new StringBuilder(); sb.append("Full size: "); GeoGrid bigGrid = getFullResolutionGrid(); sb.append(df.format(bigGrid.getCols())); sb.append(MULT_SIGN); sb.append(df.format(bigGrid.getRows())); JLabel label = new JLabel(sb.toString()); label.setFont(label.getFont().deriveFont(11f)); lodButtonPanel.add(label); } lodButtonPanel.validate(); } private void openDEM(final String filePath) { if (!EsriASCIIGridReader.canRead(filePath)) { String msg = "The selected file cannot be read."; String title = "Error"; ErrorDialog.showErrorDialog(msg, title, null, this); return; } // release previous grid to free memory gridPyramid = null; SwingWorkerWithProgressIndicator worker; worker = new SwingWorkerWithProgressIndicator<GaussianPyramid>( this, APPNAME + " Data Import", "", true) { @Override public void done() { try { updatingGUI = true; gridPyramid = get(); originalInfoText = getFullResolutionGrid().toStringWithStatistics("<br>"); // set title of window String name = getFullResolutionGrid().getName(); if (name != null && name.trim().length() > 0) { setTitle(name.trim()); } initLevelOfDetailGUI(); rdm.addDocument(new File(filePath), null); updatingGUI = false; modelChanged(); } catch (Exception ex) { String exmsg = ex.getMessage(); if (exmsg != null && exmsg.contains("user canceled")) { return; } ex.printStackTrace(); String msg = "An error occured"; String title = APPNAME + " Error"; ika.utils.ErrorDialog.showErrorDialog(msg, title, ex, MainWindow.this); return; } finally { updatingGUI = false; this.completeProgress(); } } @Override protected GaussianPyramid doInBackground() throws Exception { this.start(); // read sourceGrid from file GeoGrid newGrid = ika.geoimport.EsriASCIIGridReader.read(filePath, this); if (this.isAborted()) { throw new IllegalStateException("user canceled"); } this.setIndeterminate(true); this.setMessage("Downsampling terrain model for display"); return new GaussianPyramid(newGrid, 9999, MIN_GRID_CELLS); } }; worker.setMaxTimeWithoutDialog(1); worker.setMessage("Reading terrain model \"" + FileUtils.getFileName(filePath) + "\""); worker.execute(); } /** * Load and init GUI with DEM */ public void openDEM() { String inputGridPath = FileUtils.askFile(null, "Select an ESRI ASCII Grid", true); if (inputGridPath == null) { return; // user canceled } openDEM(inputGridPath); } private void openTexture(final String filePath) { try { java.net.URL url = ika.utils.URLUtils.filePathToURL(filePath); Dimension dim = ImageImporter.getDimensions(url); // test for non power of two support if (!Map3DGLCapabilities.hasNonPowerOfTwoTextures() && (!MathUtils.isPower2(dim.width) || !MathUtils.isPower2(dim.height))) { String msg = "Your graphics card only supports texture images with\n" + "power of two dimensions (e.g. 1024 x 1024 pixels).\n" + "The selected image has " + dim.width + " x " + dim.height + " pixels\n" + "and therefore cannot be used."; String title = ""; JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE, null); return; } // make sure the image is not too large int maxSize = Map3DTexture.getMaxTextureSize(); if (dim.width > maxSize || dim.height > maxSize) { String msg = "<html>The selected texture image is too large " + "and cannot be displayed. <br>The maximum texture size is " + maxSize + " x " + maxSize + " pixels.</html>"; String title = "Large Texture Image"; JOptionPane.showMessageDialog(this, msg, title, JOptionPane.ERROR_MESSAGE, null); return; } } catch (Exception exc) { String msg = "The texture image could not be opened."; String title = APPNAME + " Error"; ErrorDialog.showErrorDialog(msg, title, exc, this); exc.printStackTrace(); return; } final JFrame frame = this; SwingWorkerWithProgressIndicator worker; worker = new SwingWorkerWithProgressIndicator<BufferedImage>( this, APPNAME + " Texture Import", "", true) { @Override public void done() { try { try { BufferedImage t = get(); // tests for exceptions map3DViewer.setTextureImage(t); } catch (Exception ex) { String exmsg = ex.getMessage(); if (exmsg != null && exmsg.contains("user canceled")) { return; } String msg = "The texture image could not be opened."; String title = APPNAME + " Error"; ika.utils.ErrorDialog.showErrorDialog(msg, title, ex, frame); return; } } finally { modelChanged(); this.completeProgress(); } } @Override protected BufferedImage doInBackground() throws Exception { this.setProgress(0); ImageImporter importer = new ImageImporter(); importer.setProgressIndicator(this); importer.setOptimizeForDisplay(false); java.net.URL url = ika.utils.URLUtils.filePathToURL(filePath); SynchroneDataReceiver dataReceiver = new SynchroneDataReceiver(); dataReceiver.setShowMessageOnError(false); importer.read(url, dataReceiver, GeoImporter.SAME_THREAD); // test whether the image has been successfully read if (dataReceiver.hasReceivedError()) { throw new IOException("Could not read image file at " + filePath); } // retrieve the image GeoImage geoImage = (GeoImage) dataReceiver.getImportedData(); if (geoImage == null) { return null; // user canceled } BufferedImage t = geoImage.getBufferedImage(); if (this.isAborted()) { throw new IllegalStateException("user canceled"); } this.setIndeterminate(true); while (t.getWidth() * t.getHeight() > MAX_TEXTURE_SIDE * MAX_TEXTURE_SIDE) { int w = t.getWidth() / 2; int h = t.getHeight() / 2; Object hint = RenderingHints.VALUE_INTERPOLATION_BICUBIC; int imageType = BufferedImage.TYPE_INT_ARGB; t = ImageUtils.getFasterScaledInstance(t, w, h, hint, imageType, false); if (this.isAborted()) { throw new IllegalStateException("user canceled"); } } return t; } }; worker.setMaxTimeWithoutDialog(1); worker.setMessage("Reading Texture \"" + FileUtils.getFileName(filePath) + "\""); worker.execute(); } /** * Mac OS X and Windows specific initialization of the menus */ private void initMenus() { if (ika.utils.Sys.isMacOSX()) { // remove exit menu item on Mac OS X this.fileMenu.remove(this.exitMenuSeparator); this.fileMenu.remove(this.exitMenuItem); this.fileMenu.validate(); // remove window info menu item on Mac OS X this.menuBar.remove(this.winHelpMenu); /* // remove preferences menu item on Mac OS X this.editMenu.remove(this.preferencesSeparator); this.editMenu.remove(this.preferencesMenuItem); this.editMenu.validate(); */ // setup about command in apple menu final JFrame owner = this; MRJAdapter.addAboutListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ika.gui.ProgramInfoPanel.showApplicationInfo(owner); } }); // setup quit command in apple menu MRJAdapter.addQuitApplicationListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { askToCloseWindowAndExit(); } }); } else if (ika.utils.Sys.isWindows()) { this.menuBar.remove(macHelpMenu); } this.menuBar.validate(); } private void noTerrainErrorMessage(JFrame frame) { String msg = "<html>There is no terrain model loaded.<br>" + "Please first open one."; String title = APPNAME + " Error"; JOptionPane.showMessageDialog(frame, msg, title, JOptionPane.INFORMATION_MESSAGE); } /** * Displays a dialog with information about the original sourceGrid and the * current bending. */ public void showGridInfo() { try { if (originalInfoText == null || getDisplayGrid() == null) { noTerrainErrorMessage(this); return; } StringBuilder sb = new StringBuilder(); sb.append("<html> <b>"); sb.append("Terrain Model"); sb.append("</b><br><br>"); sb.append(this.originalInfoText); String title = "Terrain Model Info"; JOptionPane.showMessageDialog(this, sb.toString(), title, JOptionPane.INFORMATION_MESSAGE); } catch (Exception exc) { String msg = "An error occured."; String title = APPNAME + " Error"; ErrorDialog.showErrorDialog(msg, title, exc, this); } } /** * Returns whether the grid seems to be in geographical coordinates, i.e. * cell size is in degrees and not in meters. * @return */ private boolean isGeographicCoordinateSystem() { GeoGrid grid = this.getFullResolutionGrid(); return grid == null ? false : grid.getCellSize() < 0.1; } /** * Returns a cell size. Computes a projected cell size if the grid is not * projected. * @param resampledGrid * @return */ private double getProjectedCellSize(GeoGrid resampledGrid) { double downsampledCellSize = resampledGrid.getCellSize(); // the following test of the cell size must be done with the original // sourceGrid. Very large geographic grids that have been resampled to a small // size for display might end up with relatively large cell sizes. if (isGeographicCoordinateSystem()) { double lat = (getFullResolutionGrid().getNorth() + getFullResolutionGrid().getSouth()) / 2; lat = Math.toRadians(lat); double R = 6371000; downsampledCellSize = R * Math.toRadians(downsampledCellSize) * Math.cos(lat); } return downsampledCellSize; } /** * Converts to model to a string that can be written to a file for storing. * @return */ @Override public String toString() { DecimalFormat formatter = new DecimalFormat("##0.####"); DecimalFormatSymbols dfs = formatter.getDecimalFormatSymbols(); dfs.setDecimalSeparator('.'); formatter.setDecimalFormatSymbols(dfs); String lineSep = System.getProperty("line.separator"); StringBuilder sb = new StringBuilder(); sb.append("-"); sb.append(lineSep); // FIXME add the model here return sb.toString(); } /** * Restores the settings from a string that has been generated by toString * @param string * @throws java.io.IOException */ public void fromString(String string) throws IOException { try { updatingGUI = true; // make sure we have the right file format if (!string.startsWith("-")) { throw new IOException("Not a supported format"); } StringTokenizer tokenizer = new StringTokenizer(string, "\n\r"); // overread - tokenizer.nextToken(); // FIXME read the model here } finally { updatingGUI = false; } } /** * Called whenever the model changes. */ protected void modelChanged() { try { if (getDisplayGrid() == null || updatingGUI) { return; } getRootPane().putClientProperty("Window.documentModified", Boolean.TRUE); long modelStartTime = System.currentTimeMillis(); // FIXME change grid according to model GeoGrid grid = getDisplayGrid(); long modelEndTime = System.currentTimeMillis(); long openGLStartTime = System.currentTimeMillis(); if (this.map3DViewer != null) { double cellSize = getProjectedCellSize(grid); Map3DTexture1DMapper mapper = new Map3DTexture1DMapper(); map3DViewer.setModel(grid.getGrid(), (float) cellSize, mapper); } if (VERBOSE) { long endTime = System.currentTimeMillis(); if (grid != null) { System.out.println("Model Changed (" + grid.getCols() + " x " + grid.getRows() + ")"); } System.out.println("Bending: " + (modelEndTime - modelStartTime) + " ms"); System.out.println("OpenGL: " + (endTime - openGLStartTime) + " ms"); System.out.println("Total: " + (endTime - modelStartTime) + " ms"); System.out.println(); } } catch (Exception exc) { String msg = "An error occured."; String title = APPNAME + " Error"; ErrorDialog.showErrorDialog(msg, title, exc, this); } } /** * Displays a dialog that asks the user whether the application should * be closed and does so if the user confirms. */ private void askToCloseWindowAndExit() { if (this.getFullResolutionGrid() == null) { System.exit(0); } Map3DOptionsPanel.hide3DOptions(); int res = JOptionPane.showConfirmDialog(this, "<html>This will quit " + APPNAME + ". <br>" + "Unsaved settings will be lost.</html>", "Close " + APPNAME, JOptionPane.OK_CANCEL_OPTION); if (res == JOptionPane.OK_OPTION) { this.dispose(); System.exit(0); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; lodPanel = new TransparentMacPanel(); lodPanel_ = new TransparentMacPanel(); jLabel6 = new javax.swing.JLabel(); lodInfoTextArea = new javax.swing.JTextArea(); lodButtonPanel = new TransparentMacPanel(); lodButtonGroup = new javax.swing.ButtonGroup(); scaleTerrainPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel8 = new javax.swing.JLabel(); scaleTerrainFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel9 = new javax.swing.JLabel(); cameraPositionPanel = new javax.swing.JPanel(); javax.swing.JLabel jLabel10 = new javax.swing.JLabel(); cameraXFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel11 = new javax.swing.JLabel(); javax.swing.JLabel jLabel12 = new javax.swing.JLabel(); cameraYFormattedTextField = new javax.swing.JFormattedTextField(); javax.swing.JLabel jLabel13 = new javax.swing.JLabel(); eastLabel = new javax.swing.JLabel(); jLabel15 = new javax.swing.JLabel(); jLabel16 = new javax.swing.JLabel(); southLabel = new javax.swing.JLabel(); jLabel18 = new javax.swing.JLabel(); northLabel = new javax.swing.JLabel(); jLabel20 = new javax.swing.JLabel(); westLabel = new javax.swing.JLabel(); hypsoPanel = new javax.swing.JPanel(); hypsoSlider = new com.bric.swing.GradientSlider(); { hypsoSlider.putClientProperty("MultiThumbSlider.indicateSelectedThumb", "true"); hypsoSlider.putClientProperty("MultiThumbSlider.indicateComponent", "false"); hypsoSlider.putClientProperty("GradientSlider.useBevel", "true"); hypsoSlider.putClientProperty("GradientSlider.colorPickerIncludesOpacity","false"); //hypsoSlider.setOrientation(GradientSlider.VERTICAL); //hypsoSlider.setPaintTicks(false); initHypsoSlider(); hypsoSlider.setEnabled(false); } hypsoCheckBox = new javax.swing.JCheckBox(); javax.swing.JLabel hypsoLabel = new javax.swing.JLabel(); hypsoDefaultButton = new javax.swing.JButton(); hypsoDefaultButton.putClientProperty("JButton.buttonType", "roundRect"); container3D = new javax.swing.JPanel(); eastPanel = new javax.swing.JPanel(); jPanel1 = new javax.swing.JPanel(); map3DOptionsPanel = new ch.ethz.karto.map3d.gui.Map3DOptionsPanel(); menuBar = new javax.swing.JMenuBar(); fileMenu = new javax.swing.JMenu(); openDEMMenuItem = new javax.swing.JMenuItem(); openRecentMenu = rdm.createOpenRecentMenu(); saveDEMMenuItem = new javax.swing.JMenuItem(); jSeparator5 = new javax.swing.JSeparator(); openTextureMenuItem = new javax.swing.JMenuItem(); clearTextureMenuItem = new javax.swing.JMenuItem(); jSeparator1 = new javax.swing.JSeparator(); saveSettingsMenuItem = new javax.swing.JMenuItem(); openSettingsMenuItem = new javax.swing.JMenuItem(); jSeparator2 = new javax.swing.JSeparator(); export3DViewMenuItem = new javax.swing.JMenuItem(); exitMenuSeparator = new javax.swing.JSeparator(); exitMenuItem = new javax.swing.JMenuItem(); editMenu = new javax.swing.JMenu(); cutMenuItem = new javax.swing.JMenuItem(); copyMenuItem = new javax.swing.JMenuItem(); pasteMenuItem = new javax.swing.JMenuItem(); deleteMenuItem = new javax.swing.JMenuItem(); jSeparator3 = new javax.swing.JSeparator(); gridInfoMenuItem = new javax.swing.JMenuItem(); jSeparator7 = new javax.swing.JSeparator(); scaleTerrainMenuItem = new javax.swing.JMenuItem(); jSeparator8 = new javax.swing.JSeparator(); cameraPositionMenuItem = new javax.swing.JMenuItem(); extrasMenu = new javax.swing.JMenu(); highResMenuItem = new javax.swing.JCheckBoxMenuItem(); bindLightDirectionMenuItem = new javax.swing.JCheckBoxMenuItem(); backgroundColorMenuItem = new javax.swing.JMenuItem(); jSeparator9 = new javax.swing.JPopupMenu.Separator(); animationMenuItem = new javax.swing.JMenuItem(); macHelpMenu = new javax.swing.JMenu(); systemInfoMenuItem = new javax.swing.JMenuItem(); winHelpMenu = new javax.swing.JMenu(); infoMenuItem = new javax.swing.JMenuItem(); winSystemInfoMenuItem = new javax.swing.JMenuItem(); lodPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 0, 12)); lodPanel_.setLayout(new java.awt.GridBagLayout()); jLabel6.setText("Level of Detail for Preview"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 0, 10, 0); lodPanel_.add(jLabel6, gridBagConstraints); lodInfoTextArea.setColumns(20); lodInfoTextArea.setEditable(false); lodInfoTextArea.setFont(new java.awt.Font("Lucida Grande", 0, 11)); // NOI18N lodInfoTextArea.setLineWrap(true); lodInfoTextArea.setRows(2); lodInfoTextArea.setText("For export the full resolution is used."); lodInfoTextArea.setWrapStyleWord(true); lodInfoTextArea.setOpaque(false); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.insets = new java.awt.Insets(20, 0, 0, 0); lodPanel_.add(lodInfoTextArea, gridBagConstraints); lodButtonPanel.setLayout(new javax.swing.BoxLayout(lodButtonPanel, javax.swing.BoxLayout.Y_AXIS)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 20, 0, 0); lodPanel_.add(lodButtonPanel, gridBagConstraints); lodPanel.add(lodPanel_); scaleTerrainPanel.setLayout(new java.awt.GridBagLayout()); jLabel8.setText("Scale Factor:"); scaleTerrainPanel.add(jLabel8, new java.awt.GridBagConstraints()); scaleTerrainFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); scaleTerrainFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); scaleTerrainFormattedTextField.setValue(new Float(1)); scaleTerrainPanel.add(scaleTerrainFormattedTextField, new java.awt.GridBagConstraints()); jLabel9.setFont(jLabel9.getFont().deriveFont(jLabel9.getFont().getSize()-2f)); jLabel9.setText("All values in the terrain grid are scaled by this factor."); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0); scaleTerrainPanel.add(jLabel9, gridBagConstraints); cameraPositionPanel.setLayout(new java.awt.GridBagLayout()); jLabel10.setText("Horizontal"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; cameraPositionPanel.add(jLabel10, gridBagConstraints); cameraXFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); cameraXFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); cameraXFormattedTextField.setValue(new Float(1)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; cameraPositionPanel.add(cameraXFormattedTextField, gridBagConstraints); jLabel11.setFont(jLabel11.getFont().deriveFont(jLabel11.getFont().getSize()-2f)); jLabel11.setText("<html>Position the cylindrical camera. Coordinates are in meters.</html>"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.gridwidth = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(10, 0, 10, 0); cameraPositionPanel.add(jLabel11, gridBagConstraints); jLabel12.setText("Vertical"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; cameraPositionPanel.add(jLabel12, gridBagConstraints); cameraYFormattedTextField.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter())); cameraYFormattedTextField.setPreferredSize(new java.awt.Dimension(200, 28)); cameraYFormattedTextField.setValue(new Float(1)); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 1; gridBagConstraints.gridwidth = 2; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; cameraPositionPanel.add(cameraYFormattedTextField, gridBagConstraints); jLabel13.setFont(jLabel13.getFont().deriveFont(jLabel13.getFont().getSize()-2f)); jLabel13.setText("Grid extension:"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 3; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; cameraPositionPanel.add(jLabel13, gridBagConstraints); eastLabel.setFont(eastLabel.getFont().deriveFont(eastLabel.getFont().getSize()-2f)); eastLabel.setText("jLabel14"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 4; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(eastLabel, gridBagConstraints); jLabel15.setFont(jLabel15.getFont().deriveFont(jLabel15.getFont().getSize()-2f)); jLabel15.setText("East"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 4; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(jLabel15, gridBagConstraints); jLabel16.setFont(jLabel16.getFont().deriveFont(jLabel16.getFont().getSize()-2f)); jLabel16.setText("South"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 5; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(jLabel16, gridBagConstraints); southLabel.setFont(southLabel.getFont().deriveFont(southLabel.getFont().getSize()-2f)); southLabel.setText("jLabel14"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 5; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(southLabel, gridBagConstraints); jLabel18.setFont(jLabel18.getFont().deriveFont(jLabel18.getFont().getSize()-2f)); jLabel18.setText("North"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 6; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(jLabel18, gridBagConstraints); northLabel.setFont(northLabel.getFont().deriveFont(northLabel.getFont().getSize()-2f)); northLabel.setText("jLabel14"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 6; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(northLabel, gridBagConstraints); jLabel20.setFont(jLabel20.getFont().deriveFont(jLabel20.getFont().getSize()-2f)); jLabel20.setText("West"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(jLabel20, gridBagConstraints); westLabel.setFont(westLabel.getFont().deriveFont(westLabel.getFont().getSize()-2f)); westLabel.setText("jLabel14"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 2; gridBagConstraints.gridy = 3; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0); cameraPositionPanel.add(westLabel, gridBagConstraints); hypsoPanel.setLayout(new java.awt.GridBagLayout()); hypsoSlider.setOrientation(1); hypsoSlider.setPreferredSize(new java.awt.Dimension(40, 350)); hypsoSlider.addPropertyChangeListener(new java.beans.PropertyChangeListener() { public void propertyChange(java.beans.PropertyChangeEvent evt) { hypsoSliderPropertyChange(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.gridheight = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12); hypsoPanel.add(hypsoSlider, gridBagConstraints); hypsoCheckBox.setText("Enable"); hypsoCheckBox.setToolTipText("Enable or disable hypsometric tinting."); hypsoCheckBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { hypsoCheckBoxActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; hypsoPanel.add(hypsoCheckBox, gridBagConstraints); hypsoLabel.setFont(hypsoLabel.getFont().deriveFont(hypsoLabel.getFont().getSize()-2f)); hypsoLabel.setText("<html>Click on the color gradient to add thumbs.<br>Double-click a thumb to change its color.<br><br>Hypsometric tints are not possible in <br>combination with a texture image.</html>"); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; gridBagConstraints.gridwidth = 2; gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST; gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0); hypsoPanel.add(hypsoLabel, gridBagConstraints); hypsoDefaultButton.setText("Default"); hypsoDefaultButton.setEnabled(false); hypsoDefaultButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { hypsoDefaultButtonActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 1; gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST; hypsoPanel.add(hypsoDefaultButton, gridBagConstraints); setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); setTitle(APPNAME); setLocationByPlatform(true); addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); container3D.setOpaque(false); container3D.addComponentListener(new java.awt.event.ComponentAdapter() { public void componentResized(java.awt.event.ComponentEvent evt) { container3DComponentResized(evt); } }); container3D.setLayout(new java.awt.BorderLayout()); getContentPane().add(container3D, java.awt.BorderLayout.CENTER); eastPanel.setLayout(new java.awt.BorderLayout()); jPanel1.setLayout(new java.awt.GridBagLayout()); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 2; jPanel1.add(map3DOptionsPanel, gridBagConstraints); eastPanel.add(jPanel1, java.awt.BorderLayout.NORTH); getContentPane().add(eastPanel, java.awt.BorderLayout.EAST); fileMenu.setText("File"); openDEMMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); openDEMMenuItem.setText("Open Terrain Model�"); openDEMMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openDEMMenuItemActionPerformed(evt); } }); fileMenu.add(openDEMMenuItem); openRecentMenu.setText("Open Recent Terrain Model"); fileMenu.add(openRecentMenu); saveDEMMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); saveDEMMenuItem.setText("Save Terrain Model�"); saveDEMMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveDEMMenuItemActionPerformed(evt); } }); fileMenu.add(saveDEMMenuItem); fileMenu.add(jSeparator5); openTextureMenuItem.setText("Open Texture Image�"); openTextureMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openTextureMenuItemActionPerformed(evt); } }); fileMenu.add(openTextureMenuItem); clearTextureMenuItem.setText("Remove Texture or Hypsometric Tints"); clearTextureMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearTextureMenuItemActionPerformed(evt); } }); fileMenu.add(clearTextureMenuItem); fileMenu.add(jSeparator1); saveSettingsMenuItem.setText("Save Settings�"); saveSettingsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveSettingsMenuItemActionPerformed(evt); } }); fileMenu.add(saveSettingsMenuItem); openSettingsMenuItem.setText("Open Settings�"); openSettingsMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { openSettingsMenuItemActionPerformed(evt); } }); fileMenu.add(openSettingsMenuItem); fileMenu.add(jSeparator2); export3DViewMenuItem.setText("Export Rendering�"); export3DViewMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { export3DViewMenuItemActionPerformed(evt); } }); fileMenu.add(export3DViewMenuItem); fileMenu.add(exitMenuSeparator); exitMenuItem.setText("Exit"); exitMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { exitMenuItemActionPerformed(evt); } }); fileMenu.add(exitMenuItem); menuBar.add(fileMenu); editMenu.setText("Edit"); cutMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); cutMenuItem.setText("Cut"); cutMenuItem.setEnabled(false); editMenu.add(cutMenuItem); copyMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_C, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); copyMenuItem.setText("Copy"); copyMenuItem.setEnabled(false); editMenu.add(copyMenuItem); pasteMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_V, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); pasteMenuItem.setText("Paste"); pasteMenuItem.setEnabled(false); editMenu.add(pasteMenuItem); deleteMenuItem.setText("Delete"); deleteMenuItem.setEnabled(false); editMenu.add(deleteMenuItem); editMenu.add(jSeparator3); gridInfoMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); gridInfoMenuItem.setText("Terrain Model Info�"); gridInfoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { gridInfoMenuItemActionPerformed(evt); } }); editMenu.add(gridInfoMenuItem); editMenu.add(jSeparator7); scaleTerrainMenuItem.setText("Scale Terrain�"); scaleTerrainMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { scaleTerrainMenuItemActionPerformed(evt); } }); editMenu.add(scaleTerrainMenuItem); editMenu.add(jSeparator8); cameraPositionMenuItem.setText("Position Cylindrical Camera�"); cameraPositionMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cameraPositionMenuItemActionPerformed(evt); } }); editMenu.add(cameraPositionMenuItem); menuBar.add(editMenu); extrasMenu.setText("Extras"); highResMenuItem.setText("Use High Resolution Cylindrical Rendering"); highResMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { highResMenuItemActionPerformed(evt); } }); extrasMenu.add(highResMenuItem); bindLightDirectionMenuItem.setText("Bind Light Direction to View Direction"); bindLightDirectionMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bindLightDirectionMenuItemActionPerformed(evt); } }); extrasMenu.add(bindLightDirectionMenuItem); backgroundColorMenuItem.setText("Background Color"); backgroundColorMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { backgroundColorMenuItemActionPerformed(evt); } }); extrasMenu.add(backgroundColorMenuItem); extrasMenu.add(jSeparator9); animationMenuItem.setText("Animation"); animationMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { animationMenuItemActionPerformed(evt); } }); extrasMenu.add(animationMenuItem); menuBar.add(extrasMenu); //menuBar.remove(extrasMenu); macHelpMenu.setText("Help"); systemInfoMenuItem.setText("System Info�"); systemInfoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { systemInfoMenuItemActionPerformed(evt); } }); macHelpMenu.add(systemInfoMenuItem); menuBar.add(macHelpMenu); winHelpMenu.setText("?"); infoMenuItem.setText("Info"); infoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { infoMenuItemActionPerformed(evt); } }); winHelpMenu.add(infoMenuItem); winSystemInfoMenuItem.setText("System Info�"); winSystemInfoMenuItem.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { winSystemInfoMenuItemActionPerformed(evt); } }); winHelpMenu.add(winSystemInfoMenuItem); menuBar.add(winHelpMenu); setJMenuBar(menuBar); pack(); }// </editor-fold>//GEN-END:initComponents private void saveDEMMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveDEMMenuItemActionPerformed if (getFullResolutionGrid() == null) { noTerrainErrorMessage(this); return; } String name = this.getTitle(); name = FileUtils.cutFileExtension(name); if (name.isEmpty()) { name = "grid.asc"; } String path = FileUtils.askFile(null, "Export ESRI ASCII Grid", name, false, "asc"); if (path == null) { return; } throw new NotImplementedException(); // FIXME }//GEN-LAST:event_saveDEMMenuItemActionPerformed private void saveSettingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveSettingsMenuItemActionPerformed try { String filePath = FileUtils.askFile(this, "Save Settings", "Settings.txt", false, "txt"); if (filePath == null) { return; } String serializedModel = this.toString(); BufferedWriter out = new BufferedWriter(new FileWriter(filePath)); out.write(serializedModel); out.close(); } catch (IOException e) { ika.utils.ErrorDialog.showErrorDialog("The settings could not be written.", e); } }//GEN-LAST:event_saveSettingsMenuItemActionPerformed private void openSettingsMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openSettingsMenuItemActionPerformed try { String newFilePath = FileUtils.askFile(this, "Open Settings", true); if (newFilePath == null) { return; // user canceled } // import data from the file File file = new File(newFilePath); byte[] data = FileUtils.getBytesFromFile(file); this.fromString(new String(data)); this.modelChanged(); } catch (IOException e) { String msg = "The settings could not be read."; String title = APPNAME + " Error"; ika.utils.ErrorDialog.showErrorDialog(msg, title, e, this); } }//GEN-LAST:event_openSettingsMenuItemActionPerformed private void export3DViewMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_export3DViewMenuItemActionPerformed try { String path = FileUtils.askFile(null, "Save 3D View", "3d.png", false, "png"); if (path != null) { ImageIO.write(map3DViewer.getImage(), "png", new File(path)); } } catch (IOException ex) { String msg = "The image could not be saved."; String title = APPNAME + " Error"; ika.utils.ErrorDialog.showErrorDialog(msg, title, ex, this); } }//GEN-LAST:event_export3DViewMenuItemActionPerformed private void container3DComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_container3DComponentResized if (map3DViewer != null) { this.map3DViewer.display(); } }//GEN-LAST:event_container3DComponentResized private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing askToCloseWindowAndExit(); }//GEN-LAST:event_formWindowClosing private void infoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_infoMenuItemActionPerformed ika.gui.ProgramInfoPanel.showApplicationInfo(); }//GEN-LAST:event_infoMenuItemActionPerformed private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed this.askToCloseWindowAndExit(); }//GEN-LAST:event_exitMenuItemActionPerformed private void openDEMMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openDEMMenuItemActionPerformed this.openDEM(); }//GEN-LAST:event_openDEMMenuItemActionPerformed private void openTextureMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openTextureMenuItemActionPerformed String path = FileUtils.askFile(this, "Load Texture", true); if (path == null) { return; } openTexture(path); }//GEN-LAST:event_openTextureMenuItemActionPerformed private void clearTextureMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearTextureMenuItemActionPerformed this.map3DViewer.clearTextureImage(); }//GEN-LAST:event_clearTextureMenuItemActionPerformed private void highResMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_highResMenuItemActionPerformed map3DViewer.setHighResCylindricalRendering(highResMenuItem.isSelected()); }//GEN-LAST:event_highResMenuItemActionPerformed private void bindLightDirectionMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bindLightDirectionMenuItemActionPerformed map3DViewer.setBindLightDirectionToViewDirection(bindLightDirectionMenuItem.isSelected()); }//GEN-LAST:event_bindLightDirectionMenuItemActionPerformed private void cameraPositionMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cameraPositionMenuItemActionPerformed // get grid dimensions GeoGrid grid = this.getFullResolutionGrid(); if (grid == null) { noTerrainErrorMessage(this); return; } double w = grid.getBounds2D(GeoObject.UNDEFINED_SCALE).getWidth(); double h = grid.getBounds2D(GeoObject.UNDEFINED_SCALE).getHeight(); double cx = grid.getCenterX(GeoObject.UNDEFINED_SCALE); double cy = grid.getCenterY(GeoObject.UNDEFINED_SCALE); // init extension labels DecimalFormat format = new DecimalFormat("#,##0.###"); westLabel.setText(format.format(grid.getWest())); eastLabel.setText(format.format(grid.getEast())); southLabel.setText(format.format(grid.getSouth())); northLabel.setText(format.format(grid.getNorth())); // write current coordinates double xrel = this.map3DViewer.getShiftX(); double yrel = this.map3DViewer.getShiftY(); double x = xrel * w / 2 + cx; double y = yrel * h / 2 + cy; cameraXFormattedTextField.setValue(x); cameraYFormattedTextField.setValue(y); // show dialog int option = JOptionPane.showOptionDialog(this, cameraPositionPanel, "Position Cylindrical Camera", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option != JOptionPane.OK_OPTION) { return; } // read new coordinates try { cameraXFormattedTextField.commitEdit(); cameraYFormattedTextField.commitEdit(); x = ((Number) (cameraXFormattedTextField.getValue())).doubleValue(); y = ((Number) (cameraYFormattedTextField.getValue())).doubleValue(); this.map3DViewer.setCamera(Camera.cylindrical); xrel = (x - cx) / w * 2; yrel = (y - cy) / h * 2; this.map3DViewer.setShiftX((float) xrel); this.map3DViewer.setShiftY((float) yrel); } catch (Exception exc) { ErrorDialog.showErrorDialog("An error occured while positioning the camera.", "Error", exc, this); } }//GEN-LAST:event_cameraPositionMenuItemActionPerformed private void scaleTerrainMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_scaleTerrainMenuItemActionPerformed if (getFullResolutionGrid() == null) { noTerrainErrorMessage(this); return; } int option = JOptionPane.showOptionDialog(this, scaleTerrainPanel, "Scale Terrain", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); if (option != JOptionPane.OK_OPTION) { return; } try { scaleTerrainFormattedTextField.commitEdit(); java.lang.Number f = (java.lang.Number) (scaleTerrainFormattedTextField.getValue()); float scale = f.floatValue(); GridScaleOperator op = new GridScaleOperator(scale); GeoGrid scaledGrid = op.operate(getFullResolutionGrid()); gridPyramid = new GaussianPyramid(scaledGrid, 9999, MIN_GRID_CELLS); originalInfoText = getFullResolutionGrid().toStringWithStatistics("<br>"); modelChanged(); } catch (Exception exc) { ErrorDialog.showErrorDialog("An error occured while scaling the terrain.", "Error", exc, this); } }//GEN-LAST:event_scaleTerrainMenuItemActionPerformed private void gridInfoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_gridInfoMenuItemActionPerformed this.showGridInfo(); }//GEN-LAST:event_gridInfoMenuItemActionPerformed private void backgroundColorMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backgroundColorMenuItemActionPerformed Color bc = map3DViewer.getBackgroundColor(); bc = ColorPicker.showDialog(this, "Background Color", bc, false); if (bc != null) { map3DViewer.setBackgroundColor(bc); } }//GEN-LAST:event_backgroundColorMenuItemActionPerformed private void systemInfoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_systemInfoMenuItemActionPerformed new SystemInfoGPU(this); }//GEN-LAST:event_systemInfoMenuItemActionPerformed private void winSystemInfoMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_winSystemInfoMenuItemActionPerformed new SystemInfoGPU(this); }//GEN-LAST:event_winSystemInfoMenuItemActionPerformed private void hypsoSliderPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_hypsoSliderPropertyChange String propName = evt.getPropertyName(); if (MultiThumbSlider.VALUES_PROPERTY.equals(propName) // thumb position || MultiThumbSlider.ADJUST_PROPERTY.equals(propName) // color ) { if (!hypsoSlider.isValueAdjusting()) { this.readHypsometricTints(); } } }//GEN-LAST:event_hypsoSliderPropertyChange private void hypsoCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hypsoCheckBoxActionPerformed hypsoSlider.setEnabled(hypsoCheckBox.isSelected()); hypsoDefaultButton.setEnabled(hypsoCheckBox.isSelected()); adjustHypsometricTintingVisibility(); }//GEN-LAST:event_hypsoCheckBoxActionPerformed private void hypsoDefaultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hypsoDefaultButtonActionPerformed this.initHypsoSlider(); }//GEN-LAST:event_hypsoDefaultButtonActionPerformed private void animationMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_animationMenuItemActionPerformed this.map3DViewer.setCamera(Map3DViewer.Camera.planOblique); ShearPanel.showPanel(this, map3DViewer); }//GEN-LAST:event_animationMenuItemActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenuItem animationMenuItem; private javax.swing.JMenuItem backgroundColorMenuItem; private javax.swing.JCheckBoxMenuItem bindLightDirectionMenuItem; private javax.swing.JMenuItem cameraPositionMenuItem; private javax.swing.JPanel cameraPositionPanel; private javax.swing.JFormattedTextField cameraXFormattedTextField; private javax.swing.JFormattedTextField cameraYFormattedTextField; private javax.swing.JMenuItem clearTextureMenuItem; private javax.swing.JPanel container3D; private javax.swing.JMenuItem copyMenuItem; private javax.swing.JMenuItem cutMenuItem; private javax.swing.JMenuItem deleteMenuItem; private javax.swing.JLabel eastLabel; private javax.swing.JPanel eastPanel; private javax.swing.JMenu editMenu; private javax.swing.JMenuItem exitMenuItem; private javax.swing.JSeparator exitMenuSeparator; private javax.swing.JMenuItem export3DViewMenuItem; private javax.swing.JMenu extrasMenu; private javax.swing.JMenu fileMenu; private javax.swing.JMenuItem gridInfoMenuItem; private javax.swing.JCheckBoxMenuItem highResMenuItem; private javax.swing.JCheckBox hypsoCheckBox; private javax.swing.JButton hypsoDefaultButton; private javax.swing.JPanel hypsoPanel; private com.bric.swing.GradientSlider hypsoSlider; private javax.swing.JMenuItem infoMenuItem; private javax.swing.JLabel jLabel15; private javax.swing.JLabel jLabel16; private javax.swing.JLabel jLabel18; private javax.swing.JLabel jLabel20; private javax.swing.JLabel jLabel6; private javax.swing.JPanel jPanel1; private javax.swing.JSeparator jSeparator1; private javax.swing.JSeparator jSeparator2; private javax.swing.JSeparator jSeparator3; private javax.swing.JSeparator jSeparator5; private javax.swing.JSeparator jSeparator7; private javax.swing.JSeparator jSeparator8; private javax.swing.JPopupMenu.Separator jSeparator9; private javax.swing.ButtonGroup lodButtonGroup; private javax.swing.JPanel lodButtonPanel; private javax.swing.JTextArea lodInfoTextArea; private javax.swing.JPanel lodPanel; private javax.swing.JPanel lodPanel_; private javax.swing.JMenu macHelpMenu; private ch.ethz.karto.map3d.gui.Map3DOptionsPanel map3DOptionsPanel; private javax.swing.JMenuBar menuBar; private javax.swing.JLabel northLabel; private javax.swing.JMenuItem openDEMMenuItem; private javax.swing.JMenu openRecentMenu; private javax.swing.JMenuItem openSettingsMenuItem; private javax.swing.JMenuItem openTextureMenuItem; private javax.swing.JMenuItem pasteMenuItem; private javax.swing.JMenuItem saveDEMMenuItem; private javax.swing.JMenuItem saveSettingsMenuItem; private javax.swing.JFormattedTextField scaleTerrainFormattedTextField; private javax.swing.JMenuItem scaleTerrainMenuItem; private javax.swing.JPanel scaleTerrainPanel; private javax.swing.JLabel southLabel; private javax.swing.JMenuItem systemInfoMenuItem; private javax.swing.JLabel westLabel; private javax.swing.JMenu winHelpMenu; private javax.swing.JMenuItem winSystemInfoMenuItem; // End of variables declaration//GEN-END:variables @Override public void propertyChange(PropertyChangeEvent evt) { } /** * Part of the ComponentListener interface. */ @Override public void componentShown(ComponentEvent e) { } /** * Part of the ComponentListener interface. */ @Override public void componentHidden(ComponentEvent e) { } /** * Part of the ComponentListener interface. */ @Override public void componentMoved(ComponentEvent e) { } /** * Part of the ComponentListener interface. Make sure this window is not * getting too small. */ @Override public void componentResized(ComponentEvent e) { if (this.packedSize == null) { return; } // Check if either the width or the height are below minimum // and reset size if necessary. // Note: this is not elegant, but SUN recommends doing it that way. int width = getWidth(); int height = getHeight(); boolean resize = false; if (width < this.packedSize.width) { resize = true; width = this.packedSize.width; } if (height < this.packedSize.height) { resize = true; height = this.packedSize.height; } if (resize) { setSize(width, height); } } private void initHypsoSlider() { float[] values = new float[] {0, 0.08f, 0.24f, 0.43f, 0.69f, 0.89f}; Color[] colors = new Color[] { new Color(120, 181, 141), new Color(124, 172, 104), new Color(190, 194, 107), new Color(212, 218, 170), new Color(225, 246, 244), new Color(255, 255, 255) }; hypsoSlider.setValues(values, colors); } private void readHypsometricTints() { BufferedImage image = new BufferedImage(256, 1, BufferedImage.TYPE_INT_ARGB); for (int i = 0; i < 256; i++) { // GradientSlider returns null for 0 and 1. Rescale to get around this bug. // float t = i / 255f; float t = (1 + 253f / 255f * i) / 255f; Color color = (Color) hypsoSlider.getValue(t); image.setRGB(i, 0, color.getRGB()); } modelChanged(); map3DViewer.display(); } public void showHypsometricDialog() { //hypsoCheckBox.setSelected(map3DViewer.hasTexture() && map3DViewer.isTexture1D()); // FIXME JOptionPane.showOptionDialog(this, hypsoPanel, "Hypsometric Tints", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null); adjustHypsometricTintingVisibility(); } private void adjustHypsometricTintingVisibility() { if (hypsoCheckBox.isSelected()) { this.readHypsometricTints(); } else { map3DViewer.display(); } } }