//package dnd;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.IOException;
public class DragDrop_JTable extends JFrame {
public DragDrop_JTable() {
setTitle("Drag and Drop JTable");
JTextArea tips = new JTextArea("1. Selektiere eine Zeile in Tabelle A. " +
"Drücke die Zeile noch einmal und ziehe. \n " +
"Während du den Mauszeiger über die Tabelle B ziehst, wird die Zeile markiert die gerade unter dem Zeiger ist " +
"— die neuen Daten werden unterhalb der selektierten Zeile eingefügt. \n " +
"Lass die Zeile auf die Tabelle B fallen. Beachte, daß die Zeile von der Tabelle A entfernt wurde, " +
"und jetzt in Tabelle B erscheint. \n" +
"2. Selektiere zwei Zeilen in der Tabelle A und lass sie auf die Tabelle B fallen. " +
"Jetzt sind zwei neue Zeilen in der Tabelle B. ");
tips.setEditable(false);
tips.setBackground(new Color(255,255,204));
tips.setBorder(new LineBorder(Color.orange,5));
getContentPane().add(tips,BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(2,1));
panel.add(createTable("Tabelle A"));
panel.add(createTable("Tabelle B"));
getContentPane().add(panel,BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
}
private JPanel createTable(String tableId) {
DefaultTableModel model = new DefaultTableModel();
model.addColumn("Spalte 0");
model.addColumn("Spalte 1");
model.addColumn("Spalte 2");
model.addColumn("Spalte 3");
model.addRow(new String[]{tableId+" 00", tableId+" 01", tableId+" 02", tableId+" 03"});
model.addRow(new String[]{tableId+" 10", tableId+" 11", tableId+" 12", tableId+" 13"});
model.addRow(new String[]{tableId+" 20", tableId+" 21", tableId+" 22", tableId+" 23"});
model.addRow(new String[]{tableId+" 30", tableId+" 31", tableId+" 32", tableId+" 33"});
model.addRow(new String[]{tableId+" 40", tableId+" 41", tableId+" 42", tableId+" 43"});
model.addRow(new String[]{tableId+" 50", tableId+" 51", tableId+" 52", tableId+" 53"});
model.addRow(new String[]{tableId+" 60", tableId+" 61", tableId+" 62", tableId+" 63"});
model.addRow(new String[]{tableId+" 70", tableId+" 71", tableId+" 72", tableId+" 73"});
JTable table = new JTable(model){
//Diese Methode ermöglicht drop auf leere JTable:
public boolean getScrollableTracksViewportHeight() {
Container viewport = getParent();
if (!(viewport instanceof JViewport)) return false;
return getPreferredSize().height < viewport.getHeight();
}
};
table.getTableHeader().setReorderingAllowed(false);
table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setPreferredSize(new Dimension(400,100));
table.setDragEnabled(true);
table.setTransferHandler(new TableTransferHandler());
JPanel panel = new JPanel();
panel.add(scrollPane);
panel.setBorder(BorderFactory.createTitledBorder(tableId));
return panel;
}
public static void main(String[] args) {
new DragDrop_JTable().setVisible(true);
}
abstract class StringTransferHandler extends TransferHandler {
protected abstract String exportString(JComponent c);
protected abstract void importString(JComponent c, String str);
protected abstract void cleanup(JComponent c, boolean remove);
protected Transferable createTransferable(JComponent c) {
return new StringSelection(exportString(c));
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean importData(JComponent c, Transferable t) {
if (canImport(c, t.getTransferDataFlavors())) {
try {
String str = (String)t.getTransferData(DataFlavor.stringFlavor);
importString(c, str);
return true;
} catch (UnsupportedFlavorException ufe) {
} catch (IOException ioe) {
}
}
return false;
}
protected void exportDone(JComponent c, Transferable data, int action) {
cleanup(c, action == MOVE);
}
public boolean canImport(JComponent c, DataFlavor[] flavors) {
for (int ndx = 0; ndx < flavors.length; ndx++) {
if (DataFlavor.stringFlavor.equals(flavors[ndx])) {
return true;
}
}
return false;
}
}
class TableTransferHandler extends StringTransferHandler {
public JTable target;
public int[] rows = null;
public int addIndex = -1; //Position an der die Zeilen eingefügt werden
public int addCount = 0; //Anzahl der eingefügten Zeilen.
protected String exportString(JComponent c) {
JTable table = (JTable)c;
rows = table.getSelectedRows();
int colCount = table.getColumnCount();
StringBuffer buff = new StringBuffer();
for (int ndx = 0; ndx < rows.length; ndx++) {
for (int j = 0; j < colCount; j++) {
Object val = table.getValueAt(rows[ndx], j);
buff.append(val == null ? "" : val.toString());
if (j != colCount - 1) {
buff.append(",");
}
}
if (ndx != rows.length - 1) {
buff.append("\n");
}
}
return buff.toString();
}
protected void importString(JComponent c, String str) {
target = (JTable)c;
DefaultTableModel model = (DefaultTableModel)target.getModel();
int index = target.getSelectedRow();
//Der Benutzer wird daran gehindert die Daten auf sich selbst fallen zu lassen.
//Zum Beispiel, wenn der Benutzer die Zeilen #4,#5,#6 und #7 verschiebt und
//versucht sie unterhalb der Zeile #5 einzufügen, wäre es
//problematisch die ursprünglichen Zeilen zu entfernen.
//Daher wird dies nicht erlaubt.
if (rows != null && index >= rows[0] - 1 &&
index <= rows[rows.length - 1]) {
rows = null;
return;
}
int max = model.getRowCount();
if (index < 0) {
index = max;
} else {
index++;
if (index > max) {
index = max;
}
}
addIndex = index;
String[] values = str.split("\n");
addCount = values.length;
int colCount = target.getColumnCount();
for (int ndx = 0; ndx < values.length ; ndx++) {
model.insertRow(index++, values[ndx].split(","));
}
//Wenn wir Zeilen innerhalb derselben Tabelle verschieben, müssen
//wir die Zeilen entsprechend anpassen, da diejenigen
//hinter dem Einfügungspunkt verschoben werden.
if (rows!= null && addCount > 0) {
for (int ndx = 0; ndx < rows.length; ndx++) {
if (rows[ndx] > addIndex) {
rows[ndx] += addCount;
}
}
}
}
protected void cleanup(JComponent c, boolean remove) {
JTable source = (JTable)c;
if (remove && rows != null) {
DefaultTableModel model =
(DefaultTableModel)source.getModel();
for (int ndx = rows.length - 1; ndx >= 0; ndx--) {
model.removeRow(rows[ndx]);
}
}
rows = null;
addCount = 0;
addIndex = -1;
}
}
}