How to set the Droppable/Draggable Event on the mouse cursor - drag-and-drop

I've implemented the Drag-n-Drop effects in Wicket using the Ajax Behavior. If I dragg the Image over the tree nodes, the position of droppable accept is in the middle of image. How to set this position (event) on the cursor?
Thank you.

Also I found it. The solution is:
DroppableAjaxBehavior b = new DroppableAjaxBehavior() {
#Override
public void onDrop(Component droppedComponent, AjaxRequestTarget target) {
//do something to handle event
}
};
b.setTolerance(ToleranceEnum.POINTER);

Related

GWT Google Map Api V3 - broken when changing it

It is working fine for me for the first time it is rendered.
But, If I change anything over the map or recreate it, its broken.
Here is the screen shot for how it looks.
Here is a screen shot after I changed the results per page value.
This is my code.
#UiField DivElement mapPanel;
private GoogleMap googleMap;
public void loadAllMarkers(final List<LatLng> markers)
{
if(!markers.isEmpty())
{
final MapOptions options = MapOptions.create();
options.setMapTypeId(MapTypeId.ROADMAP);
googleMap = GoogleMap.create(mapPanel, options);
final LatLngBounds latLngBounds = LatLngBounds.create();
for(LatLng latLng : markers)
{
final MarkerOptions markerOptions = MarkerOptions.create();
markerOptions.setPosition(latLng);
markerOptions.setMap(googleMap);
final Marker marker = Marker.create(markerOptions);
latLngBounds.extend(marker.getPosition());
}
googleMap.setCenter(latLngBounds.getCenter());
googleMap.fitBounds(latLngBounds);
}
}
I am calling the loadAllMarkers() method whenever new results needs to be loaded.
Can someone point out what I am doing wrong here.
This seems to come from the following (which I pulled from a Google+ Community - GWT Maps V3 API):
Brandon DonnelsonMar 5, 2013
I've had this happen and forgotten why it is, but
mapwidget.triggerResize() will reset the tiles. This seems to happen
when the onAttach occurs and animation exists meaning that the div
started smaller and increases in side, but the map has already
attached. At the end of the animation, the map doesn't auto resize.
I'v been meaning to investigate auto resize but I haven't had time to
attack it yet.
In your case, you would call googleMap.triggerResize() after you finish your changes. this solved my problem when I had the exact same issue. I know it's a little late, but I hope it helps!
Another answer there was to extend the Map widget with the following:
#Override
protected void onAttach() {
super.onAttach();
Timer timer = new Timer() {
#Override
public void run() {
resize();
}
};
timer.schedule(5);
}
/*
* This method is called to fix the Map loading issue when opening
* multiple instances of maps in different tabs
* Triggers a resize event to be consumed by google api in order to resize view
* after attach.
*
*/
public void resize() {
LatLng center = this.getCenter();
MapHandlerRegistration.trigger(this, MapEventType.RESIZE);
this.setCenter(center);
}

GWT - event.getX() and event.getClientX()

I added click handler to flowpanel as follows
this.addDomHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
Window.alert("event.getX()="+event.getX()+" event.getY()="+event.getY());
Window.alert("event.getClientX()="+event.getClientX()+" event.getClientY()="+event.getClientY());
}
},ClickEvent.getType());
... as I could get it getX() returns mouse position within flowpanel but getClientX() returns another value and I couldn't get the value is coming from. So my question is what is the getClientXY() methods are used for?
P.S
GWT 2.2/2.3
The javadoc is clear:
getClientX: Gets the mouse x-position within the browser window's client area.
getX: Gets the mouse x-position relative to the event's current target element.
So, you can use getClientX to get the absolute left position of some element.

Programatically Detect window maximization/Minimization??? Eclipse RCP

