我一直在关注本指南 http://softwareisart.blogspot.co.uk/2011/11/drag-and-drop-of-complex-custom-objects.html
使我的自定义Jpanels可拖动(通过拖动手势)但是由于某种原因,只有没有组件的JPanel区域是可拖动的。我有一个JSVGCanvas(来自蜡染库)里面有一些绘画,然后我将其添加到我的自定义JPanel中。
过去,为了让JPanel上的悬停事件突出显示,我会执行以下操作,将鼠标悬停事件从画布传递到外部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);}
但是我不确定如何将拖动事件从画布传递到持有画布的jpanel。
是否可以将画布绑定到JPanel,这样当我点击Jpanel中的任何地方时,它会通过画布传递到JPanel?
由于
更新
嗨理查德。使用JLayer似乎很好,因为它现在包含JSVGCanvas和持有画布的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);'
我的DragGestures
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就像这样。 class 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传递给cavas的实现创建了单独的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;
阿里
答案 0 :(得分:0)
在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();
}
});
}
}