package com.socrata.datasync.ui; import com.socrata.datasync.model.CSVModel; import com.socrata.datasync.model.ControlFileModel; import com.socrata.datasync.model.DatasetModel; import com.socrata.model.importer.Column; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; /** * Provides UI to allow the customer to map a single column in the CSV to a single field name in the dataset * * Created by franklinwilliams. */ public class MappingPanel extends JPanel { JPanel CSVValuePreview = new JPanel(); JLabel CSVTitle = new JLabel(); JLabel CSVPreview = new JLabel(); int index; JComboBox<String> columnNamesComboBox; JLabel arrow = new JLabel("" + '\u2192'); String lastSelection; ControlFileModel model; final int IGNORE_INDEX = 0; final String ignoreField = "- Ignore this field -"; public MappingPanel(int index, ControlFileModel model, DatasetModel datasetModel){ initializeValues(index, model, datasetModel); styleComponents(); layoutComponents(); } public void update(){ updateCsvPreview(); updateCombobox(); } private void updateCsvPreview(){ CSVModel csv = model.getCsvModel(); CSVTitle.setText(csv.getColumnName(index)); setPreviewText(csv.getColumnPreview(index, 10)); } private void setPreviewText(String text){ String preview = "(ex. " + text.substring(0,Math.min(text.length(),50)) + ")"; CSVPreview.setText(preview); } private void updateCombobox(){ String selection = model.getColumnAtPosition(index); //Don't do anything if the state for the column hasn't changed (otherwise, you end up with a lot of events unnecessarily firing). if (selection == lastSelection) return; if (model.isIgnored(selection)) columnNamesComboBox.setSelectedIndex(IGNORE_INDEX); else columnNamesComboBox.setSelectedItem(selection); lastSelection = selection; } private void initializeValues(int index, ControlFileModel model, DatasetModel datasetModel){ this.index = index; this.model = model; columnNamesComboBox = new JComboBox<>(); // The ignore field must be the first item in the list. columnNamesComboBox.addItem(ignoreField); ArrayList<Column> columns = datasetModel.getColumns(); for (Column column : columns) { columnNamesComboBox.addItem(column.getFieldName()); } update(); columnNamesComboBox.addItemListener(new MappingComboboxListener()); } private void styleComponents(){ CSVPreview.setForeground(new Color(112,112,112)); this.setBackground(Color.WHITE); this.setBorder(BorderFactory.createMatteBorder(1,0,0,0,Color.gray)); CSVValuePreview.setOpaque(false); CSVValuePreview.setBackground(Color.WHITE); CSVTitle.setOpaque(false); CSVTitle.setBackground(Color.WHITE); CSVPreview.setOpaque(false); CSVPreview.setBackground(Color.WHITE); } private void layoutComponents(){ // this.setLayout(new BoxLayout(this,BoxLayout.X_AXIS)); this.setLayout(new BorderLayout()); this.setMinimumSize(new Dimension(800,48)); this.setMaximumSize(new Dimension(800,48)); CSVValuePreview.setLayout(new BoxLayout(CSVValuePreview,BoxLayout.Y_AXIS)); CSVTitle.setBorder (BorderFactory.createEmptyBorder(5,5,2,0)); CSVPreview.setBorder (BorderFactory.createEmptyBorder(0,5,10,0)); CSVValuePreview.add(CSVTitle); CSVValuePreview.add(CSVPreview); CSVValuePreview.setPreferredSize(new Dimension(300,48)); CSVValuePreview.setMaximumSize(new Dimension(300, 48)); columnNamesComboBox.setBorder(BorderFactory.createEmptyBorder(5,5,10,5)); columnNamesComboBox.setPreferredSize(new Dimension(200,48)); columnNamesComboBox.setMaximumSize(new Dimension(200, 48)); this.add(CSVValuePreview,BorderLayout.WEST); this.add(arrow, BorderLayout.CENTER); this.add(columnNamesComboBox, BorderLayout.EAST); } //Get a header panel with the same dimensions and layouts as the rows public static JPanel getHeaderPanel(){ JPanel header = new JPanel(); JLabel csvLabel = new JLabel("<html><b>CSV Field</b></html>"); JLabel fieldLabel = new JLabel("<html><b>Dataset Field</b></html>"); header.setBackground(Color.WHITE); csvLabel.setOpaque(false); fieldLabel.setOpaque(false); header.setBorder(BorderFactory.createEmptyBorder(5,5,0,0)); csvLabel.setPreferredSize(new Dimension(300,16)); csvLabel.setMaximumSize(new Dimension(300, 16)); header.setLayout(new BorderLayout()); header.setMinimumSize(new Dimension(800,48)); header.setMaximumSize(new Dimension(800,48)); fieldLabel.setBorder(BorderFactory.createEmptyBorder(5,7,0,0)); fieldLabel.setPreferredSize(new Dimension(200,16)); fieldLabel.setMaximumSize(new Dimension(200, 16)); header.add(csvLabel,BorderLayout.WEST); //header.add() header.add(fieldLabel, BorderLayout.EAST); return header; } private class MappingComboboxListener implements ItemListener { @Override public void itemStateChanged(ItemEvent e) { JComboBox box = (JComboBox) e.getSource(); if (e.getStateChange() == ItemEvent.SELECTED) { String selectedItem = (String) box.getSelectedItem(); //Apparently there is a way to select a null item in Java? if (selectedItem != null) { if (selectedItem.equals(ignoreField)) { model.ignoreColumnInCSVAtPosition(index); } else { model.updateColumnAtPosition(selectedItem, index); } } } } } }