Drag N Drop for some JTable cells but not all.

Hi,

I am using Drag N Drop with two JTables. I need to disable the drop for some of the table cells. It seems that either all the cells or none of the cells can be drop targets. Does anybody know how I can change this? Is there some flag I can set? I triedsetDragEnabled(false) in my TableRenderer but that didn't help.

Thanks in advance.

[365 byte] By [Schneckea] at [2007-11-26 17:24:30]
# 1
[url http://java.sun.com/docs/books/tutorial/uiswing/dnd/intro.html]Drag and Drop and Data Transfer[/url]
camickra at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 2

Thanks for the reply.

I have used the TransferHandler from the link above. I tried to control the cells drop attributes using a mouselistener in my table. The only problem is that the mouse events seem to be only activated for normal mouse behaviour and not when I drag from on table into the other table and am pressing the shift button.

How can I make the mouse listen to movements when the shift button is activated?

Thanks for any help.

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 3

Hi,

I have really spent lots of time trying to track drag-able-mouse-motion between my two JTables so that the transfer handler knows which cells he can drop to. But I can't seem to get any mouse information once the mouse leaves one table and enters the other table. Is this normal? Can the drag action only be tracked within the table where the action originated? Does anyone have any experience doing something like this, either with the mouse actions or making some JTable cells un-drop-able. Any help would be great at the moment.

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 4
Added a few more duke-dollars as I am really stuck here. 羘y tips or hints will help, evevn critics if I am posting incorrect :-(Thanks
Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 5

> Added a few more duke-dollars as I am really stuck

> here. 羘y tips or hints will help, evevn critics if I

> am posting incorrect :-(

> Thanks

I haven't done much with Drag N Drop. But I would suggest you start with a simple example for the tutorial and work your way up to your code now. (Or the reverse).

Also, if you are having a unique issue, then post a working example (of only the relavent code) so we can run it and see what you are talking about.

zadoka at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 6
You can find an example [url http://www.java2s.com/Code/Java/Swing-JFC/ExtendedDnDDragandDropDemo.htm]here[/url]
Rodney_McKaya at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 7

Ok, I have taken the example in the link above and created the situation that is causing my problems. The example has a Table / List / TextArea. You can drag and drop strings whereever you want. I need to block dropping strings on the 2nd row of the table.

So I add my code here:

public boolean canImport(JComponent c, DataFlavor[] flavors) {

if(c instanceof MyTable){

MyTable table = (MyTable)c;

if(!table.IsRowEditable())

return false;

else

return true;

}

for (int i = 0; i < flavors.length; i++) {

if (DataFlavor.stringFlavor.equals(flavors)) {

return true;

}

}

return false;

}

}

This piece of code should be controlled by the mouse movement. So if I drag from the List to the Table, then I expect the cursor to show a blocked signal over row 2 in the table. However, if the Drag action started in the List area then I get no mouse activity in the Table area. Is this understandable ? Is this normal? The full code is below. I only seem to be able to track the mouse when the Drag started within the table area. Thanks for any input.

/* From http://java.sun.com/docs/books/tutorial/index.html */

/*

* ExtendedDnDDemo.java is a 1.4 example that requires the following files:

* StringTransferHandler.java ListTransferHandler.java TableTransferHandler.java

*/

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.datatransfer.DataFlavor;

import java.awt.datatransfer.StringSelection;

import java.awt.datatransfer.Transferable;

import java.awt.datatransfer.UnsupportedFlavorException;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.io.IOException;

import javax.swing.BorderFactory;

import javax.swing.DefaultListModel;

import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.JList;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.JTextArea;

import javax.swing.ListSelectionModel;

import javax.swing.TransferHandler;

import javax.swing.table.DefaultTableModel;

import java.awt.event.MouseEvent;

public class ExtendedDnDDemo extends JPanel implements MouseListener,MouseMotionListener{

MyTable table;

public ExtendedDnDDemo() {

super(new GridLayout(3, 1));

add(createArea());

add(createList());

add(createTable());

addMouseListener(this);

addMouseMotionListener(this);

}

private JPanel createList() {

DefaultListModel listModel = new DefaultListModel();

listModel.addElement("List 0");

listModel.addElement("List 1");

listModel.addElement("List 2");

listModel.addElement("List 3");

listModel.addElement("List 4");

listModel.addElement("List 5");

listModel.addElement("List 6");

listModel.addElement("List 7");

listModel.addElement("List 8");

JList list = new JList(listModel);

list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

JScrollPane scrollPane = new JScrollPane(list);

scrollPane.setPreferredSize(new Dimension(400, 100));

list.setDragEnabled(true);

list.setTransferHandler(new ListTransferHandler());

JPanel panel = new JPanel(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("List"));

addMouseListener(this);

addMouseMotionListener(this);

return panel;

}

private JPanel createArea() {

String text = "This is the text that I want to show.";

JTextArea area = new JTextArea();

area.setText(text);

area.setDragEnabled(true);

JScrollPane scrollPane = new JScrollPane(area);

scrollPane.setPreferredSize(new Dimension(400, 100));

JPanel panel = new JPanel(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("Text Area"));

addMouseListener(this);

addMouseMotionListener(this);

return panel;

}

private JPanel createTable() {

DefaultTableModel model = new DefaultTableModel();

model.addColumn("Column 0");

model.addColumn("Column 1");

model.addColumn("Column 2");

model.addColumn("Column 3");

model.addRow(new String[] { "Table 00", "Table 01", "Table 02",

"Table 03" });

model.addRow(new String[] { "Table 10", "Table 11", "Table 12",

"Table 13" });

model.addRow(new String[] { "Table 20", "Table 21", "Table 22",

"Table 23" });

model.addRow(new String[] { "Table 30", "Table 31", "Table 32",

"Table 33" });

table = new MyTable(model);

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(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("Table"));

addMouseListener(this);

addMouseMotionListener(this);

table.addMouseListener(table);

table.addMouseMotionListener(table);

return panel;

}

public void mouseMoved(MouseEvent e){

table.SetXcoYco( e.getX(), e.getY());

}

public void mouseDragged(MouseEvent e){

table.SetXcoYco( e.getX(), e.getY());

}

public void mouseClicked(MouseEvent e){

}

public void mouseEntered(MouseEvent e){

}

public void mouseExited(MouseEvent e){

}

public void mousePressed(MouseEvent e){

}

public void mouseReleased(MouseEvent e){

}

/**

* Create the GUI and show it. For thread safety, this method should be

* invoked from the event-dispatching thread.

*/

private static void createAndShowGUI() {

//Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

//Create and set up the window.

JFrame frame = new JFrame("ExtendedDnDDemo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//Create and set up the content pane.

JComponent newContentPane = new ExtendedDnDDemo();

newContentPane.setOpaque(true); //content panes must be opaque

frame.setContentPane(newContentPane);

//Display the window.

frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

//Schedule a job for the event-dispatching thread:

//creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

class MyTable extends JTable implements MouseListener,MouseMotionListener{

/**

*

*/

private static final long serialVersionUID = 1L;

int xco = 0, yco = 0;

public MyTable(DefaultTableModel model){

super.setModel(model);

}

boolean IsRowEditable(){

Point point = new Point(xco,yco);

int row = rowAtPoint(point);

if(row != 2)

return true;

else

return false;

}

void SetXcoYco(int x, int y){

xco = x;

yco = y;

}

public void mouseMoved(MouseEvent e){

SetXcoYco( e.getX(), e.getY());

}

public void mouseDragged(MouseEvent e){

SetXcoYco( e.getX(), e.getY());

}

public void mouseClicked(MouseEvent e){

}

public void mouseEntered(MouseEvent e){

}

public void mouseExited(MouseEvent e){

}

public void mousePressed(MouseEvent e){

}

public void mouseReleased(MouseEvent e){

}

}

/*

* ListTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

class ListTransferHandler extends StringTransferHandler {

private int[] indices = null;

private int addIndex = -1; //Location where items were added

private int addCount = 0; //Number of items added.

//Bundle up the selected items in the list

//as a single string, for export.

protected String exportString(JComponent c) {

JList list = (JList) c;

indices = list.getSelectedIndices();

Object[] values = list.getSelectedValues();

StringBuffer buff = new StringBuffer();

for (int i = 0; i < values.length; i++) {

Object val = values;

buff.append(val == null ? "" : val.toString());

if (i != values.length - 1) {

buff.append("\n");

}

}

return buff.toString();

}

//Take the incoming string and wherever there is a

//newline, break it into a separate item in the list.

protected void importString(JComponent c, String str) {

JList target = (JList) c;

DefaultListModel listModel = (DefaultListModel) target.getModel();

int index = target.getSelectedIndex();

//Prevent the user from dropping data back on itself.

//For example, if the user is moving items #4,#5,#6 and #7 and

//attempts to insert the items after item #5, this would

//be problematic when removing the original items.

//So this is not allowed.

if (indices != null && index >= indices[0] - 1

&& index <= indices[indices.length - 1]) {

indices = null;

return;

}

int max = listModel.getSize();

if (index < 0) {

index = max;

} else {

index++;

if (index > max) {

index = max;

}

}

addIndex = index;

String[] values = str.split("\n");

addCount = values.length;

for (int i = 0; i < values.length; i++) {

listModel.add(index++, values);

}

}

//If the remove argument is true, the drop has been

//successful and it's time to remove the selected items

//from the list. If the remove argument is false, it

//was a Copy operation and the original list is left

//intact.

protected void cleanup(JComponent c, boolean remove) {

if (remove && indices != null) {

JList source = (JList) c;

DefaultListModel model = (DefaultListModel) source.getModel();

//If we are moving items around in the same list, we

//need to adjust the indices accordingly, since those

//after the insertion point have moved.

if (addCount > 0) {

for (int i = 0; i < indices.length; i++) {

if (indices > addIndex) {

indices += addCount;

}

}

}

for (int i = indices.length - 1; i >= 0; i--) {

model.remove(indices);

}

}

indices = null;

addCount = 0;

addIndex = -1;

}

}

/*

* StringTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

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) {

/////// MY CODE TO SET A ROW NON DROPABLE /////////////

if(c instanceof MyTable){

MyTable table = (MyTable)c;

if(!table.IsRowEditable())

return false;

else

return true;

}

/////// MY CODE TO SET A ROW NON DROPABLE /////////////

for (int i = 0; i < flavors.length; i++) {

if (DataFlavor.stringFlavor.equals(flavors)) {

return true;

}

}

return false;

}

}

/*

* TableTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

class TableTransferHandler extends StringTransferHandler {

private int[] rows = null;

private int addIndex = -1; //Location where items were added

private int addCount = 0; //Number of items added.

protected String exportString(JComponent c) {

JTable table = (JTable) c;

rows = table.getSelectedRows();

int colCount = table.getColumnCount();

StringBuffer buff = new StringBuffer();

for (int i = 0; i < rows.length; i++) {

for (int j = 0; j < colCount; j++) {

Object val = table.getValueAt(rows, j);

buff.append(val == null ? "" : val.toString());

if (j != colCount - 1) {

buff.append(",");

}

}

if (i != rows.length - 1) {

buff.append("\n");

}

}

return buff.toString();

}

protected void importString(JComponent c, String str) {

JTable target = (JTable) c;

DefaultTableModel model = (DefaultTableModel) target.getModel();

int index = target.getSelectedRow();

//Prevent the user from dropping data back on itself.

//For example, if the user is moving rows #4,#5,#6 and #7 and

//attempts to insert the rows after row #5, this would

//be problematic when removing the original rows.

//So this is not allowed.

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 i = 0; i < values.length && i < colCount; i++) {

model.insertRow(index++, values.split(","));

}

}

protected void cleanup(JComponent c, boolean remove) {

JTable source = (JTable) c;

if (remove && rows != null) {

DefaultTableModel model = (DefaultTableModel) source.getModel();

//If we are moving items around in the same table, we

//need to adjust the rows accordingly, since those

//after the insertion point have moved.

if (addCount > 0) {

for (int i = 0; i < rows.length; i++) {

if (rows > addIndex) {

rows += addCount;

}

}

}

for (int i = rows.length - 1; i >= 0; i--) {

model.removeRow(rows);

}

}

rows = null;

addCount = 0;

addIndex = -1;

}

}

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 8
> Ok, I have taken the example in the link aboveThats the example from the tutorial link I gave you hours ago.Use the [url http://forum.java.sun.com/help.jspa?sec=formatting]Code Formatting Tags[/url] when posting code.
camickra at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 9

Sorry about the formatting, I didn't know about the tags.

And that is the example you gave me earlier, but now it has MouseListners and the table section has been modified. I added a class called MyTable and a function called IsRowEditable() which is supposed to indicate if data should be dropped on a table row or not. In the example row 2 should not accept any data.

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 10

Ok, I have redone the example for Drag and Drop, where the coordinates are now wrote to the text area.

MouseMove coordinates look like this : M123 - 122

MouseDrag coordinates look like this : D123 - 122

With this output it is easy to see that there is not mouse information when data is actually getting dragged. My goal for this example is to make row 2 in the table non-dropable. I have added the following code to the TransferHandler to try and achieve this goal but without the mouse tracking during the drag I am really stuck.

public boolean canImport(JComponent c, DataFlavor[] flavors) {

// ///// MY CODE TO SET A ROW NON DROPABLE /////////////

if (c instanceof MyTable) {

MyTable table = (MyTable) c;

if (!table.IsRowEditable())

return false;

else

return true;

}

// ///// MY CODE TO SET A ROW NON DROPABLE /////////////

for (int i = 0; i < flavors.length; i++) {

if (DataFlavor.stringFlavor.equals(flavors)) {

return true;

}

}

return false;

}

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

The full code is here. An help is much appreciated.

/* From http://java.sun.com/docs/books/tutorial/index.html */

/*

* ExtendedDnDDemo.java is a 1.4 example that requires the following files:

* StringTransferHandler.java ListTransferHandler.java TableTransferHandler.java

*/

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.GridLayout;

import java.awt.Point;

import java.awt.datatransfer.DataFlavor;

import java.awt.datatransfer.StringSelection;

import java.awt.datatransfer.Transferable;

import java.awt.datatransfer.UnsupportedFlavorException;

import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener;

import java.io.IOException;

import javax.swing.BorderFactory;

import javax.swing.DefaultListModel;

import javax.swing.JComponent;

import javax.swing.JFrame;

import javax.swing.JList;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

import javax.swing.JTextArea;

import javax.swing.ListSelectionModel;

import javax.swing.TransferHandler;

import javax.swing.table.DefaultTableModel;

import java.awt.event.MouseEvent;

public class ExtendedDnDDemo extends JPanel implements MouseListener,

MouseMotionListener {

/**

*

*/

private static final long serialVersionUID = 1;

MyTable my_table;

MyList my_list;

JTextArea area;

public ExtendedDnDDemo() {

super(new GridLayout(3, 1));

add(createArea());

add(createTable());

add(createList());

addMouseListener(this);

addMouseMotionListener(this);

my_table.addMouseListener(this);

my_table.addMouseMotionListener(this);

my_list.addMouseListener(this);

my_list.addMouseMotionListener(this);

}

private JPanel createTable() {

DefaultTableModel model = new DefaultTableModel();

model.addColumn("Column 0");

model.addColumn("Column 1");

model.addColumn("Column 2");

model.addColumn("Column 3");

model.addRow(new String[] { "Table 00", "Table 01", "Table 02",

"Table 03" });

model.addRow(new String[] { "Table 10", "Table 11", "Table 12",

"Table 13" });

model.addRow(new String[] { "Table 20", "Table 21", "Table 22",

"Table 23" });

model.addRow(new String[] { "Table 30", "Table 31", "Table 32",

"Table 33" });

my_table = new MyTable(model, area);

my_table.getTableHeader().setReorderingAllowed(true);

my_table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

JScrollPane scrollPane = new JScrollPane(my_table);

scrollPane.setPreferredSize(new Dimension(400, 100));

my_table.setDragEnabled(true);

my_table.setTransferHandler(new TableTransferHandler());

JPanel panel = new JPanel(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("Table"));

return panel;

}

private JPanel createList() {

DefaultListModel listModel = new DefaultListModel();

listModel.addElement("List 0");

listModel.addElement("List 1");

listModel.addElement("List 2");

listModel.addElement("List 3");

listModel.addElement("List 4");

listModel.addElement("List 5");

listModel.addElement("List 6");

listModel.addElement("List 7");

listModel.addElement("List 8");

my_list = new MyList(listModel, my_table, area);

my_list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);

JScrollPane scrollPane = new JScrollPane(my_list);

scrollPane.setPreferredSize(new Dimension(400, 100));

my_list.setDragEnabled(true);

my_list.setTransferHandler(new ListTransferHandler());

JPanel panel = new JPanel(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("List"));

addMouseListener(this);

addMouseMotionListener(this);

return panel;

}

private JPanel createArea() {

String text = "This is the text that I want to show.";

area = new JTextArea();

area.setText(text);

area.setDragEnabled(true);

JScrollPane scrollPane = new JScrollPane(area);

scrollPane.setPreferredSize(new Dimension(400, 100));

JPanel panel = new JPanel(new BorderLayout());

panel.add(scrollPane, BorderLayout.CENTER);

panel.setBorder(BorderFactory.createTitledBorder("Text Area"));

addMouseListener(this);

addMouseMotionListener(this);

return panel;

}

public void mouseMoved(MouseEvent e) {

my_table.SetXcoYco(e.getX(), e.getY());

area.append("M: "+Integer.toString(e.getX())+" - "+Integer.toString(e.getY()));

}

public void mouseDragged(MouseEvent e) {

my_table.SetXcoYco(e.getX(), e.getY());

area.append("\nD: "+Integer.toString(e.getX())+" - "+Integer.toString(e.getY()));

}

public void mouseClicked(MouseEvent e) {

}

public void mouseEntered(MouseEvent e) {

}

public void mouseExited(MouseEvent e) {

}

public void mousePressed(MouseEvent e) {

area.append("\n");

}

public void mouseReleased(MouseEvent e) {

area.append("\n");

}

/**

* Create the GUI and show it. For thread safety, this method should be

* invoked from the event-dispatching thread.

*/

private static void createAndShowGUI() {

// Make sure we have nice window decorations.

JFrame.setDefaultLookAndFeelDecorated(true);

// Create and set up the window.

JFrame frame = new JFrame("ExtendedDnDDemo");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Create and set up the content pane.

JComponent newContentPane = new ExtendedDnDDemo();

newContentPane.setOpaque(true); // content panes must be opaque

frame.setContentPane(newContentPane);

// Display the window.

frame.pack();

frame.setVisible(true);

}

public static void main(String[] args) {

// Schedule a job for the event-dispatching thread:

// creating and showing this application's GUI.

javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGUI();

}

});

}

}

class MyList extends JList{

/**

*

*/

private static final long serialVersionUID = 1;

MyTable table;

JTextArea area;

public MyList(DefaultListModel listModel,

MyTable t, JTextArea a) {

table = t;

area = a;

super.setModel(listModel);

}

}

class MyTable extends JTable {

/**

*

*/

private static final long serialVersionUID = 1;

int xco = 0, yco = 0;

JTextArea area;

public MyTable(DefaultTableModel model, JTextArea a) {

area = a;

super.setModel(model);

}

boolean IsRowEditable() {

Point point = new Point(xco, yco);

int row = rowAtPoint(point);

if (row != 2)

return true;

else

return false;

}

void SetXcoYco(int x, int y) {

xco = x;

yco = y;

}

}

/*

* ListTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

class ListTransferHandler extends StringTransferHandler {

/**

*

*/

private static final long serialVersionUID = 1;

private int[] indices = null;

private int addIndex = -1; // Location where items were added

private int addCount = 0; // Number of items added.

// Bundle up the selected items in the list

// as a single string, for export.

protected String exportString(JComponent c) {

JList list = (JList) c;

indices = list.getSelectedIndices();

Object[] values = list.getSelectedValues();

StringBuffer buff = new StringBuffer();

for (int i = 0; i < values.length; i++) {

Object val = values;

buff.append(val == null ? "" : val.toString());

if (i != values.length - 1) {

buff.append("\n");

}

}

return buff.toString();

}

// Take the incoming string and wherever there is a

// newline, break it into a separate item in the list.

protected void importString(JComponent c, String str) {

JList target = (JList) c;

DefaultListModel listModel = (DefaultListModel) target.getModel();

int index = target.getSelectedIndex();

// Prevent the user from dropping data back on itself.

// For example, if the user is moving items #4,#5,#6 and #7 and

// attempts to insert the items after item #5, this would

// be problematic when removing the original items.

// So this is not allowed.

if (indices != null && index >= indices[0] - 1

&& index <= indices[indices.length - 1]) {

indices = null;

return;

}

int max = listModel.getSize();

if (index < 0) {

index = max;

} else {

index++;

if (index > max) {

index = max;

}

}

addIndex = index;

String[] values = str.split("\n");

addCount = values.length;

for (int i = 0; i < values.length; i++) {

listModel.add(index++, values);

}

}

// If the remove argument is true, the drop has been

// successful and it's time to remove the selected items

// from the list. If the remove argument is false, it

// was a Copy operation and the original list is left

// intact.

protected void cleanup(JComponent c, boolean remove) {

if (remove && indices != null) {

JList source = (JList) c;

DefaultListModel model = (DefaultListModel) source.getModel();

// If we are moving items around in the same list, we

// need to adjust the indices accordingly, since those

// after the insertion point have moved.

if (addCount > 0) {

for (int i = 0; i < indices.length; i++) {

if (indices[i] > addIndex) {

indices[i] += addCount;

}

}

}

for (int i = indices.length - 1; i >= 0; i--) {

model.remove(indices[i]);

}

}

indices = null;

addCount = 0;

addIndex = -1;

}

}

/*

* StringTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

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) {

// ///// MY CODE TO SET A ROW NON DROPABLE /////////////

if (c instanceof MyTable) {

MyTable table = (MyTable) c;

if (!table.IsRowEditable())

return false;

else

return true;

}

// ///// MY CODE TO SET A ROW NON DROPABLE /////////////

for (int i = 0; i < flavors.length; i++) {

if (DataFlavor.stringFlavor.equals(flavors)) {

return true;

}

}

return false;

}

}

/*

* TableTransferHandler.java is used by the 1.4 ExtendedDnDDemo.java example.

*/

class TableTransferHandler extends StringTransferHandler {

private int[] rows = null;

private int addIndex = -1; // Location where items were added

private int addCount = 0; // Number of items added.

protected String exportString(JComponent c) {

JTable table = (JTable) c;

rows = table.getSelectedRows();

int colCount = table.getColumnCount();

StringBuffer buff = new StringBuffer();

for (int i = 0; i < rows.length; i++) {

for (int j = 0; j < colCount; j++) {

Object val = table.getValueAt(rows[i], j);

buff.append(val == null ? "" : val.toString());

if (j != colCount - 1) {

buff.append(",");

}

}

if (i != rows.length - 1) {

buff.append("\n");

}

}

return buff.toString();

}

protected void importString(JComponent c, String str) {

JTable target = (JTable) c;

DefaultTableModel model = (DefaultTableModel) target.getModel();

int index = target.getSelectedRow();

// Prevent the user from dropping data back on itself.

// For example, if the user is moving rows #4,#5,#6 and #7 and

// attempts to insert the rows after row #5, this would

// be problematic when removing the original rows.

// So this is not allowed.

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 i = 0; i < values.length && i < colCount; i++) {

model.insertRow(index++, values[i].split(","));

}

}

protected void cleanup(JComponent c, boolean remove) {

JTable source = (JTable) c;

if (remove && rows != null) {

DefaultTableModel model = (DefaultTableModel) source.getModel();

//If we are moving items around in the same table, we

//need to adjust the rows accordingly, since those

//after the insertion point have moved.

if (addCount > 0) {

for (int i = 0; i < rows.length; i++) {

if (rows[i] > addIndex) {

rows[i] += addCount;

}

}

}

for (int i = rows.length - 1; i >= 0; i--) {

model.removeRow(rows[i]);

}

}

rows = null;

addCount = 0;

addIndex = -1;

}

}

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 11

> My goal for this example is to make row 2 in the table non-dropable.

The demo inserts the data after the selected row. Using the original demo I changed the TableTransferHandle to prevent the insertion of data after the second row only:

public boolean canImport(JComponent c, DataFlavor[] flavors)

{

JTable table = (JTable)c;

if (table.getSelectedRow() == 1)

{

table.setRowSelectionInterval(0, 0);

return false;

}

else

return super.canImport(c, flavors);

}

The icon doesn't change as you move from row to row since the canImport() method is only called once.

Don't know if will help but its the best I can think of.

You may want to try looking at the source code to see exactly what happens when you use the setDragEnabled() method. It may give you a better understanding of what happens to the mouseDragged events, since they seem to be forwarded to the JTable since row selection changes.

camickra at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...
# 12

Thanks for the reply. I might just have to go with that solution as I am not sure the overhead of tracking the mouse is worth this feature, as it will only be required in my program on the rare occasion. But it was anyway a good learning process. If anyone else has any advice though, I would be happy to hear it.

Cheers

Schneckea at 2007-7-8 23:52:31 > top of Java-index,Desktop,Core GUI APIs...