java/swing:两个子窗口的拖放问题

java/swing:两个子窗口的拖放问题,java,swing,drag-and-drop,Java,Swing,Drag And Drop,我有两个子窗口,我想以两种不同的方式接受拖放对象的拖放 一个是我想要接受文件列表的JPanel。它很好用 另一个是我想要接受字符串列表的JTable。如果我不启用JPanel作为拖放目标,它就可以正常工作 当我尝试同时启用两者时,JPanel drop目标似乎掩盖了JTable drop目标,即使JTable不是JPanel的子窗口,并且两个组件位于非重叠区域 同时,包含这两个元素的JFrame似乎得到了下拉图标。。。不知道为什么 有什么建议吗?这很难调试 下面是一个类似的示例应用程序,在这里

我有两个子窗口,我想以两种不同的方式接受拖放对象的拖放

一个是我想要接受文件列表的JPanel。它很好用

另一个是我想要接受字符串列表的JTable。如果我不启用JPanel作为拖放目标,它就可以正常工作

当我尝试同时启用两者时,JPanel drop目标似乎掩盖了JTable drop目标,即使JTable不是JPanel的子窗口,并且两个组件位于非重叠区域

同时,包含这两个元素的JFrame似乎得到了下拉图标。。。不知道为什么

有什么建议吗?这很难调试


下面是一个类似的示例应用程序,在这里我根本无法让JTable接受Drop:/

还有一个问题我想了解:如果我从“拖动源1”拖动到“拖放目标1”上,但不释放鼠标,每次拖动源1标签更改时,我的光标都会闪烁(在这个测试应用程序中每秒一次)它为什么会这样做?有没有办法阻止它闪烁?

package com.example.test.gui;

import java.awt.Component;
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 java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

public class DragAndDropQuestion {
    public enum Color { 
        RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, WHITE, BLACK;
        @Override public String toString() 
            { return this.name().toLowerCase(); }
        static public Color randomColor(Random r)
        {
            Color[] colors = Color.values();
            return colors[r.nextInt(colors.length)];
        }
    }
    public static class SampleBean
    {
        final private Color color;
        final private char letter;
        final static public DataFlavor dataFlavor = 
            new DataFlavor(SampleBean.class, "SampleBean");
        public Color getColor() { return this.color; }
        public char getLetter() { return this.letter; }
        private SampleBean(Color color, char letter)
        {
            this.color = color;
            this.letter = letter;
        }
        static public SampleBean randomBean(Random r)
        {
            String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            return new SampleBean(Color.randomColor(r),
                    letters.charAt(r.nextInt(letters.length())));
        }
        @Override public String toString() {
            return this.color.toString()+" "+this.letter; 
        }
    }
    public static class BorderPanel extends JPanel {
        public BorderPanel(String title)
        {
            setBorder(BorderFactory.createTitledBorder(title));
        }
    }
    public static class BeanTransferable implements Transferable
    {
        final private SampleBean value;
        static final private List<DataFlavor> flavors = Arrays.asList(
                DataFlavor.stringFlavor,
                SampleBean.dataFlavor
            );
        public BeanTransferable(SampleBean x) { this.value=x; }
        @Override public Object getTransferData(DataFlavor flavor) 
        throws UnsupportedFlavorException, IOException {
            if (flavors.get(0).equals(flavor))
            {
                return this.value.toString(); 
            }
            else if (flavors.get(1).equals(flavor))
            {
                return this.value;
            }
            else
            {
                throw new UnsupportedFlavorException(flavor);
            }
        }

