|
|
< Day Day Up > |
|
5.10 Monitors, Bounds, and Client AreaDisplays are connected to one or more physical monitors. Each monitor can have different dimensions and color characteristics. Figure 5.1 shows a display with three monitors. Figure 5.1. A display with three monitors.![]() Normally, users interact with one monitor (called the primary monitor) and use the other monitors to increase their desktop work area. The user generally expects new windows to open on the monitor where he or she is working and dialog windows to open on the same monitor as their parent. Windows do not usually straddle monitors unless the user arranges them that way. SWT models the physical monitors that are connected to the display, using instances of class Monitor. Two methods are provided on class Display that return monitors.
The following methods can be used to identify the area covered by each monitor.
On any given monitor, some of the visible area may be reserved by the operating system. For example, on Windows the task bar is normally visible on the primary monitor, reducing the amount of space that is available to your application. To query the available space on a monitor, use getClientArea(). The support for describing multiple monitors was added in R3.0 of SWT. Previous to this, the best you could do was call the getBounds() method in class Display:
The problem with using the getBounds() method of Display is that it includes areas that are not visible (see the gray rectangle marked "the Display" in Figure 5.1). You should always use getPrimaryMonitor() or getMonitors() to position your windows. The following code fragment gets all the available monitors and prints their bounds as well as the bounds of the display.
Monitor[] list = display.getMonitors();
System.out.println(list.length + " monitors.");
for (int i = 0; i < list.length; i++) {
String string = "\t" + i + " - " + list[i].getBounds();
System.out.println(string);
}
System.out.println("Total bounds: " + display.getBounds());
5.10.1 Centering a Shell on the Primary MonitorThe following code fragment centers a shell on the primary monitor using getClientArea() to query the available space.
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Monitor primary = display.getPrimaryMonitor();
Rectangle bounds = primary.getBounds();
Rectangle rect = shell.getBounds();
int x = bounds.x
+ Math.max(0, (bounds.width - rect.width) / 2);
int y = bounds.y
+ Math.max(0, (bounds.height - rect.height) / 2);
shell.setBounds(x, y, rect.width, rect.height);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
5.10.2 Positioning a Shell on a MonitorAs was previously noted, the origin of a monitor can be negative. This means that a shell positioned at a negative location may be visible to the user. This is a common source of programming errors. In other words, you cannot simply position a shell at a negative offset to hide it. Code that attempts to position a shell at a specific point needs to do so relative to the origin of the monitor, not zero. The following example positions a shell at the current location of the cursor within a monitor, ensuring that the shell is completely visible. If the shell is larger than the monitor, it is left- and top-aligned.
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(200, 200);
Point pt = display.getCursorLocation();
Point size = shell.getSize();
Monitor [] monitors = display.getMonitors();
for (int i= 0; i<monitors.length; i++) {
if (monitors [i].getBounds().contains(pt)) {
Rectangle rect = monitors [i].getClientArea();
pt.x =
Math.max(
rect.x,
Math.min(
Math.max(pt.x, rect.x),
rect.x + rect.width - size.x));
pt.y =
Math.max(
rect.y,
Math.min(
Math.max(pt.y, rect.y),
rect.y + rect.height - size.y));
break;
}
}
shell.setLocation(pt);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
|
|
|
< Day Day Up > |
|