java : Drag & Drop sur un JTable

Le code

import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.Vector;
 
import javax.swing.DropMode;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.TransferHandler;
import javax.swing.table.DefaultTableModel;
 
/**
 * @author Grummfy 2009
 * Ce code est sous licence LGPL v2
 * Ce code est pourri et DOIT être améliorer mais le but est l'exemple ...
 */
public class DragTableExample
{
	//
	// static
	//
 
	public static void main(String... args)
	{
		DragTableExample dte = new DragTableExample();
 
		JFrame jf = new JFrame();
		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jf.add(new JScrollPane(dte.getJTable()));
		jf.pack();
		jf.setVisible(true);
	}
 
	//
	// la classe
	//
	private JTable jTable;
	private int colCount = 11;
	private int rowCount = 10;
 
	public DragTableExample()
	{
		JTextField jtf = new JTextField("Drag This!");
		jtf.setDragEnabled(true);
 
		// rempli le jtable
		this.jTable = new JTable(new MyDefTableModel(this.mkNames(), this.mkData()));
 
		// permet de faire du drag (éjà implémenté par défaut dans jtable
		this.jTable.setDragEnabled(true);
 
		// on ajoute notre gestionnaire de clique sur la premièere collone (#0)
		this.jTable.addMouseListener(new MouseListener()
		{
			public void mouseClicked(MouseEvent e){}
			public void mouseEntered(MouseEvent e){}
			public void mouseExited(MouseEvent e){}
			public void mouseReleased(MouseEvent e){}
 
			public void mousePressed(MouseEvent e)
			{
				Point p = e.getPoint ();
				int colonne = jTable.columnAtPoint(p);
				int ligne = jTable.rowAtPoint(p);
				if (colonne == 0)
				{
					// sélection de la ligne
					jTable.getSelectionModel().setSelectionInterval(ligne, ligne);
 
					// lancement du drag
					TransferHandler handler = jTable.getTransferHandler();
					handler.exportAsDrag(jTable, e, TransferHandler.MOVE);
				}
			}
		});
 
		//Le mode de drop est en mode d'isnertion de ligne => si ond épose cela ajoute une ligne!
		this.jTable.setDropMode(DropMode.INSERT_ROWS);
 
		this.jTable.setTransferHandler(new MyTransferHandler());
	}
 
	public JTable getJTable()
	{
		return this.jTable;
	}
 
	private Vector mkNames()
	{
		Vector vNames = new Vector(this.colCount + 1);
 
		vNames.add("Col of drag");
 
		for (int colonne = 1; colonne < this.colCount; colonne++)
			vNames.add("Col #" + String.valueOf(colonne));
		return vNames;
	}
 
 private Vector<Vector<Object>> mkData()
 {
 Vector<Vector<Object>> vData = new Vector<Vector<Object>>(this.rowCount);
 
 for (int ligne = 0; ligne < this.rowCount; ligne++)
 {
 Vector<Object> vCol = new Vector<Object>(this.colCount);
 
 for(int colonne = 0; colonne < this.colCount; colonne++)
 {
 if (colonne == 0)
 vCol.add(new ImageIcon("images/drag_me_green.png"));
 else
 // colonnes "normal"
 vCol.add("(" + String.valueOf(ligne) + "," + String.valueOf(colonne) + ")");
 }
 vData.add(vCol);
 }
 return vData;
 }
 
 //
 // Inner class - classe interne
 //
 
 /**
 * La classe qui permet de dire si on peux faire l'import et l'export et surtout comment ...
 */
 private class MyTransferHandler extends TransferHandler
 {
 public boolean canImport(TransferHandler.TransferSupport support)
 {
 return true;
 }
 
 public boolean importData(TransferHandler.TransferSupport info)
 {
 JTable.DropLocation dropLocation = (JTable.DropLocation) info.getDropLocation();
 if (dropLocation.isInsertRow())
 {
 MyDefTableModel m = (MyDefTableModel)jTable.getModel();
 
 if (info.getTransferable().isDataFlavorSupported(JTableRowTransferable.DATA_ROW))
 {
 try
 {
 Object[] myObject = (Object[]) info.getTransferable().getTransferData(JTableRowTransferable.DATA_ROW);
 int rowIdSrc = (Integer) myObject[0];
 Object[] data = (Object[]) ((Vector<Object>)myObject[1]).toArray();
 m.removeRow(rowIdSrc);
 
 int locRow = dropLocation.getRow();
 // TODO recheck lalgo en attendant ...
 locRow = (locRow >= jTable.getRowCount())?(locRow - 1):locRow;
 m.insertRow(locRow, data);
 return true;
 }
 catch (Exception e)
 {
 e.printStackTrace();
 }
 }
 }
 return false;
 }
 
 protected Transferable createTransferable(JComponent cp)
 {
 JTable tab = (JTable) cp;
 int row = tab.getSelectedRow();
 MyDefTableModel m = (MyDefTableModel) tab.getModel();
 int colCount = m.getColumnCount();
 Vector<Object> v = new Vector<Object>(colCount);
 for (int i = 0; i < colCount; i++)
 v.add(m.getValueAt(row, i));
 
 return new JTableRowTransferable(v, row);
 }
 
 public int getSourceActions(JComponent cp)
 {
 return MOVE;
 }
 }
}
 
/**
 * Modèle du JTable utilisé, basé sur DefaultTable mais permettant en plsu d'utiliser les render
 */
class MyDefTableModel extends DefaultTableModel
{
 public MyDefTableModel(Vector names, Vector data)
 {
 super(data, names);
 }
 
 /**
 * Permet d'utilsier les "render" déjà implémenté (type primitif, Boolean (=> checkbox), ImageIcon)
 */
 public Class<?> getColumnClass(int columnIndex)
 {
 if (this.getRowCount() > 0)
 {
 return super.getValueAt(0, columnIndex).getClass();
 }
 return super.getColumnClass(columnIndex);
 }
}
 
/**
 * Classe qui "transporte" l'info durant le drag & drop
 */
class JTableRowTransferable implements Transferable
{
 public static final DataFlavor DATA_ROW = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + Object.class.getName(), null);
 
 private Vector<Object> value;
 
 private int row;
 
 public JTableRowTransferable(Vector<Object> v, int rowId)
 {
 this.value = v;
 this.row = rowId;
 }
 
 public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
 {
 if (flavor == null)
 {
 throw new IOException();
 }
 else if (flavor.equals(DATA_ROW))
 {
 Object[] o = {this.row, this.value};
 return o;
 }
 else if (flavor.equals(DataFlavor.stringFlavor))
 {
 return this.value.toString();
 }
 else
 {
 throw new UnsupportedFlavorException(flavor);
 }
 }
 
 public DataFlavor[] getTransferDataFlavors()
 {
 return new DataFlavor[] { DATA_ROW, DataFlavor.stringFlavor };
 }
 
 public boolean isDataFlavorSupported(DataFlavor flavor)
 {
 return (flavor.equals(DATA_ROW) || flavor.equals(DataFlavor.stringFlavor));
 }
}

Similar Posts:

    None Found