Mam słuchacza myszy. Ma trochę kodu reagującego na zdarzenia mouseUp i mouseDown. Działa to poprawnie.Zdarzenia MouseDown nie są dostarczane aż do MouseUp, gdy obecne jest źródło przeciągania.
Jednak, jak tylko dodaję DragSource, moje zdarzenie mouseDown nie jest już dostarczane - dopóki nie zwolnię przycisku myszy!
To jest trywialne do odtworzenia - poniżej jest prosty program, który zawiera zwykłą powłokę za pomocą tylko myszy słuchacza i słuchacza drag. Gdy uruchomię to (na komputerze Mac), a następnie naciśnie i przytrzymam przycisk myszy, nic się nie dzieje - ale zaraz po zwolnieniu przycisku myszy natychmiast wyświetlana jest zarówno dostarczona mysz, jak i zdarzenia związane z myszką. Jeśli skomentuję źródło przeciągania, zdarzenia myszy są dostarczane tak, jak powinny.
Rozglądałem się za innych z podobnymi problemami, a najbliżej znalazłem do wyjaśnienia jest to:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=26605#c16 „Jeśli hak przeciągnij wykryć, system operacyjny musi jeść zdarzeń myszy aż do niej określa, czy przeciągasz, czy nie. "
Jednak nie rozumiem, dlaczego to prawda - dlaczego system operacyjny musi jeść zdarzenia myszy, aby określić, czy mam opór, czy nie? Przeciąganie nie rozpocznie się, dopóki nie zostanie wywołane zdarzenie "myszka" z wciśniętym przyciskiem.
Co ważniejsze: Czy ktoś może zaproponować obejście tego problemu? (Próbowałem dynamicznie dodawać i usuwać moje źródło przeciągania po naciśnięciu myszy, ale wtedy nie mogłem się przeciągnąć, aby funkcja działała prawidłowo, ponieważ nigdy nie widziałem początkowego naciśnięcia klawisza - i nie mogę znaleźć sposobu na programowe zainicjowanie . drag)
Oto przykładowy 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();
}
}
Próbowałem już, a twój kod działa w systemie Windows. Może być błąd specyficzny dla systemu operacyjnego – nanda
Właśnie próbowałem tego na Ubuntu 10.04 i to sort-of works. Naciśnij lewy przycisk myszy, nie otrzymasz żadnego zdarzenia. Przesuń mysz, otrzymasz 'mouseDown' i' dragStart' * w tym samym czasie *. Kiedy puścisz, otrzymasz zdarzenie 'mouseUp'. Jeśli trzymasz mysz nieruchomo i naciśniesz lewy przycisk, otrzymasz "mouseDown" po zauważalnym 1-2 sekundowym opóźnieniu. Tak czy inaczej, 'mouseDown' jest zawsze widoczne przed puszczeniem myszy. Musi być problem z SWT na Macu? – richq
Dziękuję wam obojgu - wygląda na to, że jest to zdecydowanie platforma. Jednak wygląda na to, że jest on również uszkodzony na Linuksie - jedno sekundowe opóźnienie przed dostarczeniem MouseDown nie zadziała, ponieważ powodem, dla którego próbuję zmienić sposób obsługi z mouseUp na mouseDown, jest sprawienie, aby interfejs był bardziej responsywny. –