        @Override public DataFlavor[] getTransferDataFlavors() {
            return flavors.toArray(new DataFlavor[0]);
        }
        @Override public boolean isDataFlavorSupported(DataFlavor flavor) {
            return flavors.contains(flavor);
        }
    }
    public abstract static class SimpleDropTarget 
       implements DropTargetListener
    {
        final private String debugString;
        public SimpleDropTarget(String debugString) {
            this.debugString=debugString; 
        }
        @Override public void dragEnter(DropTargetDragEvent event) 
            { System.out.println(this.debugString+":dragEnter"); }
        @Override public void dragExit(DropTargetEvent event) {}
            { System.out.println(this.debugString+":dragExit"); }
        @Override public void dragOver(DropTargetDragEvent event) {}    
        @Override public void dropActionChanged(DropTargetDragEvent event) {}
        public void install(JComponent component) {
            new DropTarget(component, this);
        }
    }
    public abstract static class SimpleDragSource 
        implements DragSourceListener, DragGestureListener
    {
        final private String debugString;
        final private DragSource ds = new DragSource();
        public SimpleDragSource(String debugString) { 
            this.debugString=debugString; 
        }
        @Override public void dragDropEnd(DragSourceDropEvent event) {}
        @Override public void dragEnter(DragSourceDragEvent event) 
        { System.out.println(this.debugString+":dragEnter"); }
        @Override public void dragExit(DragSourceEvent event) 
        { System.out.println(this.debugString+":dragExit"); }
        @Override public void dragOver(DragSourceDragEvent event) {}
        @Override public void dropActionChanged(DragSourceDragEvent event) {}   
        public void install(JComponent component) {
            DragGestureRecognizer dgr = 
                this.ds.createDefaultDragGestureRecognizer(component,
                        DnDConstants.ACTION_COPY, this);
        }
        abstract public Transferable prepareTransferable();
        @Override public void dragGestureRecognized(DragGestureEvent dge)
        {
            this.ds.startDrag(dge,
                    DragSource.DefaultCopyDrop, prepareTransferable(), this);
        }
    }
    public static class BeanListModel implements TableModel {
        final private List<SampleBean> list = new ArrayList<SampleBean>();
        enum ColumnType {
            COLOR(Color.class, "color") {
                @Override public Color extractValue(SampleBean sampleBean) {
                    return sampleBean.getColor();
                }
            },
            LETTER(String.class, "letter") {
                @Override public String extractValue(SampleBean sampleBean) {
                    return Character.toString(sampleBean.getLetter());
                }
            },
            ;
            final private Class<?> cl;
            final private String name;
            public Class<?> getColumnClass() { return this.cl; }
            public String getColumnName() { return this.name; }
            ColumnType(Class<?> cl, String name) 
            { this.cl=cl; this.name=name; }
            abstract public Object extractValue(SampleBean sampleBean);
        }
        final static private ColumnType[] columns 
            = new ColumnType[]{ColumnType.COLOR, ColumnType.LETTER};

        @Override 
            public void addTableModelListener(TableModelListener arg0) {}
        @Override 
            public void removeTableModelListener(TableModelListener arg0) {}

        @Override public Class<?> getColumnClass(int column) {
            return columns[column].getColumnClass();
        }
        @Override public int getColumnCount() { 
            return columns.length; 
        }
        @Override public String getColumnName(int column) {
            return columns[column].getColumnName();
        }
        @Override public int getRowCount() { return list.size(); }
        @Override public Object getValueAt(int row, int column) {
            return columns[column].extractValue(list.get(row));
        }

        @Override public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override public void setValueAt(Object obj, int row, int column) {
            throw new UnsupportedOperationException();
        }       

        public void addBean(SampleBean bean)
        {
            this.list.add(bean);
        }
    }
    public static class BeanTablePanel extends BorderPanel {
        final private JTable table;
        final private BeanListModel tableModel;

