import java.awt.CardLayout;
import java.awt.Component;
import java.awt.FlowLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
import java.awt.GridLayout;
+import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
{
private SetMapBgFunction _parent = null;
private JDialog _addDialog = null;
- private JRadioButton[] _typeRadios = null;
+ private JRadioButton[] _sourceTypeRadios = null;
private JPanel _cards = null;
+ private MapSource _originalSource = null;
// controls for osm panel
private JTextField _oNameField = null;
private JTextField _baseUrlField = null, _topUrlField = null;
- private JComboBox _oZoomCombo = null;
+ private JRadioButton[] _baseTypeRadios = null, _topTypeRadios = null;
+ private JComboBox<Integer> _oZoomCombo = null;
// controls for cloudmade panel
private JTextField _cNameField = null;
private JTextField _cStyleField = null;
- private JComboBox _cZoomCombo = null;
+ private JComboBox<Integer> _cZoomCombo = null;
private JButton _okButton = null;
+ /** array of file types */
+ private static final String[] FILE_TYPES = {"png", "jpg", "gif"};
+
/**
* Constructor
JPanel radioPanel = new JPanel();
ButtonGroup radioGroup = new ButtonGroup();
radioPanel.setLayout(new GridLayout(1, 0));
- _typeRadios = new JRadioButton[2];
- _typeRadios[0] = new JRadioButton("Openstreetmap");
- radioGroup.add(_typeRadios[0]);
- radioPanel.add(_typeRadios[0]);
- _typeRadios[1] = new JRadioButton("Cloudmade");
- radioGroup.add(_typeRadios[1]);
- radioPanel.add(_typeRadios[1]);
- _typeRadios[0].setSelected(true);
+ _sourceTypeRadios = new JRadioButton[2];
+ _sourceTypeRadios[0] = new JRadioButton("Openstreetmap");
+ radioGroup.add(_sourceTypeRadios[0]);
+ radioPanel.add(_sourceTypeRadios[0]);
+ _sourceTypeRadios[1] = new JRadioButton("Cloudmade");
+ radioGroup.add(_sourceTypeRadios[1]);
+ radioPanel.add(_sourceTypeRadios[1]);
+ _sourceTypeRadios[0].setSelected(true);
// listener for clicks on type radios
ActionListener typeListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
- CardLayout cl = (CardLayout) _cards.getLayout();
- if (_typeRadios[0].isSelected()) {cl.first(_cards);}
- else {cl.last(_cards);}
- enableOK();
+ onRadioClicked();
}
};
- _typeRadios[0].addActionListener(typeListener);
- _typeRadios[1].addActionListener(typeListener);
+ _sourceTypeRadios[0].addActionListener(typeListener);
+ _sourceTypeRadios[1].addActionListener(typeListener);
radioPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
dialogPanel.add(radioPanel, BorderLayout.NORTH);
KeyAdapter keyListener = new KeyAdapter() {
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ _addDialog.dispose();
+ }
+ else {
+ enableOK();
+ }
+ }
+ };
+ // Listener for any gui changes (to enable ok when anything changes on an edit)
+ ActionListener okEnabler = new ActionListener() {
+ public void actionPerformed(ActionEvent arg0) {
enableOK();
}
};
+
// openstreetmap panel
JPanel osmPanel = new JPanel();
- osmPanel.setLayout(new GridLayout(0, 2, 5, 5));
- osmPanel.setBorder(BorderFactory.createEmptyBorder(6, 2, 4, 2));
- osmPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")));
+ osmPanel.setLayout(new BorderLayout());
+ osmPanel.setBorder(BorderFactory.createEmptyBorder(6, 3, 4, 3));
+ JPanel gbPanel = new JPanel();
+ GridBagLayout gridbag = new GridBagLayout();
+ GridBagConstraints c = new GridBagConstraints();
+ gbPanel.setLayout(gridbag);
+ c.gridx = 0; c.gridy = 0;
+ c.gridheight = 1; c.gridwidth = 1;
+ c.weightx = 0.0; c.weighty = 0.0;
+ c.ipadx = 3; c.ipady = 5;
+ c.insets = new Insets(0, 0, 5, 0);
+ c.anchor = GridBagConstraints.FIRST_LINE_START;
+ gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")), c);
_oNameField = new JTextField(18);
_oNameField.addKeyListener(keyListener);
- osmPanel.add(_oNameField);
+ c.gridx = 1; c.weightx = 1.0;
+ gbPanel.add(_oNameField, c);
// Base layer
- osmPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer1url")));
+ c.gridx = 0; c.gridy = 1;
+ c.weightx = 0.0;
+ c.insets = new Insets(0, 0, 0, 0);
+ gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer1url")), c);
_baseUrlField = new JTextField(18);
_baseUrlField.addKeyListener(keyListener);
- osmPanel.add(_baseUrlField);
+ c.gridx = 1; c.weightx = 1.0;
+ gbPanel.add(_baseUrlField, c);
+ _baseTypeRadios = new JRadioButton[3];
+ radioGroup = new ButtonGroup();
+ for (int i=0; i<3; i++)
+ {
+ _baseTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
+ radioGroup.add(_baseTypeRadios[i]);
+ c.gridx = 2+i; c.weightx = 0.0;
+ gbPanel.add(_baseTypeRadios[i], c);
+ // Each type radio needs listener to call enableOk()
+ _baseTypeRadios[i].addActionListener(okEnabler);
+ }
+
// Top layer
- osmPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer2url")));
+ c.gridx = 0; c.gridy = 2;
+ gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.layer2url")), c);
_topUrlField = new JTextField(18);
_topUrlField.addKeyListener(keyListener);
- osmPanel.add(_topUrlField);
+ c.gridx = 1; c.weightx = 1.0;
+ gbPanel.add(_topUrlField, c);
+ _topTypeRadios = new JRadioButton[3];
+ radioGroup = new ButtonGroup();
+ for (int i=0; i<3; i++)
+ {
+ _topTypeRadios[i] = new JRadioButton(FILE_TYPES[i]);
+ radioGroup.add(_topTypeRadios[i]);
+ c.gridx = 2+i; c.weightx = 0.0;
+ gbPanel.add(_topTypeRadios[i], c);
+ // Each type radio needs listener to call enableOk()
+ _topTypeRadios[i].addActionListener(okEnabler);
+ }
// Max zoom
- osmPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")));
- _oZoomCombo = new JComboBox();
+ c.gridx = 0; c.gridy = 3;
+ gbPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")), c);
+ _oZoomCombo = new JComboBox<Integer>();
for (int i=10; i<=20; i++) {
- _oZoomCombo.addItem("" + i);
+ _oZoomCombo.addItem(i);
}
- osmPanel.add(_oZoomCombo);
+ // zoom dropdown needs listener to call enableOk()
+ _oZoomCombo.addActionListener(okEnabler);
+ c.gridx = 1;
+ gbPanel.add(_oZoomCombo, c);
+ osmPanel.add(gbPanel, BorderLayout.NORTH);
_cards.add(osmPanel, "card1");
+
// Panel for cloudmade source
JPanel cloudPanel = new JPanel();
- cloudPanel.setLayout(new GridLayout(0, 2, 5, 5));
- cloudPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")));
+ cloudPanel.setBorder(BorderFactory.createEmptyBorder(6, 3, 4, 3));
+ // Use a gridlayout inside a borderlayout to avoid stretching
+ cloudPanel.setLayout(new BorderLayout());
+ JPanel cloudGridPanel = new JPanel();
+ cloudGridPanel.setLayout(new GridLayout(0, 2, 5, 5));
+ cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.sourcename")));
_cNameField = new JTextField(18);
_cNameField.addKeyListener(keyListener);
- cloudPanel.add(_cNameField);
- cloudPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.cloudstyle")));
+ cloudGridPanel.add(_cNameField);
+ cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.cloudstyle")));
_cStyleField = new JTextField(18);
_cStyleField.addKeyListener(keyListener);
- cloudPanel.add(_cStyleField);
- cloudPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")));
- _cZoomCombo = new JComboBox();
+ cloudGridPanel.add(_cStyleField);
+ cloudGridPanel.add(new JLabel(I18nManager.getText("dialog.addmapsource.maxzoom")));
+ _cZoomCombo = new JComboBox<Integer>();
for (int i=10; i<=20; i++) {
- _cZoomCombo.addItem("" + i);
+ _cZoomCombo.addItem(i);
}
- cloudPanel.add(_cZoomCombo);
- cloudPanel.add(new JLabel(" ")); // force four rows to space text boxes properly
+ cloudGridPanel.add(_cZoomCombo);
+ cloudPanel.add(cloudGridPanel, BorderLayout.NORTH);
_cards.add(cloudPanel, "card2");
// cards
JPanel holderPanel = new JPanel();
/**
* Init and show the dialog
+ * @param inSource source object before edit, or null to add
+ */
+ public void showDialog(MapSource inSource)
+ {
+ _originalSource = inSource;
+ populateFields();
+ }
+
+ /**
+ * Clear all the dialog fields to prepare for an add
*/
- public void showDialog()
+ private void clearAllFields()
{
_oNameField.setText("");
_baseUrlField.setText("");
+ _baseTypeRadios[0].setSelected(true);
_topUrlField.setText("");
+ _topTypeRadios[0].setSelected(true);
_oZoomCombo.setSelectedIndex(8);
_cNameField.setText("");
_cStyleField.setText("");
_cZoomCombo.setSelectedIndex(8);
_okButton.setEnabled(false);
+ for (int i=0; i<2; i++) {
+ _sourceTypeRadios[i].setEnabled(true);
+ }
_addDialog.setVisible(true);
}
+ /**
+ * Init the dialog fields from the given source object
+ */
+ private void populateFields()
+ {
+ if (_originalSource == null)
+ {
+ clearAllFields();
+ return;
+ }
+ boolean sourceFound = false;
+ // See if it's a cloudmade source
+ try
+ {
+ CloudmadeMapSource cloudSource = (CloudmadeMapSource) _originalSource;
+ sourceFound = true;
+ _cNameField.setText(cloudSource.getName());
+ _cStyleField.setText(cloudSource.getStyle());
+ _cZoomCombo.setSelectedIndex(getZoomIndex(cloudSource.getMaxZoomLevel()));
+ _sourceTypeRadios[1].setSelected(true);
+ }
+ catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
+
+ // See if it's an osm source
+ if (!sourceFound)
+ {
+ try
+ {
+ OsmMapSource osmSource = (OsmMapSource) _originalSource;
+ sourceFound = true;
+ _oNameField.setText(osmSource.getName());
+ _baseUrlField.setText(osmSource.getBaseUrl(0));
+ int baseType = getBaseType(osmSource.getFileExtension(0));
+ _baseTypeRadios[baseType].setSelected(true);
+ _topUrlField.setText(osmSource.getNumLayers()==0?"":osmSource.getBaseUrl(1));
+ int topType = getBaseType(osmSource.getFileExtension(1));
+ _topTypeRadios[topType].setSelected(true);
+ _oZoomCombo.setSelectedIndex(getZoomIndex(osmSource.getMaxZoomLevel()));
+ _sourceTypeRadios[0].setSelected(true);
+ }
+ catch (ClassCastException cce) {} // ignore, sourceFound flag stays false
+ }
+ for (int i=0; i<2; i++) {
+ _sourceTypeRadios[i].setEnabled(false);
+ }
+ onRadioClicked();
+ _okButton.setEnabled(false);
+ _addDialog.setVisible(true);
+ }
+
+
+ /**
+ * React to one of the type radio buttons being clicked
+ */
+ private void onRadioClicked()
+ {
+ CardLayout cl = (CardLayout) _cards.getLayout();
+ if (_sourceTypeRadios[0].isSelected()) {cl.first(_cards);}
+ else {cl.last(_cards);}
+ enableOK();
+ }
/**
* Check the currently entered details and enable the OK button if it looks OK
private void enableOK()
{
boolean ok = false;
- if (_typeRadios[0].isSelected()) {ok = isOsmPanelOk();}
- if (_typeRadios[1].isSelected()) {ok = isCloudPanelOk();}
+ if (_sourceTypeRadios[0].isSelected()) {ok = isOsmPanelOk();}
+ if (_sourceTypeRadios[1].isSelected()) {ok = isCloudPanelOk();}
_okButton.setEnabled(ok);
}
private void finish()
{
MapSource newSource = null;
- if (_typeRadios[0].isSelected())
+ String origName = (_originalSource == null ? null : _originalSource.getName());
+ if (_sourceTypeRadios[0].isSelected())
{
// Openstreetmap source
- String sourceName = getUniqueSourcename(_oNameField.getText());
+ String sourceName = getValidSourcename(_oNameField.getText(), origName);
String url1 = _baseUrlField.getText().trim();
+ String ext1 = getFileExtension(_baseTypeRadios);
String url2 = _topUrlField.getText().trim();
- newSource = new OsmMapSource(sourceName, url1, url2, _oZoomCombo.getSelectedIndex()+10);
+ String ext2 = getFileExtension(_topTypeRadios);
+ newSource = new OsmMapSource(sourceName, url1, ext1, url2, ext2, _oZoomCombo.getSelectedIndex()+10);
}
- else if (_typeRadios[1].isSelected())
+ else if (_sourceTypeRadios[1].isSelected())
{
- String sourceName = getUniqueSourcename(_cNameField.getText());
+ String sourceName = getValidSourcename(_cNameField.getText(), origName);
newSource = new CloudmadeMapSource(sourceName, _cStyleField.getText(),
_cZoomCombo.getSelectedIndex()+10);
}
// Add new source if ok
if (newSource != null)
{
- MapSourceLibrary.addSource(newSource);
+ if (_originalSource == null) {
+ MapSourceLibrary.addSource(newSource);
+ }
+ else {
+ MapSourceLibrary.editSource(_originalSource, newSource);
+ }
// inform setmapbg dialog
_parent.updateList();
_addDialog.setVisible(false);
}
/**
- * Check the given source name if it exists in library already
+ * Check the given source name is valid and whether it exists in library already
* @param inName name to check
- * @return unique name not yet in library
+ * @param inOriginalName name of source before edit (or null for new source)
+ * @return valid name for the new source
*/
- private static String getUniqueSourcename(String inName)
+ private static String getValidSourcename(String inName, String inOriginalName)
{
String name = inName;
if (name == null) {name = "";}
name = I18nManager.getText("dialog.addmapsource.noname");
}
// Check there isn't already a map source with this name
- if (MapSourceLibrary.hasSourceName(name))
+ if (inOriginalName == null || !inOriginalName.equals(name))
{
- int suffix = 1;
- while (MapSourceLibrary.hasSourceName(name + suffix)) {
- suffix++;
+ if (MapSourceLibrary.hasSourceName(name))
+ {
+ int suffix = 1;
+ while (MapSourceLibrary.hasSourceName(name + suffix)) {
+ suffix++;
+ }
+ name += suffix;
}
- name += suffix;
}
return name;
}
+
+ /**
+ * Get the selected file extension
+ * @param inRadios array of radio buttons for selection
+ * @return selected file extension
+ */
+ private String getFileExtension(JRadioButton[] inRadios)
+ {
+ if (inRadios != null)
+ {
+ for (int i=0; i<inRadios.length; i++) {
+ if (inRadios[i] != null && inRadios[i].isSelected()) {
+ return FILE_TYPES[i];
+ }
+ }
+ }
+ return FILE_TYPES[0];
+ }
+
+ /**
+ * Get the index of the given image extension
+ * @param inExt file extension, such as "png"
+ * @return index from 0 to 2
+ */
+ private static int getBaseType(String inExt)
+ {
+ for (int i=0; i<FILE_TYPES.length; i++) {
+ if (FILE_TYPES[i].equals(inExt)) {
+ return i;
+ }
+ }
+ // Not found so default to png
+ return 0;
+ }
+
+ /**
+ * Get the dropdown index of the given zoom level
+ * @param inZoomLevel zoom level, eg 18
+ * @return index of dropdown to select
+ */
+ private static int getZoomIndex(int inZoomLevel)
+ {
+ return Math.max(0, inZoomLevel - 10);
+ }
}