I'm learning the drag and drop feature in Java Swing, so I modified a sample app to look like the following :
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import java.util.Arrays;
import javax.activation.*;
import javax.swing.*;
public class Demo_Drag_And_Drop_Panel extends JPanel
{
public Demo_Drag_And_Drop_Panel()
{
DefaultListModel<Item_Panel> m=new DefaultListModel<>();
for (String s : Arrays.asList("error","information","question","warning")) m.addElement(new Item_Panel(s));
JList<Item_Panel> list=new JList<>(m);
list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
list.setTransferHandler(new ListItem_TransferHandler());
list.setDropMode(DropMode.INSERT);
list.setDragEnabled(true);
list.setLayoutOrientation(JList.HORIZONTAL_WRAP); // http://java-swing-tips.blogspot.jp/2008/10/rubber-band-selection-drag-and-drop.html
list.setVisibleRowCount(0);
list.setFixedCellWidth(300);
list.setFixedCellHeight(36);
list.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
list.setCellRenderer(new ListCellRenderer<Item_Panel>()
{
// private final JPanel p=new JPanel(new BorderLayout());
private final JPanel p=new JPanel(new FlowLayout(0,1,1));
JLabel icon=new JLabel((Icon)null,JLabel.CENTER);
JButton button=new JButton();
JLabel label=new JLabel();
JTextField textField=new JTextField();
@Override public Component getListCellRendererComponent(JList list,Item_Panel value,int index,boolean isSelected,boolean cellHasFocus)
{
icon.setIcon(value.icon);
button.setText(value.button.getText());
button.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if ((e.getModifiers() & InputEvent.BUTTON1_MASK)!=0)
{
// Out("mouseClicked : Left");
Out(value.name);
}
else if ((e.getModifiers() & InputEvent.BUTTON2_MASK)!=0)
{
// Out("mouseClicked : Middle");
}
else if ((e.getModifiers() & InputEvent.BUTTON3_MASK)!=0)
{
// Out("mouseClicked : Right");
}
}
});
label.setText(value.name);
label.setForeground(isSelected?list.getSelectionForeground():list.getForeground());
textField.setText(value.textField.getText());
textField.setEditable(true);
p.add(icon);
p.add(button);
p.add(label);
p.add(textField);
p.setBackground(isSelected?list.getSelectionBackground():list.getBackground());
return p;
}
});
add(new JScrollPane(list));
}
private static void out(String message) { System.out.print(message); }
private static void Out(String message) { System.out.println(message); }
public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); }
public static void createAndShowGUI()
{
JFrame f=new JFrame("Demo_Drag_And_Drop_Panel");
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new Demo_Drag_And_Drop_Panel());
f.setSize(350,213);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class Item_Panel
{
public final String name;
public final Icon icon;
public final JButton button;
public final JTextField textField;
public Item_Panel(String name)
{
this.name=name;
icon=UIManager.getIcon("OptionPane."+name+"Icon");
button=new JButton(name);
textField=new JTextField(name);
}
}
//@camickr already suggested above.
//http://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html
class ListItem_TransferHandler extends TransferHandler
{
private final DataFlavor localObjectFlavor;
private Object[] transferedObjects=null;
public ListItem_TransferHandler() { localObjectFlavor=new ActivationDataFlavor(Object[].class,DataFlavor.javaJVMLocalObjectMimeType,"Array of items"); }
@SuppressWarnings("deprecation")
@Override protected Transferable createTransferable(JComponent c)
{
JList list=(JList)c;
indices=list.getSelectedIndices();
transferedObjects=list.getSelectedValues();
return new DataHandler(transferedObjects,localObjectFlavor.getMimeType());
}
@Override public boolean canImport(TransferSupport info)
{
if (!info.isDrop() || !info.isDataFlavorSupported(localObjectFlavor)) return false;
return true;
}
@Override public int getSourceActions(JComponent c)
{
return MOVE; //TransferHandler.COPY_OR_MOVE;
}
@SuppressWarnings("unchecked")
@Override public boolean importData(TransferSupport info)
{
if (!canImport(info)) return false;
JList target=(JList)info.getComponent();
JList.DropLocation dl=(JList.DropLocation)info.getDropLocation();
DefaultListModel listModel=(DefaultListModel)target.getModel();
int index=dl.getIndex();
int max=listModel.getSize();
if (index<0||index>max) index=max;
addIndex=index;
try
{
Object[] values=(Object[])info.getTransferable().getTransferData(localObjectFlavor);
addCount=values.length;
for (int i=0;i<values.length;i++)
{
int idx=index++;
listModel.add(idx,values[i]);
target.addSelectionInterval(idx,idx);
}
return true;
}
catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); }
catch (IOException ioe) { ioe.printStackTrace(); }
return false;
}
@Override protected void exportDone(JComponent c,Transferable data,int action) { cleanup(c,action==MOVE); }
private void cleanup(JComponent c,boolean remove)
{
if (remove&&indices!=null)
{
JList source=(JList)c;
DefaultListModel model=(DefaultListModel)source.getModel();
if (addCount>0)
{
//http://java-swing-tips.googlecode.com/svn/trunk/DnDReorderList/src/java/example/MainPanel.java
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;
}
private int[] indices=null;
private int addIndex=-1; //Location where items were added
private int addCount=0; //Number of items added.
}
But when I ran it, I noticed the buttons are not clickable and the textfields are not editable, how to fix them ? In other words, I want to be able to click the buttons and output some info and be able to click in the textfields and edit the text in them, how to do that ?