当前页面: 开发资料首页 → Eclipse 英文资料 → Custom Drawing Table and Tree Items
摘要: Populating a table or tree widget involves creating items and setting their attributes (eg.- texts, images, etc.), after which the table or tree takes responsibility for displaying the items. This approach makes item creation straightforward and visually consistent. As of Eclipse 3.2, clients of Table and Tree can now custom draw their items, enabling a wide range of potential visual appearances. This article explores the custom draw mechanism for Table and Tree. By Grant Gayed, IBM Ottawa Lab
Summary
Populating a table or tree widget involves creating items and setting their attributes (eg.- texts, images, etc.), after which the
table or tree takes responsibility for displaying the items. This approach makes item creation straightforward and visually consistent. As of
Eclipse 3.2, clients of Table and Tree can now custom draw their items, enabling a wide range of potential visual appearances. This article
explores the custom draw mechanism for Table and Tree.
By Grant Gayed, IBM Ottawa Lab
September 15th, 2006
Tables and trees are powerful tools for presenting data in a structured manner. Data is displayed as a collection of items which have attributes like text(s), image(s), and sometimes interactive controls such as checkboxes. Typically, clients create the items and set their attributes, after which the table or tree takes responsibility for displaying them. This approach makes item creation straightforward and visually consistent, but is inflexible. For example, an item in a table or tree can only contain one image, and it must appear before its text. Given the range of visual appearances that a client may want an item to have, the best way to ensure that clients can create items with custom appearances is to allow items to be drawn.
The ability to partially or fully custom draw TableItems and TreeItems has been added as of Eclipse 3.2, and will be described in this article. It should be noted that all references made throughout the article to tables can be equally applied to trees, and vice versa.
Custom drawing is done on a per-cell basis, where a cell is the portion of an item that resides within some row and column of the parent table, or the full item if the table has no columns. For example, if a table has two columns and three items then it has six cells.
The following Table events have been defined to provide hooks into the drawing process:
SWT.MeasureItem
: allows a client to specify the dimensions of a cells contentSWT.EraseItem
: allows a client to custom draw a cells background and/or selection, and to influence whether the cells foreground should be drawnSWT.PaintItem
: allows a client to custom draw or augment a cells foreground and/or focus rectangleTo minimize the amount of work required to draw cells, these events are configured to reflect how the cell would be drawn by default. This makes it easy to augment a cells default appearance without having to draw the whole cell. If a client does not hook one of these listeners then the default cell drawing process will occur. The following sections will examine each of these events in detail along with some example code snippets.
SWT.MeasureItem
is the first custom draw event that is sent. This event gives a client the opportunity to specify the width and/or height of
a cells content. It is important to note that content size is not necessarily equivalent to cell size, since the latter may include additional decorations
such as checkboxes or tree indentation. Contexts where this event is typically sent include drawing a cell and packing a table column. This event
comes pre-configured with the following fields:
item
: the itemindex
: the column index of item
to be measuredwidth
: the default content width that the table would use if it were to draw the cell itself, based on its text, image, and checkboxheight
: the default content height that the table would use, based on the height of all of its itemsgc
: a GC that is configured with the cells font, which can be useful for performing string measurements
An application that wishes to specify a different content width and/or height for the cell can do so by changing the events width
and height
fields. A listener may choose to not change one or both of these values.
Listing 1 demonstrates the use of SWT.MeasureItem
to specify custom cell content widths and heights in a table with no columns.
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.setBounds(10,10,200,250);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Table table = new Table(shell, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setBounds(10,10,150,200);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setLinesVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < 5; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
new TableItem(table, SWT.NONE).setText("item " + i);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.MeasureItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int clientWidth = table.getClientArea().width;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.height = event.gc.getFontMetrics().getHeight() * 2;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.width = clientWidth * 2;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
<tr>
</table>
Listing 1. Specifying custom widths and heights for items in a table with no columns
Lines 1-3:
Creates a display and shell, and sets the shells bounds.
Lines 4-6:
Creates the table with no columns, sets its bounds, and sets its lines to be visible.
Lines 7-9:
Creates the tables items.
Lines 10-11
Adds an SWT.MeasureItem
listener to the table, which will be invoked whenever the size of a cells content is needed.
Line 12:
Gets the tables client width, which will be used when specifying the cell's content width.
Line 13:
Sets the events height
field to double the height of the font. This effectively doubles the height of the item in the events item
field relative to its
default height.
Line 14:
Sets the events width
field to double the width of the table. This specifies that the width of the cell should be this value regardless of its content.
Note that since this table has no columns, the width of the cell is equivalent to that of the full item.
Lines 17 to 21:
Opens the shell, runs the event loop until the shell has been disposed, and disposes the display just before exiting.
Figure 1 shows a screenshot of the snippet in Listing 1 running. Note the increased item heights (caused by line 13), and increased item widths (caused by line 14) which can be inferred from the tables horizontal scrollbar. Figure 2 shows a screenshot of the same snippet running with lines 10 through 16 commented out, allowing the table to draw in its default manner.
Figure 1. Screenshot of Listing 1 running, which specifies custom widths and heights for the items in a table
Figure 2. Screenshot of Listing 1 running without the SWT.MeasureItem
listener
Note that attempts to change a cells width or height in SWT.MeasureItem
events are subject to the following constraints:
SWT.MeasureItem
events width
field should still
always be set to the cells desired content width because this value will be used if the table has no columns or if its column is being packed.
Listing 2 demonstrates the use of SWT.MeasureItem
to specify cell widths when a table column is packed.
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.setBounds(10,10,400,200);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Table table = new Table(shell, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setBounds(10,10,350,150);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setHeaderVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setLinesVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final TableColumn column0 = new TableColumn(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column0.setWidth(100);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final TableColumn column1 = new TableColumn(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column1.setWidth(100);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column0.addListener(SWT.Selection, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column0.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column1.addListener(SWT.Selection, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
column1.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">22</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < 5; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">23</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = new TableItem(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">24</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(0, "item " + i + " col 0");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">25</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(1, "item " + i + " col 1");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">26</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">27</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.MeasureItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">28</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">29</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.width *= 2;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">30</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">31</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">32</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">33</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">34</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">35</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">36</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
</table>
Listing 2. Specifying custom cell content widths that are used by TableColumn.pack()
to size a column
Lines 1-3:
Creates a display and shell, and sets the shells bounds.
Lines 4-7:
Creates the table, sets its bounds, and sets its header and lines to be visible.
Lines 8-11:
Creates two table columns and sets the initial width of each to 100 pixels.
Lines 12-21:
Adds an SWT.Selection
listener to each of the tables columns. These listeners will invoke pack()
on the column whenever its header is clicked by the user.
Lines 22-26:
Creates the tables items.
Lines 27-28:
Adds an SWT.MeasureItem
listener to the table, which will be invoked whenever the size of a cells content is needed.
Line 29:
Sets the events width
field to double the default width of the cell. This specifies that the width of the cell should be this value regardless of its content.
Lines 32-36:
Opens the shell, runs the event loop until the shell has been disposed, and disposes the display just before exiting.
Figure 3 shows a screenshot of the snippet in Listing 2 running after each of the tables columns have been packed by clicking on their headers. Note that
the columns have been packed to a width that is double of what is needed as a result of the SWT.MeasureItem
listener in line 29. Figure 4 shows a screenshot
of the same snippet running with lines 27 through 31 commented out, which leaves the tables columns to pack to their default widths.
Figure 3. Screenshot of Listing 2 running after the tables columns have been packed using the cell content sizes specified in the SWT.MeasureItem
listener
Figure 4. Screenshot of Listing 2 running after the tables columns have been packed using the default cell sizes
SWT.EraseItem
is sent just before the background of a cell is about to be drawn. The background consists of the cells background color or the selection background
if the item is selected. This event allows a client to custom draw one or both of these. Also, this event allows the client to indicate whether the cells default
foreground should be drawn following the drawing of the background.
When this event is received the cell has been filled with either the tables background color or the portion of its background image that intersects with the cell. This event comes pre-configured with the following fields:
item
: the item
index
: the column index of item
being drawn
x
, y
: the table-relative co-ordinates of the top-left corner of the cell
width
, height
: the width and height of the full cell, or the content width of the cell if the table has no columns; if these values were previously set by
an SWT.MeasureItem
listener then they are the same here
gc
: the GC configured with the default foreground, background, font and clipping for the cell
detail
: the logical OR of one or more of the following bits, indicating what will be drawn by default:
SWT.FOREGROUND
: this bit will be set if the default cell foreground will be drawn once the background has been drawn (default is true
)
SWT.BACKGROUND
: this bit will be set if either a cell-specific or item-specific background color will be drawn for this cell (ie.- a color has previously been
set with either TableItem.setBackground(Color)
or TableItem.setBackground(int, Color)
)
SWT.SELECTED
: this bit will be set if the selection will be drawn for this cell, implying that this item is selected
SWT.FOCUSED
: this bit will be set if the focus rectangle will be drawn for this cell, implying that this item is the focus item in the table
doit
: this boolean indicates whether the table will do the drawing specified in the detail
field once this listener has completed (default is true
)
The listener is responsible for modifying the event to specify the elements that will be custom drawn (if any), and then doing the work. This is done by
clearing certain bits in the detail
field, or by setting the doit
field to false
to indicate that the listener will do all drawing for the cell (usually
in combination with an SWT.PaintItem
listener).
Listing 3 demonstrates the use of SWT.EraseItem
to custom draw the item selection rectangle in a table.
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Color red = display.getSystemColor(SWT.COLOR_RED);</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Color yellow = display.getSystemColor(SWT.COLOR_YELLOW);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Table table = new Table(shell, SWT.FULL_SELECTION);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setHeaderVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
new TableColumn(table, SWT.NONE).setWidth(100);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
new TableColumn(table, SWT.NONE).setWidth(100);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
new TableColumn(table, SWT.NONE).setWidth(100);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < 5; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = new TableItem(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(0, "item " + i + " col 0");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(1, "item " + i + " col 1");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(2, "item " + i + " col 2");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.EraseItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if ((event.detail & SWT.SELECTED) == 0) return; /* item not selected */
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int clientWidth = table.getClientArea().width;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
GC gc = event.gc;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">22</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Color oldForeground = gc.getForeground();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">23</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Color oldBackground = gc.getBackground();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">24</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setForeground(red);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">25</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setBackground(yellow);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">26</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.fillGradientRectangle(0, event.y, clientWidth, event.height, false);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">27</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setForeground(oldForeground);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">28</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setBackground(oldBackground);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">29</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.detail &= ~SWT.SELECTED;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">30</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">31</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">32</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">33</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">34</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">35</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">36</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">37</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
</table>
Listing 3: Custom drawing item selection
Lines 1-2:
Creates a display and shell.
Lines 3-4:
Obtains the systems red and yellow colors, which will be used for drawing the custom selection.
Lines 5-6:
Creates the table and sets its header to be visible. The tables style is specified to be SWT.FULL_SELECTION
since the custom-drawn selection will span
the full table width.
Lines 7-9:
Creates three table columns and sets the initial width of each to 100 pixels.
Lines 10-15:
Creates the tables items.
Line 16:
Packs the table to its preferred size.
Lines 17-18:
Adds an SWT.EraseItem
listener to the table, which will be invoked whenever the background of a cell is about to be drawn.
Line 19:
Checks the detail
field for the SWT.SELECTED
bit, and returns out of the listener if it is not there since there is no selection to draw.
Line 20:
Gets the tables client width, to be used for drawing the cell's selection.
Lines 21-23:
Obtains the GC to draw on from the event and stores its foreground and background colors for the purpose of restoring them later.
Lines 24-26:
Draws the custom selection rectangle using a gradient that spans from red to yellow. Line 26 specifies the full width of the item as the gradient bounds
so that the color range will span the table width properly. Since the GCs clipping is pre-configured to the bounds of the cell, only this portion of this
gradient drawing will appear.
Lines 27-28:
Restores the GCs foreground and background colors to their previous values.
Line 29:
Clears the SWT.SELECTED
bit from the events detail
field to indicate that the default selection should not be drawn for this cell. Note that this item is
still considered to be logically selected in the table.
Lines 32-37:
Packs and opens the shell, runs the event loop until the shell has been disposed, and disposes the display just before exiting.
Figure 5 shows a screenshot of the snippet in Listing 3 running. Though the selection gradient appears to be one continuous rectangle, it is actually
drawn three times, each clipped to its respective cell.
Figure 5. Screenshot of Listing 3 running, which uses an SWT.EraseItem
listener to draw a custom selection
Example 4: Custom drawing cell backgrounds
Listing 4 demonstrates the use of SWT.EraseItem
to custom draw cell backgrounds in a table with no columns. This example modifies the default clipping of
the GC to display gradient rectangles that represent temperature ranges.
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="43" valign="top" style="width:.45in;border-top:solid windowtext .5pt; border-left:solid windowtext .5pt;border-bottom:none;border-right:none; padding:0in 5.4pt 0in 5.4pt">1</td>
<td valign="top" style="width:788;border-top:.5pt solid windowtext; border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final String[] MONTHS = {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int[] HIGHS = {-7, -4, 1, 11, 18, 24, 26, 25, 20, 13, 5, -4};
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int[] LOWS = {-15, -13, -7, 1, 7, 13, 15, 14, 10, 4, -2, -11};
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int SCALE_MIN = -30; final int SCALE_MAX = 30;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int SCALE_RANGE = Math.abs(SCALE_MIN - SCALE_MAX);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.setBounds(10,10,400,350);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.setText("Ottawa Average Daily Temperature Ranges");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Color blue = display.getSystemColor(SWT.COLOR_BLUE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Color white = display.getSystemColor(SWT.COLOR_WHITE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Color red = display.getSystemColor(SWT.COLOR_RED);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Image parliamentImage = new Image(display, "./parliament.jpg");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Table table = new Table(shell, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setBounds(10,10,350,300);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setBackgroundImage(parliamentImage);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < 12; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = new TableItem(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">22</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(MONTHS[i] + " (" + LOWS[i] + "C..." + HIGHS[i] + "C)");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">23</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">24</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int clientWidth = table.getClientArea().width;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">25</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.MeasureItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">26</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">27</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int itemIndex = table.indexOf((TableItem)event.item);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">28</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">29</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.width = rightX;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">30</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">31</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">32</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.EraseItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">33</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">34</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int itemIndex = table.indexOf((TableItem)event.item);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">35</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int leftX = (LOWS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">36</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int rightX = (HIGHS[itemIndex] - SCALE_MIN) * clientWidth / SCALE_RANGE;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">37</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
GC gc = event.gc;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">38</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Rectangle clipping = gc.getClipping();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">39</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
clipping.x = leftX;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">40</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
clipping.width = rightX - leftX;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">41</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setClipping(clipping);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">42</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Color oldForeground = gc.getForeground();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">43</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Color oldBackground = gc.getBackground();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">44</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setForeground(blue);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">45</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setBackground(white);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">46</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.fillGradientRectangle(
event.x, event.y, event.width / 2, event.height, false);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">47</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setForeground(white);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">48</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setBackground(red);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">49</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.fillGradientRectangle(
event.x + event.width / 2, event.y, event.width / 2, event.height, false);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">50</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setForeground(oldForeground);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">51</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
gc.setBackground(oldBackground);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">52</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.detail &= ~SWT.BACKGROUND;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">53</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">54</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">55</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">56</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">57</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">58</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">59</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
parliamentImage.dispose();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">60</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
</table>
Listing 4. Custom drawing item backgrounds
Lines 1-8:
Defines constants that will be used to set the tables item data and to draw item backgrounds.
Lines 9-12:
Creates a display and shell, and sets the shells bounds and title.
Lines 13-15:
Obtains the systems blue, white and red colors, which will be used for drawing item backgrounds.
Line 16:
Loads an image that will be set into the table as the background.
Lines 17-18:
Creates the table with no columns and sets its bounds.
Line 19:
Sets the background image into the table.
Lines 20-23:
Creates the tables items.
Line 24:
Stores the tables client width for later use when drawing the item backgrounds.
Lines 25-26:
Adds an SWT.MeasureItem
listener to the table so that item sizes can be specified.
Lines 27-29:
Computes the right bound of the item in the events item
field and sets this value into the events width
field.
Lines 32-33:
Adds an SWT.EraseItem
listener to the table so that item backgrounds can be custom drawn.
Lines 34-36:
Gets the item from the events item
field and computes the left and right bounds that its temperature bar should be drawn with.
Lines 37-41:
Updates the clipping of the GC in the events gc
field to the bounds that were computed for this items temperature bar.
Lines 42-43:
Stores the GCs foreground and background colors for the purpose of restoring them later.
Lines 44-46:
Draws the left half of the custom background rectangle with a gradient that spans from blue to white. The portion of this rectangle that
intersects with the GCs clipping bounds that were set in line 41 will ultimately appear.
Lines 47-49:
Draws the right half of the custom background rectangle with a gradient that spans from white to red. The portion of this rectangle that
intersects with the GCs clipping bounds that were set in line 41 will ultimately appear.
Lines 50-51:
Restores the GCs foreground and background colors to their previous values.
Line 52:
Clears the SWT.BACKGROUND
bit from the events detail
field to indicate that the default background should not be drawn for this cell.
Lines 55-60:
Opens the shell, runs the event loop until the shell has been disposed, and disposes the background image and display just before exiting.
Figure 6 shows a screenshot of the snippet in listing 4 running.
Figure 6. Screenshot of Listing 4 running, which uses an SWT.EraseItem
listener to draw custom item backgrounds
SWT.PaintItem
SWT.PaintItem
is sent for a cell just after its default foreground contents have been drawn. This event allows a client to augment the
cell, or to completely draw the cells content. This event always comes pre-configured with the following fields:
item
: the item
index
: the column index of item
being drawn
x
, y
: the table-relative co-ordinates of the top-left corner of the cells content (ie.- its image or text)
width
, height
: the width and height of the cells content; if these values were previously set by an SWT.MeasureItem
listener then they
are the same here
gc
: the GC configured with the default foreground, background, font and clipping for the cell
detail
: the logical OR of zero or more of the following bits:
SWT.SELECTED
: this bit will be set if the item is selected
SWT.FOCUSED
: this bit will be set if the item is the tables focus item
The purpose of the x
and y
fields are to indicate the location for custom drawing. These values take into account decorations such as checkboxes and
tree indentation.
Example 5: Enhancing the native content
Listing 5 demonstrates the use of SWT.PaintItem
to augment the default drawing of tree items. It uses the x
, y
and width
fields in the SWT.PaintItem
event to draw an image to the right of alternating items. This is an example of a simple drawing enhancement that enriches an items default
content while still maintaining its native appearance.
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="43" valign="top" style="width:.45in;border-top:solid windowtext .5pt; border-left:solid windowtext .5pt;border-bottom:none;border-right:none; padding:0in 5.4pt 0in 5.4pt">1</td>
<td valign="top" style="width:788;border-top:.5pt solid windowtext; border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.setBounds(10, 10, 350, 200);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Image itemImage = new Image(display, "./palette.gif");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Image xImage = new Image(display, "./x.gif");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int IMAGE_MARGIN = 2;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Tree tree = new Tree(shell, SWT.CHECK);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
tree.setBounds(10, 10, 300, 150);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TreeItem item = new TreeItem(tree, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText("root item");
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setImage(itemImage);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < 4; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TreeItem newItem = new TreeItem(item, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
newItem.setText("descendent " + i);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
newItem.setImage(itemImage);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (i % 2 == 0) newItem.setData(xImage);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setExpanded(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item = newItem;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
tree.addListener(SWT.MeasureItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">22</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TreeItem item = (TreeItem)event.item;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">23</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Image trailingImage = (Image)item.getData();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">24</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (trailingImage != null) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">25</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.width += trailingImage.getBounds().width + IMAGE_MARGIN;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">26</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">27</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">28</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">29</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
tree.addListener(SWT.PaintItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">30</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">31</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TreeItem item = (TreeItem)event.item;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">32</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Image trailingImage = (Image)item.getData();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">33</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (trailingImage != null) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">34</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int x = event.x + event.width + IMAGE_MARGIN;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">35</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int itemHeight = tree.getItemHeight();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">36</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int imageHeight = trailingImage.getBounds().height;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">37</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int y = event.y + (itemHeight - imageHeight) / 2;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">38</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.gc.drawImage(trailingImage, x, y);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">39</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">40</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">41</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">42</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">43</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">44</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">45</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">46</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
itemImage.dispose();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">47</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
xImage.dispose();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">48</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
</table>
Listing 5. Using SWT.PaintItem
to augment the default drawing of items
Lines 1-3:
Creates a display and shell, and sets the shells bounds.
Lines 4-6:
Loads the images that will be used in this example, and defines a constant that will be used when drawing item foregrounds.
Lines 7-8:
Creates the tree with no columns and sets its bounds.
Lines 9-19:
Creates the trees items. Note that line 15 sets the item image for each item, and line 16 sets the trailing image as the item data for alternating items.
This data will be used when custom drawing the item foregrounds.
Lines 20-21:
Adds an SWT.MeasureItem
listener to the tree so that item sizes can be specified.
Lines 22-26:
Gets the item from the events item
field, and if it has a trailing image, updates the events width
field to include space for the items default
content plus the trailing image.
Lines 29-30:
Adds an SWT.PaintItem
listener to the tree so that the default foreground can be augmented.
Lines 31-39:
Gets the tree item from the events item
field, and if it has a trailing image set, draws the image to the right of the items text.
The events x
, y
and width
fields are used to compute the position of the image.
Lines 42-48:
Opens the shell, runs the event loop until the shell has been disposed, and disposes the images and display just before exiting.
Figure 7 shows a screenshot of the snippet in listing 5 running. It has the appearance of a native tree but also includes trailing images.
Figure 7. Screenshot of Listing 5 running, which uses an SWT.PaintItem
listener to augment the default drawing of items in a tree
Example 6: Custom drawing complete item contents
Listing 6 demonstrates the use of SWT.PaintItem
to draw items with multiple lines of text, which is not currently supported in tables.
It clears the SWT.FOREGROUND
bit from the detail
field in the SWT.EraseItem
event, and then draws the text in the SWT.PaintItem
event.
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td width="43" valign="top" style="width:.45in;border-top:solid windowtext .5pt; border-left:solid windowtext .5pt;border-bottom:none;border-right:none; padding:0in 5.4pt 0in 5.4pt">1</td>
<td valign="top" style="width:788;border-top:.5pt solid windowtext; border-left:medium none;border-bottom:medium none;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int COLUMN_COUNT = 4;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">2</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int ITEM_COUNT = 8;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">3</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final int TEXT_MARGIN = 3;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">4</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Display display = new Display();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">5</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Shell shell = new Shell(display);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">6</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
final Table table = new Table(shell, SWT.FULL_SELECTION);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">7</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setHeaderVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">8</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.setLinesVisible(true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">9</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < COLUMN_COUNT; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">10</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
new TableColumn(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">11</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">12</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < ITEM_COUNT; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">13</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = new TableItem(table, SWT.NONE);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">14</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int j = 0; j < COLUMN_COUNT; j++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">15</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
String string = "item " + i + " col " + j;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">16</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if ((i + j) % 3 == 1) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">17</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
string +="\nnew line1";
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">18</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">19</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if ((i + j) % 3 == 2) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">20</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
string +="\nnew line1\nnew line2";
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">21</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">22</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
item.setText(j, string);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">23</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">24</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">25</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.MeasureItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">26</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">27</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = (TableItem)event.item;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">28</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
String text = item.getText(event.index);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">29</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Point size = event.gc.textExtent(text);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">30</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.width = size.x + 2 * TEXT_MARGIN;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">31</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.height = Math.max(event.height, size.y + TEXT_MARGIN);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">32</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">33</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">34</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.EraseItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">35</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">36</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.detail &= ~SWT.FOREGROUND;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">37</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">38</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">39</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.addListener(SWT.PaintItem, new Listener() {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">40</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
public void handleEvent(Event event) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">41</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
TableItem item = (TableItem)event.item;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">42</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
String text = item.getText(event.index);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">43</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
/* center column 1 vertically */
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">44</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
int yOffset = 0;
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">45</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (event.index == 1) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">46</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
Point size = event.gc.textExtent(text);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">47</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
yOffset = Math.max(0, (event.height - size.y) / 2);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">48</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">49</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
event.gc.drawText(text, event.x + TEXT_MARGIN, event.y + yOffset, true);
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">50</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">51</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
});
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">52</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
for (int i = 0; i < COLUMN_COUNT; i++) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">53</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.getColumn(i).pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">54</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">55</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
table.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">56</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.pack();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">57</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
shell.open();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">58</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
while (!shell.isDisposed()) {
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">59</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
if (!display.readAndDispatch()) display.sleep();
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">60</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
}
</td>
</tr>
<tr>
<td width="43" valign="top" style="width:.45in;border:none;border-left:solid windowtext .5pt; padding:0in 5.4pt 0in 5.4pt">61</td>
<td valign="top" style="border-left:medium none; border-top:medium none; border-bottom:medium none; width:788;border-right:.5pt solid windowtext; padding-left:5.4pt; padding-right:5.4pt; padding-top:0in; padding-bottom:0in">
display.dispose();
</td>
</tr>
</table>
Listing 6. Using SWT.PaintItem
to draw items with multiple lines of text
Lines 1-3:
Defines constants that will be used for creating and drawing the tables items.
Lines 4-5:
Creates a display and shell.
Lines 6-8:
Creates the table and sets its header and lines to be visible.
Lines 9-11:
Creates the tables columns.
Lines 12-24:
Creates the tables items. Item texts are set to values with one, two, or three lines of text.
Lines 25-26:
Adds an SWT.MeasureItem
listener to the table so that item sizes can be specified.
Lines 27-31:
Gets the item and column index from the event, computes the bounds of its text, and uses this value to set the events width
and height
fields. TEXT_MARGIN
is added
to the bounds to create space for a small margin around the items content.
Lines 34-38:
Adds an SWT.EraseItem
listener to the table for the purpose of clearing the SWT.FOREGROUND
bit from the events detail
field. This indicates that the default drawing
of item foregrounds should not occur because the SWT.PaintItem
listener will do this in full.
Lines 39-40:
Adds an SWT.PaintItem
listener to the table so that item foregrounds can be custom drawn.
Lines 41-49:
Gets the text for the cell and draws it. The text is centered vertically within the cell for column 1, and draws top-aligned otherwise.
Lines 52-54:
Packs the tables columns to their preferred widths, using the values provided by the SWT.MeasureItem
listener.
Lines 55-56:
Packs the table and shell to their preferred sizes.
Lines 57-61:
Opens the shell, runs the event loop until the shell has been disposed, and disposes the display just before exiting.
Figure 8 shows a screenshot of the snippet in Listing 6 running.
Figure 8. Screenshot of Listing 6 running, which uses an SWT.PaintItem
listener to custom draw the tables items
Conclusion
With Table and Tree custom draw facilities in place, items can appear native, custom-drawn, or somewhere in between. With a small amount of effort, clients can use
this flexibility to display data any way that they want. The potential uses for custom item drawing extend beyond the examples presented in this article. To view
a growing collection of examples that use custom draw tables and trees see http://www.eclipse.org/swt/snippets/#table
and http://www.eclipse.org/swt/snippets/#tree.
Errata and comments about this article can be reported in https://bugs.eclipse.org/bugs/show_bug.cgi?id=157330.
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.
IBM is a registered trademark of International Business Machines Corporation in the United States, other countries, or both.
Other company, product, or service names may be trademarks or service marks of others.
↑返回目录
前一篇: Introducing AJDT: The AspectJ Development Tools
后一篇: Implementing Model Integrity in EMF with EMFT OCL