package com.socrata.datasync.ui; import com.socrata.datasync.config.controlfile.LocationColumn; import com.socrata.datasync.model.CSVModel; import com.socrata.datasync.model.ControlFileModel; import com.socrata.model.importer.Column; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * A dialog box which allows the customer to pick from columns in a CSV and then map them into * a location column * * Created by franklinwilliams */ public class SyntheticLocationDialog extends JDialog { Map<String,LocationColumn> syntheticColumnsCopy; ControlFileModel model; JComboBox addressCombo; JComboBox cityCombo; JComboBox zipCombo; JComboBox stateCombo; JComboBox latCombo; JComboBox lonCombo; JButton buttonOK; JButton buttonCancel; JLabel headerLabel; JComboBox activeLocation; public SyntheticLocationDialog(ControlFileModel model, JFrame parent, Map<String, LocationColumn> syntheticColumns, String initFieldName, String title) { //}, String message){ super(parent, title); this.model = model; //Copy the columns so that playing around with them in the dialog doesn't accidentially change the underlying model. this.syntheticColumnsCopy = copySyntheticColumns(syntheticColumns); setLocationRelativeTo(null); setModal(true); initComponents(); layoutComponents(); if (initFieldName != null) activeLocation.setSelectedItem(initFieldName); pack(); setVisible(true); } //Make a copy of the columns so that we don't change the control file just by launching the dialog. private Map<String, LocationColumn> copySyntheticColumns(Map<String,LocationColumn> original){ Map<String, LocationColumn> newSet = new HashMap<String, LocationColumn>(); for (String str : original.keySet()){ newSet.put(str,original.get(str)); } return newSet; } private void initComponents() { headerLabel = new JLabel(); headerLabel.setText("Select the fields that make up the column"); buttonOK = new JButton(); buttonOK.setText("OK"); buttonCancel = new JButton(); buttonCancel.setText("Cancel"); buttonCancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { setVisible(false); dispose(); } }); buttonOK.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { commitUpdates(); setVisible(false); dispose(); } }); addressCombo = getComboBox(); cityCombo = getComboBox(); stateCombo = getComboBox(); zipCombo = getComboBox(); latCombo = getComboBox(); lonCombo = getComboBox(); activeLocation = getLocationsCombobox(); activeLocation.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { updateSyntheticComponentComboboxes(); } } }); updateSyntheticComponentComboboxes(); } private void updateSyntheticComponentComboboxes(){ LocationColumn locationColumn = getActiveLocation(); if (locationColumn.address != null) addressCombo.setSelectedItem(locationColumn.address); addressCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.address = model.getColumnAtPosition(item.getIndex()); } }); if (locationColumn.city != null) cityCombo.setSelectedItem(locationColumn.city); cityCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.city = model.getColumnAtPosition(item.getIndex()); } }); if (locationColumn.state != null) stateCombo.setSelectedItem(locationColumn.state); stateCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.state = model.getColumnAtPosition(item.getIndex()); } }); if (locationColumn.zip != null) zipCombo.setSelectedItem(locationColumn.zip); zipCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.zip = model.getColumnAtPosition(item.getIndex()); } }); if (locationColumn.latitude != null) latCombo.setSelectedItem(locationColumn.latitude); latCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.latitude = model.getColumnAtPosition(item.getIndex()); } }); if (locationColumn.longitude != null) lonCombo.setSelectedItem(locationColumn.longitude); lonCombo.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { LocationColumn col = getActiveLocation(); SyntheticComboBoxItem item = (SyntheticComboBoxItem) e.getItem(); col.longitude = model.getColumnAtPosition(item.getIndex()); } }); } private void layoutComponents() { JPanel contentPane = new JPanel(); contentPane.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(4, 1, new Insets(10, 10, 10, 10), -1, -1)); contentPane.setMaximumSize(new Dimension(315, 291)); final JPanel panel1 = new JPanel(); panel1.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1)); contentPane.add(panel1, new com.intellij.uiDesigner.core.GridConstraints(3, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, 1, null, null, null, 0, false)); final com.intellij.uiDesigner.core.Spacer spacer1 = new com.intellij.uiDesigner.core.Spacer(); panel1.add(spacer1, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); final JPanel panel2 = new JPanel(); panel2.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1, true, false)); panel1.add(panel2, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); panel2.add(buttonOK, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); panel2.add(buttonCancel, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel3 = new JPanel(); panel3.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1)); contentPane.add(panel3, new com.intellij.uiDesigner.core.GridConstraints(2, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); panel3.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), null)); final JPanel panel4 = new JPanel(); panel4.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(6, 1, new Insets(0, 0, 0, 0), -1, -1)); panel3.add(panel4, new com.intellij.uiDesigner.core.GridConstraints(0, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); panel4.add(addressCombo, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); panel4.add(cityCombo, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); panel4.add(stateCombo, new com.intellij.uiDesigner.core.GridConstraints(2, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); panel4.add(zipCombo, new com.intellij.uiDesigner.core.GridConstraints(3, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); panel4.add(latCombo, new com.intellij.uiDesigner.core.GridConstraints(4, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); panel4.add(lonCombo, new com.intellij.uiDesigner.core.GridConstraints(5, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_WEST, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(220, -1), new Dimension(220, -1), 0, false)); final JPanel panel5 = new JPanel(); panel5.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(6, 2, new Insets(0, 0, 0, 0), -1, -1)); panel3.add(panel5, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, new Dimension(50, -1), null, 1, false)); final JLabel label1 = new JLabel(); label1.setText("Address"); panel5.add(label1, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 2, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label2 = new JLabel(); label2.setText("City"); panel5.add(label2, new com.intellij.uiDesigner.core.GridConstraints(1, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label3 = new JLabel(); label3.setText("State"); panel5.add(label3, new com.intellij.uiDesigner.core.GridConstraints(2, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label4 = new JLabel(); label4.setText("Zip"); panel5.add(label4, new com.intellij.uiDesigner.core.GridConstraints(3, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label5 = new JLabel(); label5.setText("Latitude"); panel5.add(label5, new com.intellij.uiDesigner.core.GridConstraints(4, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JLabel label6 = new JLabel(); label6.setText("Longitude"); panel5.add(label6, new com.intellij.uiDesigner.core.GridConstraints(5, 1, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_EAST, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final JPanel panel6 = new JPanel(); panel6.setLayout(new com.intellij.uiDesigner.core.GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1)); contentPane.add(panel6, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_BOTH, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_SHRINK | com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); headerLabel.setText("Select the location column to configure"); panel6.add(headerLabel, new com.intellij.uiDesigner.core.GridConstraints(0, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_NONE, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); panel6.add(activeLocation, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); final com.intellij.uiDesigner.core.Spacer spacer2 = new com.intellij.uiDesigner.core.Spacer(); contentPane.add(spacer2, new com.intellij.uiDesigner.core.GridConstraints(1, 0, 1, 1, com.intellij.uiDesigner.core.GridConstraints.ANCHOR_CENTER, com.intellij.uiDesigner.core.GridConstraints.FILL_HORIZONTAL, com.intellij.uiDesigner.core.GridConstraints.SIZEPOLICY_FIXED, 1, new Dimension(-1, 5), new Dimension(-1, 5), new Dimension(-1, 5), 3, false)); getContentPane().add(contentPane); } // Get a combobox whose values are all of the possible fields in the control file that could be mapped to this column private JComboBox getComboBox() { JComboBox<SyntheticComboBoxItem> columnNamesComboBox = new JComboBox<>(); for (int i = 0; i < model.getColumnCount();i++){ String friendlyName = model.getDisplayName(i); columnNamesComboBox.addItem(new SyntheticComboBoxItem(friendlyName,i)); } columnNamesComboBox.setSelectedIndex(-1); return columnNamesComboBox; } private JComboBox getLocationsCombobox(){ ArrayList<Column> columns = model.getDatasetModel().getColumns(); JComboBox<String> locationComboBox = new JComboBox<String>(); for (Column column : columns) { if (column.getDataTypeName().equals("location")) { locationComboBox.addItem(column.getFieldName()); } } locationComboBox.setSelectedIndex(0); return locationComboBox; } private LocationColumn getActiveLocation() { String fieldName = (String) activeLocation.getSelectedItem(); LocationColumn locationColumn = syntheticColumnsCopy.get(fieldName); if (locationColumn == null) { locationColumn = new LocationColumn(); syntheticColumnsCopy.put(fieldName,locationColumn); } return locationColumn; } private void commitUpdates() { for (String field : syntheticColumnsCopy.keySet()) { model.setSyntheticLocation(field,syntheticColumnsCopy.get(field)); } //When lat and lon are set, there is no need to geocode. Turn it off if (latitudeOrLongitudeAreSet(syntheticColumnsCopy)) model.setSocrataGeocoding(false); } private boolean latitudeOrLongitudeAreSet(Map<String,LocationColumn> syntheticColumns){ for (String key : syntheticColumns.keySet()){ LocationColumn column = syntheticColumns.get(key); if (column.latitude != null || column.longitude != null) return true; } return false; } } // All of the updates will be done based on the index of the columns array in the model. // This will provide a facility for displaying a friendly name, while still updating the internal // name by index, whatever it happens to be at the time. class SyntheticComboBoxItem{ String displayName; int index; public SyntheticComboBoxItem(String displayName, int index){ this.displayName = displayName; this.index = index; } public String getDisplayName(){ return displayName; } public int getIndex(){ return index; } @Override public String toString(){ return getDisplayName(); } }