As the title shows, I want to add a listener to my rcp user interface in order to detect maximization and minimization. Actually, it not that my real purpose, but I think it is a way to solve my problem. I have a view with some shapes in the center, and I wonna keep the drawing exactly in the center even if the window is resized. To do so, I used the following listener :
public void createPartControl(final Composite parent) {
display = parent.getDisplay();
white= display.getSystemColor(SWT.COLOR_WHITE);
parent.setLayout(new FillLayout(SWT.VERTICAL));
final ScrolledComposite sc = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
sc.setMinHeight(100);
sc.setMinWidth(100);
sc.setSize(565, 305);
final Composite child = new Composite(sc,SWT.NONE);
child.setLayout(new FillLayout());
// Set child as the scrolled content of the ScrolledComposite
sc.setContent(child);
child.setBackground(white);
gc = new GC(child);
parent.addListener (SWT.Resize, new Listener () {
public void handleEvent (Event e) {
x = child.getBounds().width/2;
y = child.getBounds().height/2;
child.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
dessin(gc); // draw my shapes
}
});
}
everything goes well except when I maximize the window and then minimize it, in this case I loose the drawing (it is in the corner).
Any idea please? I'm I thinking in the right way?
The two events to detect minimization and un-minimization (not necessarily maximization) are Iconify and Deiconify which only occur on the Shell. See the javadocs for Shell.
Consider moving the resize event is seen for the parent, as the child need not necessarily be resized yet.
In order to keep something in the center of something else all you need is the SWT.Resize event, so this question is a classic case of the XY Problem. (Except that the OP in this case seems to already suspect that this may be an XY Problem.)
However, many people arrive at this question with a legitimate need to programmatically detect window minimized / maximized / restored events, for the following reason:
If you want to be able to save the bounds of your application window on exit, you cannot just save whatever is returned by Shell.getBounds(), because your application may be terminated while minimized or maximized or fullscreen, in which case its bounds should not be persisted. What should be persisted is the minimized/normal/maximized/fullscreen state of the shell, (I call it "posture",) and the bounds of the shell last time its posture was "normal". So, essentially, you need to keep track of when the posture is "normal", and for that you need to have a "posture changed" event.
The problem is that when SWT issues the "deiconified" event, it has not calculated the bounds of the shell yet, so the value that you get in that case is bogus.
So, here is the solution to that:
You are going to need a method which recalculates the posture as follows:
private void recalculatePosture()
{
Posture posture = swtShell.getFullScreen()? Posture.FULLSCREEN
: swtShell.getMinimized()? Posture.MINIMIZED
: swtShell.getMaximized()? Posture.MAXIMIZED
: Posture.NORMAL;
if( posture != previousPosture )
{
issue event...
previousPosture = posture;
}
}
In order to generate the "maximized", "restored (from maximized)" and "fullscreen" events you can use Shell.addListener() to listen for the SWT.Move and SWT.Resize event, and invoke recalculatePosture() when they occur.
In order to generate the "minimized" event you can use the shellIconified() method of the ShellListener as #the.duckman said, and again, invoke recalculatePosture().
In order to generate the "restored (from minimized)" event, you need to do the following in your ShellListener:
#Override
protected void onShellDeiconified( ShellEvent e )
{
display.asyncExec( () -> recalculatePosture() );
}
This will cause the recalculation of posture a short time after the 'deiconified' event, at which point SWT will have gotten around to properly calculating the bounds of the shell.

GWT: How to center element containing CellTable?

I'm trying to center an element that contains a CellTable. The actual
centering logic works okay, but I'm having problems with all those
attaching/detaching events. Basically, I'm doing this in my container
widget:
#Override
public void onLoad() {
super.onLoad();
center();
}
However, it seems that onLoad on the container does not mean that all
children have loaded, so... the actual centering routine is called too
early and Element.getOffsetWidth/getOffsetHeight are both returning 0.
This results in the container being displayed with the left upper corner
in the center of the screen.
Same thing happens if I use an AttachEvent.Handler on the CellTable.
So... is there any event on CellTable, or on Widget or whatever that
allows me to trigger an action when the DOM subtree has been attached to
the DOM?
Thanks in advance.
Take a look at scheduleDeferred. A deferred command is executed after the browser event loop returns.
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
center();
}
});
Override onAttach instead of onLoad. onAttach default implementation calls onLoad followed by doAttachChildren (which calls onAttach on each child widget), so the following code should call center after the children have been attached:
#Override
public void onAttach() {
super.onAttach();
center();
}
(BTW, the default implementation of onLoad is a no-op)

MouseDown events are not delivered until MouseUp when a Drag Source is present

