Drag and Drop on a JPanel in JMEDesktop

Ok, autoupdate finished for the moment, so its time for some drag and drop :slight_smile:



I guess i start by also implementing a testcase for swing and then transfering it to jmedesktop.

Lets see if we can get this to work.



PS: @kidneybean

updating the updater is no problem :wink:

just use webstart for the updater/launcher and have it install/update the main programm somewhere else.

ok, tried it with the BasicDND example from sun and it didnt work.



Next step was to take Galuns classes.

I added the following class:

package de.mbws.client.experimental;

import java.awt.AWTEvent;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;

public class CaptureListener implements AWTEventListener {

public CaptureListener() {
long eventMask = AWTEvent.MOUSE_EVENT_MASK
| AWTEvent.MOUSE_MOTION_EVENT_MASK;
Toolkit toolkit = Toolkit.getDefaultToolkit();
toolkit.addAWTEventListener(this, eventMask);
}


public void eventDispatched(AWTEvent event) {
int ID = event.getID();
if (ID == MouseEvent.MOUSE_PRESSED)
System.out.println("Mousepressed" + event.getSource());
else {
if (ID == MouseEvent.MOUSE_RELEASED)
System.out.println("Mousereleased" + event.getSource());
else if (ID == MouseEvent.MOUSE_MOVED)
System.out.println("MouseMoved" + event.getSource());
else if (ID == MouseEvent.MOUSE_DRAGGED)
System.out.println("mousedragged" + event.getSource());
}
}
}


Now there is one simple difference between the Swingtext and TestJMEDesktop.
In Galuns code you have two internal frames both named DNDPanel. Inside each frame there is one label.
When i run Galuns Swingtest and move the mouse over the INSIDE of a DNDPanel then i get the output:
MouseMovedjavax.swing.JPanel[null.glassPane,0,0,190x67,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777217,maximumSize=,minimumSize=,preferredSize=]
MouseMovedde.mbws.client.experimental.DndPanel[DndPanel2,140,220,200x100,layout=javax.swing.plaf.basic.BasicInternalFrameUI$Handler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.metal.MetalBorders$InternalFrameBorder@19da4fc,flags=264,maximumSize=,minimumSize=,preferredSize=,closable=false,defaultCloseOperation=DISPOSE_ON_CLOSE,desktopIcon=javax.swing.JInternalFrame$JDesktopIcon[,0,600,160x31,invalid,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@16f144c,flags=8,maximumSize=,minimumSize=,preferredSize=],frameIcon=javax.swing.plaf.IconUIResource@1e232b5,iconable=false,isClosed=false,isIcon=false,isMaximum=false,isSelected=false,maximizable=false,opened=true,resizable=false,rootPane=javax.swing.JRootPane[,5,28,190x67,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=449,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true,title=]

If i move the mouse over the INSIDE of the FOCUSSED (!) JFRAME  i receive:
MouseMovedde.mbws.client.experimental.DndPanel[DndPanel1,30,100,200x100,invalid,layout=javax.swing.plaf.basic.BasicInternalFrameUI$Handler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.metal.MetalBorders$InternalFrameBorder@19da4fc,flags=264,maximumSize=,minimumSize=,preferredSize=,closable=false,defaultCloseOperation=DISPOSE_ON_CLOSE,desktopIcon=javax.swing.JInternalFrame$JDesktopIcon[,0,600,160x31,invalid,layout=java.awt.BorderLayout,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@16f144c,flags=8,maximumSize=,minimumSize=,preferredSize=],frameIcon=javax.swing.plaf.IconUIResource@1e232b5,iconable=false,isClosed=false,isIcon=false,isMaximum=false,isSelected=true,maximizable=false,opened=true,resizable=false,rootPane=javax.swing.JRootPane[,5,28,190x67,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=449,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true,title=]


Trying the same with JMEDesktop gives me the same result for the unfocussed DNDPanel but for the focussed i only receive
MouseMovedjavax.swing.JLabel[,0,0,190x67,alignmentX=0.0,alignmentY=0.0,border=,flags=8388608,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=DndPanel,verticalAlignment=CENTER,verticalTextPosition=CENTER]


So the problem seems to be that with jmedesktop for whatever reason the topmost "component" inside the DNDPanel is reported as source for the event.
the same goes by the way for the other containers inside testmedesktop. I allways receive the topmost component, be it button, label etc.

My guess at the moment is that the problem is related to which component is named as source for an event.

Using Galuns example i see that the dragSTART works in the jmedesktop ONLY if the DNDPanel is NOT selected first.

If it is then it doesnt work from that Frame, only from the other.

So I think that one of the points we should have a closer look at is the componentAt method returning the Component that is given to the new created mousevent.

That would however only solve the dragstart problem…

The drop however doesnt work in either case.

Interestingly in JME i get a mousereleased when i finish my movement, in swing i DONT get that.

So far i havent been able to really figure out how these dragevents are created.

Frankly it has become too complicated to debug it. This "actionPerformed" breakpoint is horrible. Modifying the source code of java and trying it with debug statements instead of breakpoints didnt help either.

So I dont get a real good grasp on how swing works when it comes to dnd and what jme does different.

I think its easier and more efficient to program a general and small framework for that instead of relying on swingDND/jmedesktopEvents.



Sad … i hate it when problems are not solved



:frowning:

It looks like SunDragSourceContextPeer.checkEvent(event) is responsible to dispatch the event to the right target and create appropriate component and hierarchy events. The problem is, it consumes too many events if it's just called in JMEDesktop.sendAWTMouseEvent().

I think something like EventDispatchThread (boolean pumpOneEventForHierarchy) is needed to get the right targets.