package tim.prune.function; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import tim.prune.App; import tim.prune.GenericFunction; import tim.prune.I18nManager; import tim.prune.config.Config; import tim.prune.gui.BaseImageDefinitionPanel; import tim.prune.gui.DecimalNumberField; import tim.prune.gui.TerrainDefinitionPanel; import tim.prune.threedee.TerrainDefinition; import tim.prune.threedee.ThreeDException; import tim.prune.threedee.ThreeDWindow; import tim.prune.threedee.WindowFactory; import tim.prune.tips.TipManager; /** * Class to show the 3d window */ public class ShowThreeDFunction extends GenericFunction { /** Dialog for input parameters */ private JDialog _dialog = null; /** Field for altitude exaggeration value */ private DecimalNumberField _exaggField = null; /** Component for defining the base image */ private BaseImageDefinitionPanel _baseImagePanel = null; /** Component for defining the terrain */ private TerrainDefinitionPanel _terrainPanel = null; /** * Constructor * @param inApp app object */ public ShowThreeDFunction(App inApp) { super(inApp); } /** * Get the name key */ public String getNameKey() { return "function.show3d"; } /** * Begin the function */ public void begin() { ThreeDWindow window = WindowFactory.getWindow(_parentFrame); if (window == null) { JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.function.nojava3d"), I18nManager.getText("error.function.notavailable.title"), JOptionPane.WARNING_MESSAGE); } else { // See if the track has any altitudes at all - if not, show a tip to use SRTM if (!_app.getTrackInfo().getTrack().hasAltitudeData()) { _app.showTip(TipManager.Tip_UseSrtmFor3d); } // Show a dialog to get the parameters if (_dialog == null) { _dialog = new JDialog(_app.getFrame(), I18nManager.getText(getNameKey()), true); _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); _dialog.getContentPane().add(makeDialogComponents()); _dialog.pack(); } final int exaggFactor = Config.getConfigInt(Config.KEY_HEIGHT_EXAGGERATION); if (exaggFactor > 0) { _exaggField.setValue(exaggFactor / 100.0); } _baseImagePanel.updateBaseImageDetails(); _dialog.setLocationRelativeTo(_app.getFrame()); _dialog.setVisible(true); } } /** * Make the dialog components to select the options * @return JPanel holding the gui elements */ private JPanel makeDialogComponents() { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout(4, 4)); JPanel innerPanel = new JPanel(); innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.Y_AXIS)); // Panel for altitude exaggeration JPanel exaggPanel = new JPanel(); exaggPanel.setLayout(new FlowLayout()); exaggPanel.add(new JLabel(I18nManager.getText("dialog.3d.altitudefactor") + ": ")); _exaggField = new DecimalNumberField(); // don't allow negative numbers _exaggField.setText("5.0"); exaggPanel.add(_exaggField); innerPanel.add(exaggPanel); innerPanel.add(Box.createVerticalStrut(4)); // Panel for terrain _terrainPanel = new TerrainDefinitionPanel(); innerPanel.add(_terrainPanel); mainPanel.add(innerPanel, BorderLayout.NORTH); innerPanel.add(Box.createVerticalStrut(4)); // Panel for base image (null because we don't need callback) _baseImagePanel = new BaseImageDefinitionPanel(null, _dialog, _app.getTrackInfo().getTrack()); innerPanel.add(_baseImagePanel); // OK, Cancel buttons JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); JButton okButton = new JButton(I18nManager.getText("button.ok")); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _dialog.dispose(); new Thread(new Runnable() { public void run() { finish(); // needs to be in separate thread } }).start(); } }); buttonPanel.add(okButton); JButton cancelButton = new JButton(I18nManager.getText("button.cancel")); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { _dialog.dispose(); } }); buttonPanel.add(cancelButton); mainPanel.add(buttonPanel, BorderLayout.SOUTH); return mainPanel; } /** * All parameters have been selected in the input dialog, now we can go to the 3d window */ private void finish() { // Store exaggeration factor and grid size in config Config.setConfigInt(Config.KEY_HEIGHT_EXAGGERATION, (int) (_exaggField.getValue() * 100)); int terrainGridSize = _terrainPanel.getGridSize(); if (terrainGridSize < 20) {terrainGridSize = 20;} Config.setConfigInt(Config.KEY_TERRAIN_GRID_SIZE, terrainGridSize); ThreeDWindow window = WindowFactory.getWindow(_parentFrame); if (window != null) { try { // Pass the parameters to use and show the window window.setTrack(_app.getTrackInfo().getTrack()); window.setAltitudeFactor(_exaggField.getValue()); // Also pass the base image parameters from input dialog window.setBaseImageParameters(_baseImagePanel.getImageDefinition()); window.setTerrainParameters(new TerrainDefinition(_terrainPanel.getUseTerrain(), _terrainPanel.getGridSize())); window.setDataStatus(_app.getCurrentDataStatus()); window.show(); } catch (ThreeDException e) { _app.showErrorMessageNoLookup(getNameKey(), I18nManager.getText("error.3d") + ": " + e.getMessage()); } } } }