I have a mouse listener. It has some code to respond to mouseUp and mouseDown events. This works correctly.
However, as soon as I add a DragSource, my mouseDown event is no longer delivered -- until I release the mouse button!
This is trivial to reproduce - below is a simple program which contains a plain shell with just a mouse listener and a drag listener. When I run this (on a Mac), and I press and hold the mouse button, nothing happens - but as soon as I release the mouse button, I instantly see both the mouse down and mouse up events delivered. If I comment out the drag source, then the mouse events are delivered the way they should be.
I've searched for others with similar problems, and the closest I've found to an explanation is this:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=26605#c16
"If you hook drag detect, the operating system needs to eat mouse events until it determines that you have either dragged or not."
However, I don't understand why that's true -- why must the operating system eat mouse events to determine if I have a drag or not? The drag doesn't start until I have a mouse -move- event with the button pressed.
More importantly: Can anyone suggest a workaround? (I tried dynamically adding and removing my drag source when the mouse is pressed, but then I couldn't get drag & drop to function properly since it never saw the initial key press - and I can't find a way to programmatically initiate a drag.)
Here's the sample program:
package swttest;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class SwtTest {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.addMouseListener(new MouseListener() {
public void mouseUp(MouseEvent e) {
System.out.println("mouseUp");
}
public void mouseDown(MouseEvent e) {
System.out.println("mouseDown");
}
public void mouseDoubleClick(MouseEvent e) {
System.out.println("mouseDoubleClick");
}
});
DragSourceListener dragListener = new DragSourceListener() {
public void dragFinished(DragSourceEvent event) {
System.out.println("dragFinished");
}
public void dragSetData(DragSourceEvent event) {
System.out.println("dragSetData");
}
public void dragStart(DragSourceEvent event) {
System.out.println("dragStart");
}
};
DragSource dragSource = new DragSource(shell, DND.DROP_COPY | DND.DROP_MOVE);
dragSource.addDragListener(dragListener);
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
To answer your specific question about why this happens -- on Cocoa we don't consider a drag to have started until the mouse has moved a few pixels. This ensures against 'accidental' drags if you're sloppy with the clicks. On Linux and Win32 the window toolkit can do the drag detection. If you just hold down the button the detection times out and the mouse down is delivered. On Cocoa we have no time out, which is why nothing happens until the drag is detected or a mouse up happens.
That's a lot of detail, but the conclusion is that the behavior is inconsistent, and we should always be able to deliver the mouse down immediately, without waiting for the drag detection to complete.
I don't see a workaround, since this is happening before the Control sees the event.
See this bug which has patches for win32, gtk and cocoa SWT.
I had faced the same problem and found a solution. Once you attach a DragSource to your custom widget, the event loop will be blocked in that widget's mouse down hook and will eat mouse move events to detect a drag. (I've only looked into the GTK code of SWT to find this out, so it may work a little differently on other platforms, but my solution works on GTK, Win32 and Cocoa.) In my situation, I wasn't so much interested in detecting the mouse down event right when it happened, but I was interested in significantly reducing the drag detection delay, since the whole purpose of my Canvas implementation was for the user to drag stuff. To turn off the event loop blocking and built-in drag detection, all you have to do is:
setDragDetect(false);
In my code, I am doing this before attaching the DragSource. As you already pointed out, this will leave you with the problem that you can't initiate a drag anymore. But I have found a solution for that as well. Luckily, the drag event generation is pure Java and not platform specific in SWT (only the drag detection is). So you can just generate your own DragDetect event at a time when it is convenient for you. I have attached a MouseMoveListener to my Canvas, and it stores the last mouse position, the accumulated drag distance and whether or not it already generated a DragDetect event (among other useful things). This is the mouseMove() implementation:
public void mouseMove(MouseEvent e) {
if (/* some condition that tell you are expecting a drag*/) {
int deltaX = fLastMouseX - e.x;
int deltaY = fLastMouseY - e.y;
fDragDistance += deltaX * deltaX + deltaY * deltaY;
if (!fDragEventGenerated && fDragDistance > 3) {
fDragEventGenerated = true;
// Create drag event and notify listeners.
Event event = new Event();
event.type = SWT.DragDetect;
event.display = getDisplay();
event.widget = /* your Canvas class */.this;
event.button = e.button;
event.stateMask = e.stateMask;
event.time = e.time;
event.x = e.x;
event.y = e.y;
if ((getStyle() & SWT.MIRRORED) != 0)
event.x = getBounds().width - event.x;
notifyListeners(SWT.DragDetect, event);
}
}
fLastMouseX = e.x;
fLastMouseY = e.y;
}
And that will replace the built-in, blocking drag detection for you.