gpt4 book ai didi

java - 禁用或拦截窗外的掉落

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:10:32 25 4
gpt4 key购买 nike

我已经实现了一组可拖动的选项卡,遵循这个例子的形式: How to implement draggable tab using Java Swing?

一切似乎都如我所愿,但是,当我拖出主面板时,桌面将成为有效的放置目标(结果放置被接受并标记为成功)。

有没有办法拦截这个掉落以对掉落到我们的根 Pane 之外使用react?它很容易检测到,但我不清楚如何在外界之前真正捕捉到液滴。

在 DragSourceListener 的 dragDropEnd 被调用时,拖放已经执行,并且似乎没有在 dragOver/Exit/Whatever 中结束拖拽的好方法。

哎呀,如果这样的事情能奏效就好了:

@Override
public void dragOver(DragSourceDragEvent dragEvent)
{
DragEnabledTabTransferData data = getTabTransferData(dragEvent);
DragSourceContext dragSourceContext = dragEvent.getDragSourceContext();
if (data == null)
{
dragSourceContext.setCursor(DragSource.DefaultMoveNoDrop);
return;
}
if (!data.getTabbedPane().getRootPane().getBounds().contains(dragEvent.getLocation()))
{
dragSourceContext.dragDropEnd(new DragSourceDropEvent(dragSourceContext, 999, true));
}
}

相反,拖动会继续拖动。我知道,但是我的麻烦得到了一个 dragDropEnd。

有什么想法吗?听到唯一的解决方案是让一些隐藏的最大化全局 Pane 仅充当放置目标来捕获窗口外事件,我会感到非常难过。

这是一个工作示例。如果您将一个选项卡拖出,比如说,在 Linux 中的桌面上,它会尝试将传输数据转换为 Serializable 并且不高兴。如果您想直接跳到我在上面指出的内容,我正在玩的拖拽被评论为“这是我假设我们能够拦截东西的地方”。

/** "Simple" example of DnD tabbed panes. Sourced from Eugene Yokota:
* http:stackoverflow.com/questions/60269/how-to-implement-draggable-tab-using-java-swing */
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;

public class DnDTabbedPane extends JTabbedPane {
private static final String NAME = "TabTransferData";
private final DataFlavor FLAVOR = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType, NAME);

public DnDTabbedPane() {
super();
final DragSourceListener dsl = new DragSourceListener() {
public void dragEnter(DragSourceDragEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}

public void dragExit(DragSourceEvent e) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
}

/**
* This is where I'd assume we'd be able to intercept stuff
* so drops don't happen where we don't want them to.
*/
public void dragOver(DragSourceDragEvent e) {
TabTransferData data = getTabTransferData(e);
if (data == null) {
e.getDragSourceContext().setCursor(DragSource.DefaultMoveNoDrop);
return;
}
//This is where I ended up robokilling the drag via hackery
e.getDragSourceContext().setCursor(DragSource.DefaultMoveDrop);
}
public void dragDropEnd(DragSourceDropEvent e) {}
public void dropActionChanged(DragSourceDragEvent e) {}
};

final DragGestureListener dgl = new DragGestureListener() {
public void dragGestureRecognized(DragGestureEvent e) {

Point tabPt = e.getDragOrigin();
int dragTabIndex = indexAtLocation(tabPt.x, tabPt.y);
if (dragTabIndex < 0) {
return;
}
e.startDrag(DragSource.DefaultMoveDrop,new TabTransferable(DnDTabbedPane.this, dragTabIndex), dsl);
}
};

new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, new CDropTargetListener(), true);
new DragSource().createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, dgl);
}

private TabTransferData getTabTransferData(DropTargetDropEvent a_event) {
try {
return (TabTransferData) a_event.getTransferable().getTransferData(FLAVOR);
} catch (Exception e) {}

return null;
}

private TabTransferData getTabTransferData(DropTargetDragEvent a_event) {
try {
return (TabTransferData) a_event.getTransferable().getTransferData(FLAVOR);
} catch (Exception e) {}

return null;
}

private TabTransferData getTabTransferData(DragSourceDragEvent a_event) {
try {
return (TabTransferData) a_event.getDragSourceContext().getTransferable().getTransferData(FLAVOR);
} catch (Exception e) {}

return null;
}

class TabTransferable implements Transferable {
private TabTransferData m_data = null;
private DataFlavor[] flavors = {FLAVOR};
public TabTransferable(DnDTabbedPane a_tabbedPane, int a_tabIndex) {
m_data = new TabTransferData(DnDTabbedPane.this, a_tabIndex);
}

public Object getTransferData(DataFlavor flavor) {
return m_data;
}

public DataFlavor[] getTransferDataFlavors() {
return flavors;
}

public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.getHumanPresentableName().equals(NAME);
}
}

