Swing JFC Java

/*
 This program is a part of the companion code for Core Java 8th ed.
 (http://horstmann.com/corejava)
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see .
 */
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.DefaultListModel;
import javax.swing.DropMode;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.TransferHandler;
/**
 * This program demonstrates drag and drop in an image list.
 * 
 * @version 1.00 2007-09-20
 * @author Cay Horstmann
 */
public class ImageListDnDTest {
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new ImageListDnDFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }
}
class ImageListDnDFrame extends JFrame {
  public ImageListDnDFrame() {
    setTitle("ImageListDnDTest");
    setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    list1 = new ImageList(new File("images1").listFiles());
    list2 = new ImageList(new File("images2").listFiles());
    setLayout(new GridLayout(2, 1));
    add(new JScrollPane(list1));
    add(new JScrollPane(list2));
  }
  private ImageList list1;
  private ImageList list2;
  private static final int DEFAULT_WIDTH = 600;
  private static final int DEFAULT_HEIGHT = 500;
}
class ImageList extends JList {
  public ImageList(File[] imageFiles) {
    DefaultListModel model = new DefaultListModel();
    for (File f : imageFiles)
      model.addElement(new ImageIcon(f.getPath()));
    setModel(model);
    setVisibleRowCount(0);
    setLayoutOrientation(JList.HORIZONTAL_WRAP);
    setDragEnabled(true);
    setDropMode(DropMode.ON_OR_INSERT);
    setTransferHandler(new ImageListTransferHandler());
  }
}
class ImageListTransferHandler extends TransferHandler {
  // Support for drag
  public int getSourceActions(JComponent source) {
    return COPY_OR_MOVE;
  }
  protected Transferable createTransferable(JComponent source) {
    JList list = (JList) source;
    int index = list.getSelectedIndex();
    if (index < 0)
      return null;
    ImageIcon icon = (ImageIcon) list.getModel().getElementAt(index);
    return new ImageTransferable(icon.getImage());
  }
  protected void exportDone(JComponent source, Transferable data, int action) {
    if (action == MOVE) {
      JList list = (JList) source;
      int index = list.getSelectedIndex();
      if (index < 0)
        return;
      DefaultListModel model = (DefaultListModel) list.getModel();
      model.remove(index);
    }
  }
  // Support for drop
  public boolean canImport(TransferSupport support) {
    if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
      if (support.getUserDropAction() == MOVE)
        support.setDropAction(COPY);
      return true;
    } else
      return support.isDataFlavorSupported(DataFlavor.imageFlavor);
  }
  public boolean importData(TransferSupport support) {
    JList list = (JList) support.getComponent();
    DefaultListModel model = (DefaultListModel) list.getModel();
    Transferable transferable = support.getTransferable();
    List flavors = Arrays.asList(transferable.getTransferDataFlavors());
    List images = new ArrayList();
    try {
      if (flavors.contains(DataFlavor.javaFileListFlavor)) {
        List fileList = (List) transferable
            .getTransferData(DataFlavor.javaFileListFlavor);
        for (File f : fileList) {
          try {
            images.add(ImageIO.read(f));
          } catch (IOException ex) {
            // couldn't read image--skip
          }
        }
      } else if (flavors.contains(DataFlavor.imageFlavor)) {
        images.add((Image) transferable.getTransferData(DataFlavor.imageFlavor));
      }
      int index;
      if (support.isDrop()) {
        JList.DropLocation location = (JList.DropLocation) support.getDropLocation();
        index = location.getIndex();
        if (!location.isInsert())
          model.remove(index); // replace location
      } else
        index = model.size();
      for (Image image : images) {
        model.add(index, new ImageIcon(image));
        index++;
      }
      return true;
    } catch (IOException ex) {
      return false;
    } catch (UnsupportedFlavorException ex) {
      return false;
    }
  }
}
/*
 * This program is a part of the companion code for Core Java 8th ed.
 * (http://horstmann.com/corejava)
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see .
 */
/**
 * This class is a wrapper for the data transfer of image objects.
 */
class ImageTransferable implements Transferable {
  /**
   * Constructs the selection.
   * 
   * @param image
   *          an image
   */
  public ImageTransferable(Image image) {
    theImage = image;
  }
  public DataFlavor[] getTransferDataFlavors() {
    return new DataFlavor[] { DataFlavor.imageFlavor };
  }
  public boolean isDataFlavorSupported(DataFlavor flavor) {
    return flavor.equals(DataFlavor.imageFlavor);
  }
  public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
    if (flavor.equals(DataFlavor.imageFlavor)) {
      return theImage;
    } else {
      throw new UnsupportedFlavorException(flavor);
    }
  }
  private Image theImage;
}