Hallo
Ich implementiere gerade ein Drag'n'Drop auf einem JTable. Dabei sollen allerdings nur best. Zellen auf best. andere Zellen gedroppt werden können. Letzteres ist nicht so das Problem, weil ich in canImport() herausfinden kann um welches target es sich handelt (da krieg ich vom TransferSupport die Zelle).
Allerdings muss ich auch die source kennen, um entscheiden zu können, ob der Drag unterstützt wird.
Hier die Lösung, die ich mir überlegt habe, allerdings funktioniert es nicht zuverlässig, weil rowAtPoint(Point p) und rolumnAtPoint(Point p) zu spät aufgerufen zu werden scheinen.
Also grundsätzlich geht es um folgendes: Ich will nur von best. Zellen aus den Drag starten, wie geht das?
[Java]
import java.awt.Point;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
public class Test {
private static void createGui() {
JFrame jf = new JFrame("Test");
jf.setSize(400, 200);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
Integer[][] data = {{1,2,3},{4,5,6},{7,8,9}};
JTable jt = new JTable(data, new String[] {"A", "B", "C"});
jt.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jt.setDragEnabled(true);
jt.setDropMode(DropMode.ON);
jt.setTransferHandler(new TransferHandler() {
public int getSourceActions(JComponent c) {
JTable table = (JTable) c;
Point p = table.getMousePosition();
int row = table.rowAtPoint(p);
int column = table.columnAtPoint(p);
// example check, if source is allowed (in this case only even cells)
if ((Integer) table.getValueAt(row, column) % 2 == 0)
return LINK;
return NONE;
}
protected Transferable createTransferable(JComponent c) {
return new StringSelection(null);
}
public boolean canImport(TransferSupport supp) {
return true;
}
public boolean importData(TransferSupport supp) {
return true;
}
});
jf.getContentPane().add(jt);
jf.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGui();
}
});
}
}
[/Java]
Wenn ihr das ausprobiert, seht ihr, dass es manchmal geht und manchmal nicht (da scheint Point null zu sein). D.h. ich krieg einfach nicht immer die richtige Zelle zurück. Oder ist der Ansatz generell falsch?
Vielen Dank für eure Hilfe.
lg,
uli
Ich implementiere gerade ein Drag'n'Drop auf einem JTable. Dabei sollen allerdings nur best. Zellen auf best. andere Zellen gedroppt werden können. Letzteres ist nicht so das Problem, weil ich in canImport() herausfinden kann um welches target es sich handelt (da krieg ich vom TransferSupport die Zelle).
Allerdings muss ich auch die source kennen, um entscheiden zu können, ob der Drag unterstützt wird.
Hier die Lösung, die ich mir überlegt habe, allerdings funktioniert es nicht zuverlässig, weil rowAtPoint(Point p) und rolumnAtPoint(Point p) zu spät aufgerufen zu werden scheinen.
Also grundsätzlich geht es um folgendes: Ich will nur von best. Zellen aus den Drag starten, wie geht das?
[Java]
import java.awt.Point;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
public class Test {
private static void createGui() {
JFrame jf = new JFrame("Test");
jf.setSize(400, 200);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
Integer[][] data = {{1,2,3},{4,5,6},{7,8,9}};
JTable jt = new JTable(data, new String[] {"A", "B", "C"});
jt.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jt.setDragEnabled(true);
jt.setDropMode(DropMode.ON);
jt.setTransferHandler(new TransferHandler() {
public int getSourceActions(JComponent c) {
JTable table = (JTable) c;
Point p = table.getMousePosition();
int row = table.rowAtPoint(p);
int column = table.columnAtPoint(p);
// example check, if source is allowed (in this case only even cells)
if ((Integer) table.getValueAt(row, column) % 2 == 0)
return LINK;
return NONE;
}
protected Transferable createTransferable(JComponent c) {
return new StringSelection(null);
}
public boolean canImport(TransferSupport supp) {
return true;
}
public boolean importData(TransferSupport supp) {
return true;
}
});
jf.getContentPane().add(jt);
jf.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGui();
}
});
}
}
[/Java]
Wenn ihr das ausprobiert, seht ihr, dass es manchmal geht und manchmal nicht (da scheint Point null zu sein). D.h. ich krieg einfach nicht immer die richtige Zelle zurück. Oder ist der Ansatz generell falsch?
Vielen Dank für eure Hilfe.
lg,
uli
Zuletzt bearbeitet: