package edu.colostate.vchill.gui; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; public class MapServerConfigWindow extends JPanel implements ChangeListener { private final int maxSliderSize = 255; private final int minSliderSize = 0; private static int Opacity = 255; ArrayList<String> layers; JList dragFromJList; JList overlayJList; JList underlayJList; DefaultListModel choices = new DefaultListModel(); DefaultListModel overlay = new DefaultListModel(); DefaultListModel underlay = new DefaultListModel(); private JButton displayMapButton; private JButton removeFromOverlayButton; private JButton removeFromUnderlayButton; private JButton addToOverlayButton; private JButton addToUnderlayButton; private JSlider weatherDataOpacitySlider; private JLabel weatherDataOpacityLabel; private static int[] selectedUnderlayIndices = null; private static int[] selectedOverlayIndices = null; public MapServerConfigWindow(ArrayList<String> passedLayers) { super(new BorderLayout()); layers = passedLayers; weatherDataOpacitySlider = new JSlider(JSlider.HORIZONTAL, minSliderSize, maxSliderSize, Opacity); weatherDataOpacitySlider.addChangeListener(this); for (int i = 0; i < layers.size(); i++) { choices.addElement(layers.get(i)); } populateOverlayAndUnderlay(); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); dragFromJList = new JList(choices); dragFromJList.setTransferHandler(new FromTransferHandler()); dragFromJList.setDragEnabled(true); dragFromJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JLabel label = new JLabel("Drag and drop choices to these boxes"); JScrollPane sp = new JScrollPane(dragFromJList); // sp.setAlignmentX(0f); p.add(label, BorderLayout.NORTH); p.add(sp, BorderLayout.WEST); JPanel subP = new JPanel(); subP.setLayout(new BoxLayout(subP, BoxLayout.X_AXIS)); addToOverlayButton = new JButton("Move to overlay"); addToOverlayButton.setActionCommand("Move to overlay"); addToOverlayButton.addActionListener(new overlayJListListener()); subP.add(addToOverlayButton, BorderLayout.WEST); /* * subP.add(Box.createHorizontalStrut(5)); subP.add(new * JSeparator(SwingConstants.VERTICAL)); * * subP.add(Box.createHorizontalStrut(5)); */ addToUnderlayButton = new JButton("Move to underlay"); addToUnderlayButton.setActionCommand("Move to underlay"); addToUnderlayButton.addActionListener(new underlayJListListener()); subP.add(addToUnderlayButton, BorderLayout.EAST); p.add(subP); add(p, BorderLayout.LINE_START); p.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); overlayJList = new JList(overlay); overlayJList.setTransferHandler(new OverlayTransferHandler(TransferHandler.MOVE)); overlayJList.setDropMode(DropMode.INSERT); overlayJList.setDragEnabled(true); overlayJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); overlayJList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() == 2) { removeFromOverlay(); } } }); underlayJList = new JList(underlay); underlayJList.setTransferHandler(new UnderlayTransferHandler(TransferHandler.MOVE)); underlayJList.setDropMode(DropMode.INSERT); underlayJList.setDragEnabled(true); underlayJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); underlayJList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() == 2) { removeFromUnderlay(); } } }); p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); label.setAlignmentX(0f); p.add(label); sp = new JScrollPane(overlayJList); sp.setAlignmentX(0f); p.add(sp); p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); sp.setAlignmentX(0f); p.add(sp); p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(p, BorderLayout.CENTER); label = new JLabel("Overlay:"); label.setAlignmentX(0f); p.add(label); sp.setAlignmentX(0f); p.add(sp); p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(p, BorderLayout.CENTER); removeFromOverlayButton = new JButton("Remove from Overlay"); removeFromOverlayButton.setActionCommand("Remove from Overlay"); removeFromOverlayButton.addActionListener(new RemoveFromOverlayListener()); p.add(removeFromOverlayButton); sp = new JScrollPane(underlayJList); sp.setAlignmentX(0f); p.add(sp); p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); label = new JLabel("Underlay"); label.setAlignmentX(0f); p.add(label); sp.setAlignmentX(0f); p.add(sp); p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); add(p, BorderLayout.CENTER); removeFromUnderlayButton = new JButton("Remove from Underlay"); removeFromUnderlayButton.setActionCommand("Remove from Underlay"); removeFromUnderlayButton.addActionListener(new RemoveFromUnderlayListener()); p.add(removeFromUnderlayButton); weatherDataOpacityLabel = new JLabel("Weather Data Opacity " + (Integer.toString((100 * Opacity / 255))) + "%"); p.add(weatherDataOpacityLabel); p.add(weatherDataOpacitySlider); // getContentPane().setPreferredSize(new Dimension(250, 300)); displayMapButton = new JButton("Display Map"); displayMapButton.setActionCommand("Display Map"); displayMapButton.addActionListener(new DisplayMapListener()); // Create a panel that uses BoxLayout. JPanel buttonPane = new JPanel(); buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS)); buttonPane.add(displayMapButton); buttonPane.add(Box.createHorizontalStrut(5)); buttonPane.add(new JSeparator(SwingConstants.VERTICAL)); buttonPane.add(Box.createHorizontalStrut(5)); buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // add(listScrollPane, BorderLayout.CENTER); add(buttonPane, BorderLayout.PAGE_END); } private int[] matchIndicesToTitles(DefaultListModel myDefaultListModel) { int[] myIndices = new int[myDefaultListModel.getSize()]; for (int i = 0; i < myDefaultListModel.getSize(); i++) { for (int j = 0; j < layers.size(); j++) { if (layers.get(j).equals(myDefaultListModel.get(i))) { myIndices[i] = j; } } } return myIndices; } public static int getOpacity() { return Opacity; } private void populateOverlayAndUnderlay() { if (selectedOverlayIndices == null) { // System.out.println("No overlay layers to display"); } else { for (int i = 0; i < selectedOverlayIndices.length; i++) { for (int j = 0; j < choices.getSize(); j++) { if (layers.get(selectedOverlayIndices[i]).equals(choices.get(j))) { String removedValue = (String) choices.get(j); choices.removeElementAt(j); overlay.insertElementAt(removedValue, overlay.getSize()); } } } } if (selectedUnderlayIndices == null) { // System.out.println("No underlay layers to display"); } else { for (int i = 0; i < selectedUnderlayIndices.length; i++) { for (int j = 0; j < choices.getSize(); j++) { if (layers.get(selectedUnderlayIndices[i]).equals(choices.get(j))) { String removedValue = (String) choices.get(j); choices.removeElementAt(j); underlay.insertElementAt(removedValue, underlay.getSize()); } } } } } public void removeFromOverlay() { int selectedIndex = overlayJList.getSelectedIndex(); String removedValue = (String) overlay.get(selectedIndex); overlay.removeElementAt(selectedIndex); choices.insertElementAt(removedValue, 0); } public void removeFromUnderlay() { int selectedIndex = underlayJList.getSelectedIndex(); String removedValue = (String) underlay.get(selectedIndex); underlay.removeElementAt(selectedIndex); choices.insertElementAt(removedValue, 0); } public void stateChanged(ChangeEvent e) { JSlider source = (JSlider) e.getSource(); weatherDataOpacityLabel.setText("Weather Data Opacity " + (Integer.toString((100 * weatherDataOpacitySlider.getValue() / 255))) + "%"); if (!source.getValueIsAdjusting()) { Opacity = source.getValue(); } } class DisplayMapListener implements ActionListener { public void actionPerformed(ActionEvent e) { // int index = dragToOverlay.getSelectedIndex(); selectedUnderlayIndices = matchIndicesToTitles(underlay); selectedOverlayIndices = matchIndicesToTitles(overlay); // int[] selectedUnderlayIndices = underlayJList.getSelectedIndices(); // int[] selectedOverlayIndices = overlayJList.getSelectedIndices(); MapServerConfig msConfig = MapServerConfig.getInstance(); msConfig.displayMap(selectedUnderlayIndices, selectedOverlayIndices); } } class RemoveFromOverlayListener implements ActionListener { public void actionPerformed(ActionEvent e) { removeFromOverlay(); } } class RemoveFromUnderlayListener implements ActionListener { public void actionPerformed(ActionEvent e) { removeFromUnderlay(); } } class underlayJListListener implements ActionListener { public void actionPerformed(ActionEvent e) { int selectedIndex = dragFromJList.getSelectedIndex(); String removedValue = (String) choices.get(selectedIndex); choices.removeElementAt(selectedIndex); underlay.insertElementAt(removedValue, underlay.getSize()); } } class overlayJListListener implements ActionListener { public void actionPerformed(ActionEvent e) { int selectedIndex = dragFromJList.getSelectedIndex(); String removedValue = (String) choices.get(selectedIndex); choices.removeElementAt(selectedIndex); overlay.insertElementAt(removedValue, overlay.getSize()); } } class FromTransferHandler extends TransferHandler { /** * */ private static final long serialVersionUID = 1L; public int getSourceActions(JComponent comp) { return MOVE; } private int index = 0; public Transferable createTransferable(JComponent comp) { index = dragFromJList.getSelectedIndex(); if (index < 0 || index >= choices.getSize()) { return null; } return new StringSelection((String) dragFromJList.getSelectedValue()); } public void exportDone(JComponent comp, Transferable trans, int action) { if (action != MOVE) { return; } choices.removeElementAt(index); } } class OverlayTransferHandler extends TransferHandler { int previousSize; int currentSize; public int getSourceActions(JComponent comp) { previousSize = overlay.getSize(); currentSize = overlay.getSize(); return MOVE; } private int index = 0; public Transferable createTransferable(JComponent comp) { index = overlayJList.getSelectedIndex(); if (index < 0 || index >= overlay.getSize()) { return null; } return new StringSelection((String) overlayJList.getSelectedValue()); } public void exportDone(JComponent comp, Transferable trans, int action) { try { String deletedValue = (String) overlay.get(index + 1); String otherDeletedValue = (String) overlay.get(index); if ((overlayJList.getSelectedIndex() <= index) && ((index + 1) <= overlay.getSize())) { overlay.removeElementAt(index + 1); } else overlay.removeElementAt(index); currentSize = overlay.getSize(); if (currentSize < previousSize) { overlay.insertElementAt(deletedValue, index); for (int i = 0; i < underlay.getSize(); i++) { if (i == 0) { String placeHolder = (String) overlay.get(index + 1); overlay.set(index + 1, deletedValue); overlay.set(index, placeHolder); overlayJList.setSelectedIndex(index); } if (otherDeletedValue.equals(underlay.get(i))) underlay.removeElementAt(i); } } } catch (Exception e) { for (int i = 0; i < underlay.getSize(); i++) { if (underlay.get(i).equals(overlay.get(overlayJList.getSelectedIndex()))) { underlay.removeElementAt(i); } } } } int action; public OverlayTransferHandler(int action) { this.action = action; } public boolean canImport(TransferHandler.TransferSupport support) { // for the demo, we'll only support drops (not clipboard paste) if (!support.isDrop()) { return false; } // we only import Strings if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } boolean actionSupported = (action & support.getSourceDropActions()) == action; if (actionSupported) { support.setDropAction(action); return true; } return false; } public boolean importData(TransferHandler.TransferSupport support) { // if we can't handle the import, say so if (!canImport(support)) { return false; } // fetch the drop location JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); int index = dl.getIndex(); // fetch the data and bail if this fails String data; try { data = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException e) { return false; } catch (java.io.IOException e) { return false; } JList list = (JList) support.getComponent(); DefaultListModel model = (DefaultListModel) list.getModel(); model.insertElementAt(data, index); Rectangle rect = list.getCellBounds(index, index); list.scrollRectToVisible(rect); list.setSelectedIndex(index); list.requestFocusInWindow(); return true; } } class UnderlayTransferHandler extends TransferHandler { int previousSize; int currentSize; public int getSourceActions(JComponent comp) { previousSize = underlay.getSize(); currentSize = underlay.getSize(); return MOVE; } private int index = 0; public Transferable createTransferable(JComponent comp) { index = underlayJList.getSelectedIndex(); if (index < 0 || index >= underlay.getSize()) { return null; } return new StringSelection((String) underlayJList.getSelectedValue()); } public void exportDone(JComponent comp, Transferable trans, int action) { try { String deletedValue = (String) underlay.get(index + 1); String otherDeletedValue = (String) underlay.get(index); if ((underlayJList.getSelectedIndex() <= index) && ((index + 1) <= underlay.getSize())) { underlay.removeElementAt(index + 1); } else underlay.removeElementAt(index); currentSize = underlay.getSize(); if (currentSize < previousSize) { underlay.insertElementAt(deletedValue, index); for (int i = 0; i < overlay.getSize(); i++) { if (i == 0) { String placeHolder = (String) underlay.get(index + 1); underlay.set(index + 1, deletedValue); underlay.set(index, placeHolder); underlayJList.setSelectedIndex(index); } if (otherDeletedValue.equals(overlay.get(i))) { overlay.removeElementAt(i); } } } } catch (Exception e) { for (int i = 0; i < overlay.getSize(); i++) { if (overlay.get(i).equals(underlay.get(underlayJList.getSelectedIndex()))) { overlay.removeElementAt(i); } } } } int action; public UnderlayTransferHandler(int action) { this.action = action; } public boolean canImport(TransferHandler.TransferSupport support) { // for the demo, we'll only support drops (not clipboard paste) if (!support.isDrop()) { return false; } // we only import Strings if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } boolean actionSupported = (action & support.getSourceDropActions()) == action; if (actionSupported) { support.setDropAction(action); return true; } return false; } public boolean importData(TransferHandler.TransferSupport support) { // if we can't handle the import, say so if (!canImport(support)) { return false; } // fetch the drop location JList.DropLocation dl = (JList.DropLocation) support.getDropLocation(); int index = dl.getIndex(); // fetch the data and bail if this fails String data; try { data = (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor); } catch (UnsupportedFlavorException e) { return false; } catch (java.io.IOException e) { return false; } JList list = (JList) support.getComponent(); DefaultListModel model = (DefaultListModel) list.getModel(); model.insertElementAt(data, index); Rectangle rect = list.getCellBounds(index, index); list.scrollRectToVisible(rect); list.setSelectedIndex(index); list.requestFocusInWindow(); return true; } } }