        public BeanTablePanel(String title)
        {
            super(title);
            this.table = new JTable();
            this.tableModel = new BeanListModel();
            this.table.setModel(this.tableModel);
            add(new JScrollPane(this.table));
            SimpleDropTarget dt = new SimpleDropTarget("BeanTable"){
                @Override public void drop(DropTargetDropEvent dtde) {
                    Transferable tr = dtde.getTransferable();
                    if (tr.isDataFlavorSupported(SampleBean.dataFlavor))
                    {
                        try {
                            SampleBean b = (SampleBean) 
                                tr.getTransferData(SampleBean.dataFlavor);
                            addBean(b);
                        }
                        catch (UnsupportedFlavorException e) {
                            e.printStackTrace();
                        }
                        catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            dt.install(this.table);
            // !!! This doesn't seem to work...
        }
        void addBean(SampleBean b) {
            this.tableModel.addBean(b);         
        }
    }
    public static class BeanLabelPanel extends BorderPanel {
        final private JLabel label;
        public BeanLabelPanel(String title)
        {
            super(title);
            this.label = new JLabel("drop item here");
            add(this.label);
            SimpleDropTarget dt = new SimpleDropTarget("BeanLabel"){
                @Override public void drop(DropTargetDropEvent dtde) {
                    Transferable tr = dtde.getTransferable();
                    if (tr.isDataFlavorSupported(DataFlavor.stringFlavor))
                    {
                        try {
                            String s = (String) 
                                tr.getTransferData(DataFlavor.stringFlavor);
                            setLabel(s);
                        }
                        catch (UnsupportedFlavorException e) {
                            e.printStackTrace();
                        }
                        catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            dt.install(this.label);
        }       
        void setLabel(String s) { this.label.setText(s); }
    }
    public static class BeanSourcePanel extends BorderPanel {
        final private JLabel label;
        final private Random randomizer;
        private SampleBean x;

        public BeanSourcePanel(
         String title, ScheduledExecutorService scheduler)
        {
            super(title);
            this.label = new JLabel(" ");
            this.randomizer = new Random();
            add(this.label);

            scheduler.scheduleAtFixedRate(new Runnable()
            { public void run() { changeBean(); } }, 
            0, 1000, TimeUnit.MILLISECONDS);

            (new SimpleDragSource("RandomBean"){
                @Override public Transferable prepareTransferable() {
                    return new BeanTransferable(getBean());
                }
            }).install(this.label);
        }       
        public SampleBean getBean() { return this.x; }
        void changeBean()
        {
            this.x = SampleBean.randomBean(this.randomizer);
            this.label.setText(this.x.toString());
        }       
    }

    public static class DNDQFrame extends JFrame
    {
        public DNDQFrame(String title, ScheduledExecutorService scheduler)
        {
            setTitle(title);
            getContentPane().setLayout(
                    new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)
            );
            add(new JLabel("Drag and Drop Question"));
            add(new BeanSourcePanel("drag source 1", scheduler));
            add(new BeanLabelPanel("drop target 1"));
            add(new BeanTablePanel("drop target 2"));
        }
        @Override public Component add(Component component)
        {
            if (component instanceof JComponent)
                ((JComponent) component).setAlignmentX(0.0f);
            return super.add(component);            
        }       
    }

    static public void main(String[] args)
    {
        ScheduledExecutorService scheduler = 
            new ScheduledThreadPoolExecutor(1);
        DNDQFrame frame = new DNDQFrame("DragAndDropQuestion", scheduler);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
package com.example.test.gui;
导入java.awt.Component;
导入java.awt.datatransfer.DataFlavor;
导入java.awt.datatransfer.transfer;
导入java.awt.datatransfer.UnsupportedFlavorException;
导入java.awt.dnd.DnDConstants;
导入java.awt.dnd.DragGestureEvent;
导入java.awt.dnd.DragGestureListener;
导入java.awt.dnd.DragGestureRecognizer;
导入java.awt.dnd.DragSource;
导入java.awt.dnd.DragSourceDragEvent;
导入java.awt.dnd.DragSourceDropEvent;
导入java.awt.dnd.DragSourceEvent;
导入java.awt.dnd.DragSourceListener;
导入java.awt.dnd.DropTarget;
导入java.awt.dnd.dropTargetDrageEvent;
导入java.awt.dnd.DropTargetDropEvent;
导入java.awt.dnd.DropTargetEvent;
导入java.awt.dnd.DropTargetListener;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.Random;
导入java.util.concurrent.ScheduledExecutorService;
导入java.util.concurrent.ScheduledThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入javax.swing.BorderFactory;
导入javax.swing.BoxLayout;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.event.TableModelListener;
导入javax.swing.table.TableModel;
公开课问题{
公共枚举颜色{
红、橙、黄、绿、蓝、紫、白、黑;
@重写公共字符串toString()
{返回this.name().toLowerCase();}
静态公共颜色randomColor(随机r)
{
Color[]colors=Color.values();
返回颜色[r.nextInt(colors.length)];
}
}
公共静态类SampleBean
{
最终私色;
最后一封私人信件;
最终静态公共DataFlavor DataFlavor=
新的DataFlavor(SampleBean.class,“SampleBean”);
公共颜色getColor(){返回this.Color;}
public char getLetter(){返回this.letter;}
私有SampleBean(颜色、字符字母)
{
这个颜色=颜色;
这个字母=字母;
}
静态公共SampleBean randomBean(Random r)
{
字符串字母=“abcdefghijklmnopqrstuvxyz”;
返回新的SampleBean(Color.randomColor(r),
letters.charAt(r.nextInt(letters.length());
}
@重写公共字符串toString(){
返回this.color.toString()+“”+this.letter;
}
}
公共静态类BorderPanel扩展了JPanel{
公共边框面板(字符串标题)
{
setboorder(BorderFactory.createTitledBorder(title));
}
}
公共静态类BeanTransferable
{
最终私有SampleBean值;
静态最终私有列表flavors=Arrays.asList(
DataFlavor.stringFlavor,
SampleBean.dataFlavor
);
公共BeanTransferable(SampleBean x){this.value=x;}
@重写公共对象getTransferData(DataFlavor)
抛出不受支持的LavorException,IOException{
if(flavors.get(0).equals(flavor))
{
返回此.value.toString();
}
else if(flavors.get(1).equals(flavor))
{
返回此.value;
}
其他的
{
抛出新的不受支持的LavorException(flavor);
}
}
@重写公共DataFlavor[]getTransferDataFlavors(){
return-flavors.toArray(新的DataFlavor[0]);
}
@支持重写公共布尔值IsDataFlavor(DataFlavor){
返回味道。包含(味道);
}
}
公共抽象静态类SimpleDropTarget
实现DropTargetListener
{
最后一个私有字符串debugString;
公共SimpleDropTarget(字符串调试字符串){
this.debugString=debugString;
}
@覆盖公共无效dragEnter(DropTargetDragEvent事件)
{System.out.println(this.debugString+“:dragEnter”);}
@重写公共void dragExit(DropTargetEvent事件){}
{System.out.println(this.debugString+“:dragExit”);}
@重写公共无效dragOver(DropTargetDragEvent事件){}
@重写公共void dropActionChanged(DropTargetDragEvent事件){}
public void安装(JComponent组件){
新的DropTarget(组件,本);
}
}
公共抽象静态类SimpleDragSource
实现DragSourceListener、DragGestureListener
{
最后一个私有字符串debugString;
最终私有DragSource ds=新DragSource();
公共SimpleDragSource(Str)