gpt4 book ai didi

java - 如何使 Jpanel 的所有区域可拖动,包括其中的 JSVGCanvas

转载 作者:太空宇宙 更新时间:2023-11-04 14:05:20 26 4
gpt4 key购买 nike

我一直在遵循本指南 http://softwareisart.blogspot.co.uk/2011/11/drag-and-drop-of-complex-custom-objects.html

使我的自定义 Jpanels 可拖动(通过拖动手势),但由于某种原因,只有没有组件的 JPanel 区域可拖动。我有一个 JSVGCanvas(来自 batik 库),其中有一些绘画,然后我将其添加到我的自定义 JPanel 中。

过去,对于 JPanel 上的悬停事件以使其突出显示,我会执行以下操作将鼠标悬停事件从 Canvas 传递到外部 jpanel,如下所示来解决此问题。

@Override public void mouseClicked(MouseEvent e){outside.dispatchEvent(e);}
@Override public void mousePressed(MouseEvent e){outside.dispatchEvent(e);}
@Override public void mouseReleased(MouseEvent e){outside.dispatchEvent(e);}

但是我不确定如何将拖动事件从 Canvas 传递到持有 Canvas 的 jpanel。

有什么方法可以将 Canvas 绑定(bind)到 JPanel,以便当我单击 Jpanel 中的任意位置时,它会通过 Canvas 传递到 JPanel?

谢谢

更新

嗨,理查德。使用 JLayer 似乎很好,因为它现在包含 JSVGCanvas 和持有 Canvas 的 JPanel。但是我应该如何在“此处拖动手势处理”位中添加拖动手势。我通常将拖动事件添加到我的 JPanel 中,如下所示。

DragSource ds = new DragSource();
ds.createDefaultDragGestureRecognizer(SecondChoice,
DnDConstants.ACTION_COPY, new DragGestureListImp());

DragSource ds2 = new DragSource();
ds2.createDefaultDragGestureRecognizer(FirstChoice,
DnDConstants.ACTION_COPY, new DragGestureListImp());


new MyDropTargetListImp(FirstChoice);
new MyDropTargetListImp(SecondChoice);'

还有我的拖动手势

class DragGestureListImp implements DragGestureListener {

@Override
public void dragGestureRecognized(DragGestureEvent event) {

Cursor cursor = null;
CustomJPanel panel= (CustomJPanel) event.getComponent();



if (event.getDragAction() == DnDConstants.ACTION_COPY) {
cursor = DragSource.DefaultCopyDrop;
}
Canvas canvas= panel.getCanvas();

event.startDrag(cursor, new TransferableCanvas(canvas));
}
} //DragGestureListImp

而MyDropTargetListImp就是这样的。 类 MyDropTargetListImp 扩展 DropTargetAdapter 实现 DropTargetListener {

    private DropTarget dropTarget;
private CustomJPanel panel;

public MyDropTargetListImp(CustomJPanel panel) {
this.panel = panel;

dropTarget = new DropTarget(panel, DnDConstants.ACTION_COPY, this,
true, null);
}


public void drop(DropTargetDropEvent event) {
try {

System.out.println("dropped Event");
Transferable tr = event.getTransferable();
CustomJPanel an = (CustomJPanel) tr.getTransferData(dataFlavor);

if (event.isDataFlavorSupported(dataFlavor)) {
event.acceptDrop(DnDConstants.ACTION_COPY);

this.panel.updateMyStuff(an)

event.dropComplete(true);
this.panel.validate();
return;
}
event.rejectDrop();
} catch (Exception e) {
e.printStackTrace();
event.rejectDrop();
}
} //drop
} //MyDropTargetListImp

错误:(281, 21) java: 不兼容的类型:java.awt.AWTEvent 无法转换为 java.awt.dnd.MouseDragGestureRecognizer

更新最终结果

JLayers 对我有一点帮助,但我最终通过以下方式实现了它。在 Richard 编写的 JLayer 类中,我只是向 Canvas 和 JLayer 添加了一个gestureListener,并为每个将 JLayer 传递到 cava 的实现创建了单独的 GesturesImplementations。

DragSource ds = new DragSource();
// create a component to be decorated with the layer
// This would be your custom component.
CustomPanel customPanel = new CustomPanel (index, information);
//customPanel.add(new JButton("JButton"));

JLayer tempLayerUI = new JLayer<JComponent>(customPanel, layerUI);

ds.createDefaultDragGestureRecognizer(customPanel.canvas,
DnDConstants.ACTION_COPY, new DragGestureListImp1(tempLayerUI));

ds.createDefaultDragGestureRecognizer(tempLayerUI,
DnDConstants.ACTION_COPY, new DragGestureListImp());

return tempLayerUI;

阿里

最佳答案

在 Java 7 或更高版本中,您应该能够将 JPanel 包装在 JLayer 实例中,该实例拦截当前发送到 JSVGCanvas 的鼠标事件。这将允许您在包装器中进行拖动手势处理。

下面是来自 https://docs.oracle.com/javase/7/docs/api/javax/swing/JLayer.html 的示例代码的改编版本

public class JLayerSample {

private static JLayer<JComponent> createLayer() {
// This custom layerUI will intercept all mouseMotion events generated within its borders and delegate to the wrapped JPanel
LayerUI<JComponent> layerUI = new LayerUI<JComponent>() {

public void installUI(JComponent c) {
super.installUI(c);
// enable mouse events for the layer's subcomponents
((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
}

public void uninstallUI(JComponent c) {
super.uninstallUI(c);
// reset the layer event mask
((JLayer) c).setLayerEventMask(0);
}

// overridden method which catches MouseMotion events
public void eventDispatched(AWTEvent e, JLayer<? extends JComponent> l) {
if (e instanceof MouseEvent) {
System.out.println("MouseEvent detected " + e);
// Do drag gesture processing here.
// Note, you cannot dispatch these events to the view component, since that
// creates an event loop.
}
}
};

// create a component to be decorated with the layer
// This would be your custom component.
JPanel panel = new JPanel();
panel.add(new JButton("JButton"));

// create the layer for the panel using our custom layerUI
return new JLayer<JComponent>(panel, layerUI);
}

private static void createAndShowGUI() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// work with the layer as with any other Swing component
frame.add(createLayer());

frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

关于java - 如何使 Jpanel 的所有区域可拖动,包括其中的 JSVGCanvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28922000/

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