java swing拖放linux:未调用DragSourceListener.dragDropEnd

问题描述 投票:0回答:0

我正在尝试对

jtabbedpane
实现拖放行为。 它在我的 Windows 10 上运行良好,但在 Debian 12 上运行不佳(Debian 上的 openjdk 17)。

这是一个最小的测试用例:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
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.InvalidDnDOperationException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class DnDTestCase extends JFrame {
  JTabbedPane tabbedPane;
  public DnDTestCase() {
    tabbedPane = new JTabbedPane(JTabbedPane.TOP);
    getContentPane().add(tabbedPane, BorderLayout.CENTER);

    JPanel panel = new JPanel();
    tabbedPane.addTab("New tab", null, panel, null);

    this.setSize(320, 240);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    initDnd();
  }

  void initDnd() {
    final DragSourceListener dsl = new DragSourceListener() {
      @Override
      public void dragEnter(DragSourceDragEvent e) {}
      @Override
      public void dragExit(DragSourceEvent e) {}
      @Override
      public void dragOver(DragSourceDragEvent e) {}
      @Override
      public void dragDropEnd(DragSourceDropEvent e) {
        System.out.println("dragDropEnd()");
      }
      @Override
      public void dropActionChanged(DragSourceDragEvent e) {}
    };

    final DragGestureListener dgl = new DragGestureListener() {
      @Override
      public void dragGestureRecognized(DragGestureEvent e) {
        System.out.println("dragGestureRecognized()");
        try {
          e.startDrag(DragSource.DefaultMoveDrop,
            new Transferable() {
              @Override
              public Object getTransferData(DataFlavor flavor) {
                return null;
              }
              @Override
              public DataFlavor[] getTransferDataFlavors() {
                return null;
              }
              @Override
              public boolean isDataFlavorSupported(DataFlavor flavor) {
                return true;
              }
            },
            dsl);
        } catch (InvalidDnDOperationException idoe) {
          idoe.printStackTrace();
        }
      }
    };

    DragSource ds = new DragSource();
    ds.createDefaultDragGestureRecognizer(tabbedPane, DnDConstants.ACTION_MOVE, dgl);

  }

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> new DnDTestCase().setVisible(true));
  }
}

这里是

Windows
。[JFrame+JtabPane]

基本上,您可以将选项卡拖放到窗口本身,也可以拖放到

JFrame
之外的空白区域,在这两种情况下,在 Windows 上,释放鼠标按钮时都会触发
dragDropEnd
功能。所以它在终端中显示
dragDropEnd()
。这很好。

但是,在

Linux
运行中,仅当鼠标光标位于
dragDropEnd
上方时才会触发
JFrame
(显然,原始的一个或什至另一个,这并不重要)。

如果在空白处释放鼠标按钮(=不是

JFrame
— 甚至可能是
JDialog
),它不会触发任何操作,直到鼠标光标移回到
JFrame
上。因此,由于某种原因,如果鼠标不在
JFrame
上,则不会生成事件?

我是否明显做错了什么?

java swing drag-and-drop drag
© www.soinside.com 2019 - 2024. All rights reserved.