1 package tim.prune.function;
3 import java.awt.BorderLayout;
4 import java.awt.FlowLayout;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
8 import javax.swing.Box;
9 import javax.swing.BoxLayout;
10 import javax.swing.JButton;
11 import javax.swing.JDialog;
12 import javax.swing.JLabel;
13 import javax.swing.JOptionPane;
14 import javax.swing.JPanel;
17 import tim.prune.GenericFunction;
18 import tim.prune.I18nManager;
19 import tim.prune.config.Config;
20 import tim.prune.gui.BaseImageDefinitionPanel;
21 import tim.prune.gui.DecimalNumberField;
22 import tim.prune.gui.TerrainDefinitionPanel;
23 import tim.prune.threedee.TerrainDefinition;
24 import tim.prune.threedee.ThreeDException;
25 import tim.prune.threedee.ThreeDWindow;
26 import tim.prune.threedee.WindowFactory;
27 import tim.prune.tips.TipManager;
30 * Class to show the 3d window
32 public class ShowThreeDFunction extends GenericFunction
34 /** Dialog for input parameters */
35 private JDialog _dialog = null;
36 /** Field for altitude exaggeration value */
37 private DecimalNumberField _exaggField = null;
38 /** Component for defining the base image */
39 private BaseImageDefinitionPanel _baseImagePanel = null;
40 /** Component for defining the terrain */
41 private TerrainDefinitionPanel _terrainPanel = null;
45 * @param inApp app object
47 public ShowThreeDFunction(App inApp)
55 public String getNameKey() {
56 return "function.show3d";
64 ThreeDWindow window = WindowFactory.getWindow(_parentFrame);
67 JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.function.nojava3d"),
68 I18nManager.getText("error.function.notavailable.title"), JOptionPane.WARNING_MESSAGE);
72 // See if the track has any altitudes at all - if not, show a tip to use SRTM
73 if (!_app.getTrackInfo().getTrack().hasAltitudeData()) {
74 _app.showTip(TipManager.Tip_UseSrtmFor3d);
76 // Show a dialog to get the parameters
79 _dialog = new JDialog(_app.getFrame(), I18nManager.getText(getNameKey()), true);
80 _dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
81 _dialog.getContentPane().add(makeDialogComponents());
84 final int exaggFactor = Config.getConfigInt(Config.KEY_HEIGHT_EXAGGERATION);
85 if (exaggFactor > 0) {
86 _exaggField.setValue(exaggFactor / 100.0);
88 _baseImagePanel.updateBaseImageDetails();
89 _dialog.setLocationRelativeTo(_app.getFrame());
90 _dialog.setVisible(true);
95 * Make the dialog components to select the options
96 * @return JPanel holding the gui elements
98 private JPanel makeDialogComponents()
100 JPanel mainPanel = new JPanel();
101 mainPanel.setLayout(new BorderLayout(4, 4));
103 JPanel innerPanel = new JPanel();
104 innerPanel.setLayout(new BoxLayout(innerPanel, BoxLayout.Y_AXIS));
105 // Panel for altitude exaggeration
106 JPanel exaggPanel = new JPanel();
107 exaggPanel.setLayout(new FlowLayout());
108 exaggPanel.add(new JLabel(I18nManager.getText("dialog.3d.altitudefactor") + ": "));
109 _exaggField = new DecimalNumberField(); // don't allow negative numbers
110 _exaggField.setText("5.0");
111 exaggPanel.add(_exaggField);
112 innerPanel.add(exaggPanel);
113 innerPanel.add(Box.createVerticalStrut(4));
116 _terrainPanel = new TerrainDefinitionPanel();
117 innerPanel.add(_terrainPanel);
118 mainPanel.add(innerPanel, BorderLayout.NORTH);
119 innerPanel.add(Box.createVerticalStrut(4));
121 // Panel for base image (null because we don't need callback)
122 _baseImagePanel = new BaseImageDefinitionPanel(null, _dialog, _app.getTrackInfo().getTrack());
123 innerPanel.add(_baseImagePanel);
125 // OK, Cancel buttons
126 JPanel buttonPanel = new JPanel();
127 buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
128 JButton okButton = new JButton(I18nManager.getText("button.ok"));
129 okButton.addActionListener(new ActionListener() {
130 public void actionPerformed(ActionEvent e)
133 new Thread(new Runnable() {
135 finish(); // needs to be in separate thread
140 buttonPanel.add(okButton);
141 JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
142 cancelButton.addActionListener(new ActionListener() {
143 public void actionPerformed(ActionEvent e)
148 buttonPanel.add(cancelButton);
149 mainPanel.add(buttonPanel, BorderLayout.SOUTH);
155 * All parameters have been selected in the input dialog, now we can go to the 3d window
157 private void finish()
159 // Store exaggeration factor in config
160 Config.setConfigInt(Config.KEY_HEIGHT_EXAGGERATION, (int) (_exaggField.getValue() * 100));
161 ThreeDWindow window = WindowFactory.getWindow(_parentFrame);
166 // Pass the parameters to use and show the window
167 window.setTrack(_app.getTrackInfo().getTrack());
168 window.setAltitudeFactor(_exaggField.getValue());
169 // Also pass the base image parameters from input dialog
170 window.setBaseImageParameters(_baseImagePanel.getImageDefinition());
171 window.setTerrainParameters(new TerrainDefinition(_terrainPanel.getUseTerrain(), _terrainPanel.getGridSize()));
172 window.setDataStatus(_app.getCurrentDataStatus());
175 catch (ThreeDException e)
177 _app.showErrorMessageNoLookup(getNameKey(), I18nManager.getText("error.3d") + ": " + e.getMessage());