class TabTransferData {
DnDTabbedPane m_tabbedPane = null;
int m_tabIndex = -1;

public TabTransferData(DnDTabbedPane a_tabbedPane, int a_tabIndex) {
m_tabbedPane = a_tabbedPane;
m_tabIndex = a_tabIndex;
}
}

class CDropTargetListener implements DropTargetListener {
public void dragEnter(DropTargetDragEvent e) {
if (isDragAcceptable(e)) {
e.acceptDrag(e.getDropAction());
} else {
e.rejectDrag();
}
}

public void drop(DropTargetDropEvent a_event) {
if (isDropAcceptable(a_event)) {
convertTab(getTabTransferData(a_event),
getTargetTabIndex(a_event.getLocation()));
a_event.dropComplete(true);
} else {
a_event.dropComplete(false);
}
}

private boolean isTransferableGood(Transferable t, DataFlavor flavor)
{
return t == null || t.isDataFlavorSupported(flavor);
}

private boolean isDataGood(TabTransferData data)
{
if (DnDTabbedPane.this == data.m_tabbedPane && data.m_tabIndex >= 0) {
return true;
}
return false;
}

public boolean isDragAcceptable(DropTargetDragEvent e) {
Transferable t = e.getTransferable();
if (!isTransferableGood(t, e.getCurrentDataFlavors()[0])) {
return false;
}
return isDataGood(getTabTransferData(e));
}

public boolean isDropAcceptable(DropTargetDropEvent e) {
Transferable t = e.getTransferable();
if (!isTransferableGood(t, e.getCurrentDataFlavors()[0])) {
return false;
}
return isDataGood(getTabTransferData(e));
}

public void dragExit(DropTargetEvent e) {}
public void dropActionChanged(DropTargetDragEvent e) {}
public void dragOver(final DropTargetDragEvent e) {}
}

private int getTargetTabIndex(Point a_point) {
for (int i = 0; i < getTabCount(); i++) {
Rectangle r = getBoundsAt(i);
r.setRect(r.x - r.width / 2, r.y, r.width, r.height);
if (r.contains(a_point)) {
return i;
}
}
return -1;
}

private void convertTab(TabTransferData a_data, int a_targetIndex) {
DnDTabbedPane source = a_data.m_tabbedPane;
int sourceIndex = a_data.m_tabIndex;
if (sourceIndex < 0) {
return;
}

Component cmp = source.getComponentAt(sourceIndex);
String str = source.getTitleAt(sourceIndex);

if (a_targetIndex < 0 || sourceIndex == a_targetIndex) {
return;
}
source.remove(sourceIndex);
if (a_targetIndex == getTabCount()) {
addTab(str, cmp);
} else if (sourceIndex > a_targetIndex) {
insertTab(str, null, cmp, null, a_targetIndex);
} else {
insertTab(str, null, cmp, null, a_targetIndex - 1);
}
}

public static void main(String[] args)
{
JFrame window = new JFrame();
DnDTabbedPane tabbedPane = new DnDTabbedPane();
for(int i=0; i< 5; i++)
{
tabbedPane.addTab("I'm tab "+i, new JLabel("I'm tab "+i));
}
window.add(tabbedPane);
window.setSize(400, 200);
window.setVisible(true);
}
}

到目前为止,我能做的最好的事情就是在我们跳出 parent 时调用一些东西来达到这种效果。

    Component rootPane = SwingUtilities.getRoot(component);
Rectangle bounds = rootPane.getBounds();
if (!bounds.contains(location))
{
Robot robot = null;
try
{
robot = new Robot();
} catch (AWTException e)
{
return;
}
robot.keyPress(KeyEvent.VK_ESCAPE);
robot.keyRelease(KeyEvent.VK_ESCAPE);
}

这完全是黑客攻击,并没有解决我的问题。我想拦截最终的放置事件,看看它是否在框架之外并在其自己的 JFrame 中生成选项卡。

如果我使用的是 NetBeans、MyDoggy 或 Eclipse 框架,我想这一切都会为我神奇地处理。唉。

最佳答案

无法直接取消拖动。见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4502185

我更愿意通过更改光标向用户显示不允许在桌面上放置。

你的 DragSourceListener dsl 在 dragOver 方法中有一个 DragSourceDragEvent 告诉你桌面上的目标操作为 NONE。

更改为:

public void dragOver(DragSourceDragEvent e) {

TabTransferData data = getTabTransferData(e);

if( data == null || e.getTargetActions() == DnDConstants.ACTION_NONE ) {
e.getDragSourceContext().setCursor( DragSource.DefaultMoveNoDrop );
return;
}

e.getDragSourceContext().setCursor( DragSource.DefaultMoveDrop);
}

如果你真的想取消,那么你必须使用你的 ESC 解决方案或类似的东西:

    try {
new Robot().mouseRelease( InputEvent.BUTTON1_MASK ); // if Button1 was the only Button to start a Drag
} catch( AWTException e1 ) {
}

关于java - 禁用或拦截窗外的掉落,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14249566/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com