|
|
< Day Day Up > |
|
3.1 Mouse EventsWhen a mouse button is pressed or the mouse is moved, a mouse event is created and normally delivered to the control that is beneath the cursor. However, when a mouse button is pressed and held, and the mouse is moved outside of the control (perhaps into another control or over the desktop), events are delivered to the original control that got the mouse press. When the mouse button is released, events are delivered normally. This temporary redirection of events is called mouse capture or grabbing. The control that receives the events is called the grab control. Mouse capture happens automatically in SWT. It is something that you need to be aware of but need not be concerned with. Most programmers simply expect the mouse to behave in this manner.[3]
3.1.1 Mouse Buttons, Coordinates, and the State MaskWhen the mouse is pressed or released, the button field of the mouse event that is generated contains the number of the button that was pressed. Mouse buttons are numbered from left to right, using consecutive integer values starting from 1. For users who are left-handed (and configure the operating system for a left-handed person), the button numbering scheme remains the same but the buttons are arranged physically from right to left. This mapping for left-handed users is transparent to SWT and to your application. When a mouse event occurs, the x and y coordinates are reported in the corresponding fields of the event. These coordinates are relative to the control that received the event at the time the event occurred.[4] Because the user may have moved the mouse between the time the event occurred and the time it was delivered, the physical location of the mouse can be different from the coordinates reported in the event.[5] Recording the position of the mouse in the event prevents the system from being sensitive to these movements. You should always use the coordinates in the mouse event.
Mouse events use the stateMask field of the event to indicate the mouse state. In the same manner as key modifiers, the stateMask field contains the state of the mouse immediately prior to the event. For example, if no mouse buttons or keyboard modifier keys have already been pressed, when the left mouse button is pressed, a mouse down event is issued with the button field set to 1 and the stateMask set to zero. The stateMask field does not contain the "button 1" state mask. However, provided that the user holds the left button down, the stateMask field of subsequent mouse events will contain this mask. Mouse state is represented by constants in the class SWT. Table 3.1 shows the mouse state mask values.
The constant SWT.BUTTON_MASK contains every mouse mask and is used in a manner similar to SWT.MODIFIER_MASK:
//WRONG – broken when new mouse masks are added
int bits = SWT.BUTTON1 | SWT.BUTTON2 | SWT.BUTTON3;
if ((event.stateMask & bits) == 0) {
System.out.println ("No mouse buttons are down");
}
//CORRECT – works when new mouse masks are added
if ((event.stateMask & SWT.BUTTON_MASK) == 0) {
System.out.println ("No mouse buttons are down");
}
3.1.2 Mouse EventsTable 3.2 shows the mouse-related events that are provided by SWT.
The relevant event fields during mouse events are shown in Table 3.3.
The mouse up, down, and move events are self-evident, mapping directly to the operating system equivalents. It is important to note that only SWT.MouseDown and SWT.MouseUp use the button field. When the mouse is moved, even when a button is held down, this field is zero. This makes sense because the mouse can be moved while more than one button is pressed but the field can represent only a single button. In this case, the stateMask field is used to determine button state. As expected, SWT.MouseEnter and SWT.MouseExit events occur when the user moves the mouse into and out of a control. SWT.MouseHover occurs when the mouse "lingers" within a control. The time period and exact criteria for SWT.MouseHover are platform-specific. Double-Click EventsThe SWT.MouseDoubleClick event is sent when the mouse is rapidly pressed and released twice. Once again, the exact time period and criteria for double-click are platform-specific. For example, on some platforms, the mouse must not only be pressed and released twice, but it must remain within a specific area that was determined by the first mouse press. The ordering of SWT.MouseDown, SWT.MouseUp, and SWT.MouseDoubleClick events is as follows.
The implications of this event ordering are subtle. When writing your own control, if it issues an SWT.Selection event on a single click and the SWT .DefaultSelection event on double-click, both these events need to be sent from SWT.MouseUp. Implementing selection the obvious way by sending SWT.Selection from SWT.MouseDown and SWT.DefaultSelection from SWT .MouseDoubleClick means that when the user double-clicks on your control, you will send two SWT.Selection events and one SWT.DefaultSelection. Sending SWT.Selection from SWT.MouseUp has the further advantage that your control can implement "drag selection" and "scroll while selecting" behavior. Displaying Mouse EventsThe following example prints every mouse event that occurs in a shell.
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Listener mouseListener = new Listener() {
public void handleEvent(Event e) {
String string = "UNKNOWN";
switch (e.type) {
case SWT.MouseDown: string = "DOWN"; break;
case SWT.MouseUp: string = "UP"; break;
case SWT.MouseMove: string = "MOVE"; break;
case SWT.MouseDoubleClick:
string = "DOUBLE";
break;
case SWT.MouseEnter: string="ENTER"; break;
case SWT.MouseExit: string = "EXIT"; break;
case SWT.MouseHover: string="HOVER"; break;
}
string += ": stateMask=0x"
+ Integer.toHexString(e.stateMask);
if ((e.stateMask & SWT.CTRL) != 0)
string += " CTRL";
if ((e.stateMask & SWT.ALT) != 0)
string += " ALT";
if ((e.stateMask & SWT.SHIFT) != 0)
string += " SHIFT";
if ((e.stateMask & SWT.COMMAND) != 0)
string += " COMMAND";
if ((e.stateMask & SWT.BUTTON1) != 0)
string += " BUTTON1";
if ((e.stateMask & SWT.BUTTON2) != 0)
string += " BUTTON2";
if ((e.stateMask & SWT.BUTTON3) != 0)
string += " BUTTON3";
string += ", button=0x"
+ Integer.toHexString(e.button);
string += ", x=" + e.x + ", y=" + e.y;
System.out.println(string);
}
};
shell.addListener(SWT.MouseDown, mouseListener);
shell.addListener(SWT.MouseUp, mouseListener);
shell.addListener(SWT.MouseMove, mouseListener);
shell.addListener(SWT.MouseDoubleClick, mouseListener);
shell.addListener(SWT.MouseEnter, mouseListener);
shell.addListener(SWT.MouseExit, mouseListener);
shell.addListener(SWT.MouseHover, mouseListener);
shell.setSize(200, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
3.1.3 Detecting a Context Menu RequestTo detect when the user has requested a context menu, SWT defines the SWT.MenuDetect event (Table 3.4).
The relevant event fields during an SWT.MenuDetect event are shown in Table 3.5.
The SWT.MenuDetect event is very flexible. Depending on the platform, some controls have a built-in context menu that the operating system provides.[6] Others have a context menu that was assigned by the application program. Some controls have no context menu at all. In any case, SWT.MenuDetect allows you to detect when a menu is requested and provide your own context menu at that time. You can either display it yourself by using the x and y coordinates in the event or assign the new menu using Control.setMenu(). The following example code does just that.
static int Count;
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.addListener(SWT.MenuDetect, new Listener() {
public void handleEvent(Event event) {
Menu menu = shell.getMenu();
if (menu != null) menu.dispose();
menu = new Menu(shell, SWT.POP_UP);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Menu " + Count++);
shell.setMenu(menu);
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
Notice that a new menu with a different numbered menu item is created each time the MenuDetect event is received. The doit field in the event is used to override the built-in context menu that is found in some controls or a menu that was supplied previously using setMenu(). Setting this field to false stops this menu from being displayed. You can provide your own menu (opening it in the listener code) or choose not to display a menu by setting this field to false. One final note: SWT.MenuDetect is also sent when the user requests a context menu using the keyboard. 3.1.4 Detecting a Drag-and-Drop RequestTo determine when a drag-and-drop operation should be initiated, the SWT.DragDetect event is used (Table 3.6).
The relevant event fields during an SWT.DragDetect event are shown in Table 3.7.
Listening for SWT.DragDetect does not start a drag-and-drop operation. Rather, it detects the platform-specific mouse gesture used to indicate that a drag should start. On some platforms, drag operations are initiated using the middle mouse button. On others, the left mouse button is used. On some platforms, to distinguish a drag gesture from a mouse selection, the user moves the mouse a certain number of pixels while keeping it pressed. Application programmers can listen for SWT.DragDetect and use it to decide when to move their own objects without requiring them to use the SWT drag-and-drop support.[7] The advantage over simply using an SWT .MouseDown to do this is that users are familiar with the standard mouse drag gesture from other applications on the desktop. By using SWT.DragDetect, the application will follow the platform conventions.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
< Day Day Up > |
|