java拖放
我试图熟悉java中的拖放操作,但我找到的所有教程都是。。。(让我生气) 我只想从JList(包含在名为“UserPanel”的自制JPanel中)中拖动一个“PublicUserLabel”,然后将其放入从JTabbedPanel生成的自制类中。 拖动对象本身而不是其stringrepresentation是非常重要的 这就是我到目前为止所做的: PublicUserLabeljava拖放,java,swing,awt,drag-and-drop,Java,Swing,Awt,Drag And Drop,我试图熟悉java中的拖放操作,但我找到的所有教程都是。。。(让我生气) 我只想从JList(包含在名为“UserPanel”的自制JPanel中)中拖动一个“PublicUserLabel”,然后将其放入从JTabbedPanel生成的自制类中。 拖动对象本身而不是其stringrepresentation是非常重要的 这就是我到目前为止所做的: PublicUserLabel public class PublicUserLabel extends JLabel implements Dra
public class PublicUserLabel extends JLabel implements DragSourceListener, DragGestureListener, Transferable
{
private DragSource ds;
private PublicUser user;
public PublicUserLabel(PublicUser user)
{
super(user.getName());
this.user = user;
ds = new DragSource();
ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this);
}
@Override
public void dragGestureRecognized(DragGestureEvent e)
{
ds.startDrag(e, DragSource.DefaultCopyDrop, this, this);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
{
if (flavor.equals(PublicUserFlavor.publicUserFlavor))
{
return this;//TODO ?
}
throw new UnsupportedFlavorException(flavor);
}
@Override
public DataFlavor[] getTransferDataFlavors()
{
DataFlavor[] df = new DataFlavor[2];
df[0] = DataFlavor.stringFlavor;
df[1] = PublicUserFlavor.publicUserFlavor;
return df;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor)
{
return flavor.equals(PublicUserFlavor.publicUserFlavor);
}
//some more methods
}
用户面板:
public class UserPanel extends JPanel
{
private JTextField search;
private List<PublicUser> allUser;
private JList<PublicUserLabel> list;
private JScrollPane scrollPane;
private DefaultListModel<PublicUserLabel> listModel;
public UserPanel()
{
allUser = new LinkedList<PublicUser>();
listModel = new DefaultListModel<PublicUserLabel>();
list = new JList<PublicUserLabel>(listModel);
list.setDragEnabled(true);
选项卡面板:
public class TabPanel extends JTabbedPane implements DropTargetListener
{
public TabPanel()
{
setTabPlacement(JTabbedPane.BOTTOM);
addNewTabComponent("bla");
addNewTabComponent("blub");
setDropTarget(new DropTarget(this, this));
}
@Override
public void drop(DropTargetDropEvent e)
{
Transferable transferable = e.getTransferable();
if (transferable.isDataFlavorSupported(PublicUserFlavor.publicUserFlavor))
{
e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
try
{
Object o = transferable.getTransferData(PublicUserFlavor.publicUserFlavor);
System.out.println(o);
if (o instanceof PublicUserLabel)
{
PublicUserLabel l = (PublicUserLabel)o;
PublicUser u = l.getUser();
System.out.println(u);
}
}
catch (UnsupportedFlavorException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.getDropTargetContext().dropComplete(true);
}
}
drop方法中有一些syso,如果用户被丢弃在面板中,则应执行这些syso。但事实并非如此。我做错什么了吗?
谢谢你的帮助 我能看到的主要问题是您混合了两种不同的API。您正在使用低级的D'n'D API和较新的“component D'n'D”API 就我个人而言,新的API让我很恼火,所以我倾向于避免使用它 我不明白为什么需要转移标签,而转移底层的
PublicUser
对象会更好,但这只是我的问题
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestDnD {
public static void main(String[] args) {
new TestDnD();
}
public TestDnD() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JList list;
public TestPane() {
setLayout(new BorderLayout());
list = new JList();
DefaultListModel model = new DefaultListModel();
model.addElement(new User("Shaun"));
model.addElement(new User("Andy"));
model.addElement(new User("Luke"));
model.addElement(new User("Han"));
model.addElement(new User("Liea"));
model.addElement(new User("Yoda"));
list.setModel(model);
add(new JScrollPane(list), BorderLayout.WEST);
DragGestureRecognizer dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
list,
DnDConstants.ACTION_COPY_OR_MOVE,
new DragGestureHandler(list));
JPanel panel = new JPanel(new GridBagLayout());
add(panel);
DropTarget dt = new DropTarget(
panel,
DnDConstants.ACTION_COPY_OR_MOVE,
new DropTargetHandler(panel),
true);
}
}
public static class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
public static class UserTransferable implements Transferable {
public static final DataFlavor USER_DATA_FLAVOR = new DataFlavor(User.class, "User");
private User user;
public UserTransferable(User user) {
this.user = user;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{USER_DATA_FLAVOR};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return USER_DATA_FLAVOR.equals(flavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object value = null;
if (USER_DATA_FLAVOR.equals(flavor)) {
value = user;
} else {
throw new UnsupportedFlavorException(flavor);
}
return value;
}
}
protected class DragGestureHandler implements DragGestureListener {
private JList list;
public DragGestureHandler(JList list) {
this.list = list;
}
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
Object selectedValue = list.getSelectedValue();
if (selectedValue instanceof User) {
User user = (User) selectedValue;
Transferable t = new UserTransferable(user);
DragSource ds = dge.getDragSource();
ds.startDrag(
dge,
null,
t,
new DragSourceHandler());
}
}
}
protected class DragSourceHandler implements DragSourceListener {
public void dragEnter(DragSourceDragEvent dsde) {
}
public void dragOver(DragSourceDragEvent dsde) {
}
public void dropActionChanged(DragSourceDragEvent dsde) {
}
public void dragExit(DragSourceEvent dse) {
}
public void dragDropEnd(DragSourceDropEvent dsde) {
System.out.println("Drag ended...");
}
}
protected class DropTargetHandler implements DropTargetListener {
private JPanel panel;
public DropTargetHandler(JPanel panel) {
this.panel = panel;
}
public void dragEnter(DropTargetDragEvent dtde) {
if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
System.out.println("Accept...");
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
} else {
System.out.println("Drag...");
dtde.rejectDrag();
}
}
public void dragOver(DropTargetDragEvent dtde) {
}
public void dropActionChanged(DropTargetDragEvent dtde) {
}
public void dragExit(DropTargetEvent dte) {
}
public void drop(DropTargetDropEvent dtde) {
System.out.println("Dropped...");
if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
Transferable t = dtde.getTransferable();
if (t.isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
try {
Object transferData = t.getTransferData(UserTransferable.USER_DATA_FLAVOR);
if (transferData instanceof User) {
User user = (User) transferData;
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
panel.add(new JLabel(user.getName()));
panel.revalidate();
panel.repaint();
} else {
dtde.rejectDrop();
}
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
dtde.rejectDrop();
} catch (IOException ex) {
ex.printStackTrace();
dtde.rejectDrop();
}
} else {
dtde.rejectDrop();
}
}
}
}
}
我能看到的主要问题是,您混合了两种不同的API。您正在使用低级的D'n'D API和较新的“component D'n'D”API 就我个人而言,新的API让我很恼火,所以我倾向于避免使用它 我不明白为什么需要转移标签,而转移底层的
PublicUser
对象会更好,但这只是我的问题
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestDnD {
public static void main(String[] args) {
new TestDnD();
}
public TestDnD() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JList list;
public TestPane() {
setLayout(new BorderLayout());
list = new JList();
DefaultListModel model = new DefaultListModel();
model.addElement(new User("Shaun"));
model.addElement(new User("Andy"));
model.addElement(new User("Luke"));
model.addElement(new User("Han"));
model.addElement(new User("Liea"));
model.addElement(new User("Yoda"));
list.setModel(model);
add(new JScrollPane(list), BorderLayout.WEST);
DragGestureRecognizer dgr = DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
list,
DnDConstants.ACTION_COPY_OR_MOVE,
new DragGestureHandler(list));
JPanel panel = new JPanel(new GridBagLayout());
add(panel);
DropTarget dt = new DropTarget(
panel,
DnDConstants.ACTION_COPY_OR_MOVE,
new DropTargetHandler(panel),
true);
}
}
public static class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name;
}
}
public static class UserTransferable implements Transferable {
public static final DataFlavor USER_DATA_FLAVOR = new DataFlavor(User.class, "User");
private User user;
public UserTransferable(User user) {
this.user = user;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{USER_DATA_FLAVOR};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return USER_DATA_FLAVOR.equals(flavor);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
Object value = null;
if (USER_DATA_FLAVOR.equals(flavor)) {
value = user;
} else {
throw new UnsupportedFlavorException(flavor);
}
return value;
}
}
protected class DragGestureHandler implements DragGestureListener {
private JList list;
public DragGestureHandler(JList list) {
this.list = list;
}
@Override
public void dragGestureRecognized(DragGestureEvent dge) {
Object selectedValue = list.getSelectedValue();
if (selectedValue instanceof User) {
User user = (User) selectedValue;
Transferable t = new UserTransferable(user);
DragSource ds = dge.getDragSource();
ds.startDrag(
dge,
null,
t,
new DragSourceHandler());
}
}
}
protected class DragSourceHandler implements DragSourceListener {
public void dragEnter(DragSourceDragEvent dsde) {
}
public void dragOver(DragSourceDragEvent dsde) {
}
public void dropActionChanged(DragSourceDragEvent dsde) {
}
public void dragExit(DragSourceEvent dse) {
}
public void dragDropEnd(DragSourceDropEvent dsde) {
System.out.println("Drag ended...");
}
}
protected class DropTargetHandler implements DropTargetListener {
private JPanel panel;
public DropTargetHandler(JPanel panel) {
this.panel = panel;
}
public void dragEnter(DropTargetDragEvent dtde) {
if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
System.out.println("Accept...");
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
} else {
System.out.println("Drag...");
dtde.rejectDrag();
}
}
public void dragOver(DropTargetDragEvent dtde) {
}
public void dropActionChanged(DropTargetDragEvent dtde) {
}
public void dragExit(DropTargetEvent dte) {
}
public void drop(DropTargetDropEvent dtde) {
System.out.println("Dropped...");
if (dtde.getTransferable().isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
Transferable t = dtde.getTransferable();
if (t.isDataFlavorSupported(UserTransferable.USER_DATA_FLAVOR)) {
try {
Object transferData = t.getTransferData(UserTransferable.USER_DATA_FLAVOR);
if (transferData instanceof User) {
User user = (User) transferData;
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
panel.add(new JLabel(user.getName()));
panel.revalidate();
panel.repaint();
} else {
dtde.rejectDrop();
}
} catch (UnsupportedFlavorException ex) {
ex.printStackTrace();
dtde.rejectDrop();
} catch (IOException ex) {
ex.printStackTrace();
dtde.rejectDrop();
}
} else {
dtde.rejectDrop();
}
}
}
}
}
在线教程有什么问题?拖动对象本身而不是其stringrepresentation非常重要1)为什么?2) 如果从
JList
开始拖动,将很困难,因为JList
甚至不包含该JLabel
,只有呈现的版本才重要,因为用户不仅有名称。用户还具有公共rsa密钥和uuid。我必须至少从丢弃的对象中获取uuid和密钥。我与PublicUser存储了一个列表,其中包含我需要的所有信息,因此我不必使用JList。一个糟糕教程的例子是标题“将所有内容放在一起”。绝对不是所有人都在一起。甚至一个被覆盖的方法的签名也丢失了。@zachlatta在线教程是矛盾的。除非你知道你在看什么。通常,Swing中有两个不同的d'n'd API。有低级API和较新的“组件”API。没有多少教程公开解释他们使用的是哪一个,这使得已经是一个困难的主题变得更加复杂-我知道编写好的教程是一项艰苦的工作-如果艰苦的工作没有达到你想要的结果,你可能会考虑雇佣一个私人导师…在线教程有什么不对?重要的是拖动对象本身而不是它的字符串表示1)为什么?2) 如果从JList
开始拖动,将很困难,因为JList
甚至不包含该JLabel
,只有呈现的版本才重要,因为用户不仅有名称。用户还具有公共rsa密钥和uuid。我必须至少从丢弃的对象中获取uuid和密钥。我与PublicUser存储了一个列表,其中包含我需要的所有信息,因此我不必使用JList。一个糟糕教程的例子是标题“将所有内容放在一起”。绝对不是所有人都在一起。甚至一个被覆盖的方法的签名也丢失了。@zachlatta在线教程是矛盾的。除非你知道你在看什么。通常,Swing中有两个不同的d'n'd API。有低级API和较新的“组件”API。不是很多的教程公开解释他们正在使用的是什么,它使已经是一个困难的主题变得更复杂了——要学好好的教程是很难的。如果你的努力没有得到你想要的结果,你可能会考虑雇佣一个私人导师……失踪或混合你的小天使?-)我认为较新的api更易于使用——遗憾的是,它很难用没有api的组件实现default@kleopatra嗯?什么较新的API?@andrewhompson设置setDrageEnabled/setTransferHandler时钩住的部分,即一些组件(如tree/table/list…)的底层(package.dnd)之上的抽象…:-)@正如你所说,如果它没有内置在组件中,那就是一种痛苦。我还发现,它故意禁用API的某些部分,以至于其他开发人员无法重新引入它们,例如拖动光标/图像。我一直想实现博客中的一些想法,但还没有找到时间坐下来做它——又是你的小天使?——就我个人而言,我认为新的api更容易使用——遗憾的是,它很难用没有它的组件实现default@kleopatra嗯?什么较新的API?@andrewhompson设置setDrageEnabled/setTransferHandler时钩住的部分,即一些组件(如tree/table/list…)的底层(package.dnd)之上的抽象…:-)@正如你所说,如果它没有内置在组件中,那就是一种痛苦。我还发现,它故意禁用API的某些部分,以至于其他开发人员无法重新引入它们,例如拖动光标/图像。我想实现博客中的一些想法,但还没有找到时间坐下来做